diff --git a/AUTHORS.txt b/AUTHORS.txt index aae2cd4f91..5a20dc7535 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -6,10 +6,6 @@ Core Developers: Shun Lin (Sean Lin) - Hao Wu (WuHao) - - Dingping Lv (David Lv) - Ricardo Quesada Huabin LING (@pandamicro) @@ -18,6 +14,8 @@ Core Developers: Long Jiang (@jianglong0156) + Menghe Zhang (@ZhangMenghe) + Contributors: Name GithubID Main contribution @@ -180,6 +178,7 @@ Mykyta Usikov @musikov cc.ClippingNode 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 @@ -271,10 +270,16 @@ 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 a37a37a9a7..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,530 +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); - - if (callback) - callback(null, img); - }; - 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"); + var queue = _queue[url]; + if (queue) { + queue.callbacks.push(callback); + return queue.img; } - }; - cc._addEventListener(img, "load", loadCallback); - cc._addEventListener(img, "error", errorCallback); - img.src = url; - return 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]; + } - /** - * 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); - } + 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]; + } - 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 realUrl = url; - if (!url.match(cc._urlRegExp)) - { - var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath; - realUrl = self.getUrl(basePath, url); - } + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { + imagePool.put(img); + } + } + }; - 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(); + _queue[url] = { + img: img, + callbacks: callback ? [callback] : [] + }; + + 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:
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
+ * Loads alias map from the contents of a filename.
+ *
+ * @note The plist file name should follow the format below:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
- * 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.
- *
* The alpha threshold.
- * A CCCamera is used in every CCNode.
@@ -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;
@@ -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) 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
* Event callback that is invoked every time when CCNode enters the 'stage'.
* Event callback that is invoked when the CCNode enters in the 'stage'.
@@ -105,9 +107,9 @@ cc.__getListenerID = function (event) {
*/
cc.eventManager = /** @lends cc.eventManager# */{
//Priority dirty flag
- DIRTY_NONE:0,
- DIRTY_FIXED_PRIORITY:1 <<0,
- DIRTY_SCENE_GRAPH_PRIORITY : 1<< 1,
+ DIRTY_NONE: 0,
+ DIRTY_FIXED_PRIORITY: 1 << 0,
+ DIRTY_SCENE_GRAPH_PRIORITY: 1 << 1,
DIRTY_ALL: 3,
_listenersMap: {},
@@ -116,12 +118,13 @@ cc.eventManager = /** @lends cc.eventManager# */{
_nodePriorityMap: {},
_globalZOrderNodeMap: {},
_toAddedListeners: [],
+ _toRemovedListeners: [],
_dirtyNodes: [],
_inDispatch: 0,
_isEnabled: false,
_nodePriorityIndex: 0,
- _internalCustomListenerIDs:[cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
+ _internalCustomListenerIDs: [cc.game.EVENT_HIDE, cc.game.EVENT_SHOW],
_setDirtyForNode: function (node) {
// Mark the node dirty only when there is an event listener associated with it.
@@ -140,12 +143,12 @@ cc.eventManager = /** @lends cc.eventManager# */{
pauseTarget: function (node, recursive) {
var listeners = this._nodeListenersMap[node.__instanceId], i, len;
if (listeners) {
- for ( i = 0, len = listeners.length; i < len; i++)
+ for (i = 0, len = listeners.length; i < len; i++)
listeners[i]._setPaused(true);
}
if (recursive === true) {
var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
+ for (i = 0, len = locChildren.length; i < len; i++)
this.pauseTarget(locChildren[i], true);
}
},
@@ -157,14 +160,14 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
resumeTarget: function (node, recursive) {
var listeners = this._nodeListenersMap[node.__instanceId], i, len;
- if (listeners){
- for ( i = 0, len = listeners.length; i < len; i++)
+ if (listeners) {
+ for (i = 0, len = listeners.length; i < len; i++)
listeners[i]._setPaused(false);
}
this._setDirtyForNode(node);
if (recursive === true) {
var locChildren = node.getChildren();
- for ( i = 0, len = locChildren.length; i< len; i++)
+ for (i = 0, len = locChildren.length; i< len; i++)
this.resumeTarget(locChildren[i], true);
}
},
@@ -228,7 +231,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
for (var i = 0; i < listenerVector.length;) {
selListener = listenerVector[i];
selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
+ if (selListener._getSceneGraphPriority() != null) {
this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
}
@@ -255,8 +258,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (!this._inDispatch) {
listeners.clear();
- delete this._listenersMap[listenerID];
}
+ delete this._listenersMap[listenerID];
}
var locToAddedListeners = this._toAddedListeners, listener;
@@ -270,7 +273,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
},
_sortEventListeners: function (listenerID) {
- var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
+ var dirtyFlag = this.DIRTY_NONE, locFlagMap = this._priorityDirtyFlagMap;
if (locFlagMap[listenerID])
dirtyFlag = locFlagMap[listenerID];
@@ -281,9 +284,9 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (dirtyFlag & this.DIRTY_FIXED_PRIORITY)
this._sortListenersOfFixedPriority(listenerID);
- if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY){
+ if (dirtyFlag & this.DIRTY_SCENE_GRAPH_PRIORITY) {
var rootNode = cc.director.getRunningScene();
- if(rootNode)
+ if (rootNode)
this._sortListenersOfSceneGraphPriority(listenerID, rootNode);
else
locFlagMap[listenerID] = this.DIRTY_SCENE_GRAPH_PRIORITY;
@@ -297,7 +300,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
return;
var sceneGraphListener = listeners.getSceneGraphPriorityListeners();
- if(!sceneGraphListener || sceneGraphListener.length === 0)
+ if (!sceneGraphListener || sceneGraphListener.length === 0)
return;
// Reset priority index
@@ -310,12 +313,12 @@ cc.eventManager = /** @lends cc.eventManager# */{
listeners.getSceneGraphPriorityListeners().sort(this._sortEventListenersOfSceneGraphPriorityDes);
},
- _sortEventListenersOfSceneGraphPriorityDes : function(l1, l2){
+ _sortEventListenersOfSceneGraphPriorityDes: function (l1, l2) {
var locNodePriorityMap = cc.eventManager._nodePriorityMap, node1 = l1._getSceneGraphPriority(),
node2 = l2._getSceneGraphPriority();
- if( !l2 || !node2 || !locNodePriorityMap[node2.__instanceId] )
+ if (!l2 || !node2 || !locNodePriorityMap[node2.__instanceId])
return -1;
- else if( !l1 || !node1 || !locNodePriorityMap[node1.__instanceId] )
+ else if (!l1 || !node1 || !locNodePriorityMap[node1.__instanceId])
return 1;
return locNodePriorityMap[l2._getSceneGraphPriority().__instanceId] - locNodePriorityMap[l1._getSceneGraphPriority().__instanceId];
},
@@ -326,7 +329,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
return;
var fixedListeners = listeners.getFixedPriorityListeners();
- if(!fixedListeners || fixedListeners.length === 0)
+ if (!fixedListeners || fixedListeners.length === 0)
return;
// After sort: priority < 0, > 0
fixedListeners.sort(this._sortListenersOfFixedPriorityAsc);
@@ -345,20 +348,20 @@ cc.eventManager = /** @lends cc.eventManager# */{
return l1._getFixedPriority() - l2._getFixedPriority();
},
- _onUpdateListeners: function (listenerID) {
- var listeners = this._listenersMap[listenerID];
- if (!listeners)
- return;
-
+ _onUpdateListeners: function (listeners) {
var fixedPriorityListeners = listeners.getFixedPriorityListeners();
var sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
- var i, selListener;
+ var i, selListener, idx, toRemovedListeners = this._toRemovedListeners;
if (sceneGraphPriorityListeners) {
for (i = 0; i < sceneGraphPriorityListeners.length;) {
selListener = sceneGraphPriorityListeners[i];
if (!selListener._isRegistered()) {
cc.arrayRemoveObject(sceneGraphPriorityListeners, selListener);
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
} else
++i;
}
@@ -367,9 +370,13 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners) {
for (i = 0; i < fixedPriorityListeners.length;) {
selListener = fixedPriorityListeners[i];
- if (!selListener._isRegistered())
+ if (!selListener._isRegistered()) {
cc.arrayRemoveObject(fixedPriorityListeners, selListener);
- else
+ // if item in toRemove list, remove it from the list
+ idx = toRemovedListeners.indexOf(selListener);
+ if(idx !== -1)
+ toRemovedListeners.splice(idx, 1);
+ } else
++i;
}
}
@@ -381,20 +388,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
listeners.clearFixedListeners();
},
- _updateListeners: function (event) {
- var locInDispatch = this._inDispatch;
- cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
-
- if(locInDispatch > 1)
- return;
-
- if (event.getType() === cc.Event.TOUCH) {
- this._onUpdateListeners(cc._EventListenerTouchOneByOne.LISTENER_ID);
- this._onUpdateListeners(cc._EventListenerTouchAllAtOnce.LISTENER_ID);
- } else
- this._onUpdateListeners(cc.__getListenerID(event));
-
- cc.assert(locInDispatch === 1, cc._LogInfos.EventManager__updateListeners_2);
+ frameUpdateListeners: function () {
var locListenersMap = this._listenersMap, locPriorityDirtyFlagMap = this._priorityDirtyFlagMap;
for (var selKey in locListenersMap) {
if (locListenersMap[selKey].empty()) {
@@ -407,11 +401,72 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (locToAddedListeners.length !== 0) {
for (var i = 0, len = locToAddedListeners.length; i < len; i++)
this._forceAddEventListener(locToAddedListeners[i]);
- this._toAddedListeners.length = 0;
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
+ }
+ },
+
+ _updateTouchListeners: function (event) {
+ var locInDispatch = this._inDispatch;
+ cc.assert(locInDispatch > 0, cc._LogInfos.EventManager__updateListeners);
+
+ if (locInDispatch > 1)
+ return;
+
+ var listeners;
+ listeners = this._listenersMap[cc._EventListenerTouchOneByOne.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+ listeners = this._listenersMap[cc._EventListenerTouchAllAtOnce.LISTENER_ID];
+ if (listeners) {
+ this._onUpdateListeners(listeners);
+ }
+
+ cc.assert(locInDispatch === 1, cc._LogInfos.EventManager__updateListeners_2);
+
+ var locToAddedListeners = this._toAddedListeners;
+ if (locToAddedListeners.length !== 0) {
+ for (var i = 0, len = locToAddedListeners.length; i < len; i++)
+ this._forceAddEventListener(locToAddedListeners[i]);
+ locToAddedListeners.length = 0;
+ }
+ if (this._toRemovedListeners.length !== 0) {
+ this._cleanToRemovedListeners();
}
},
- _onTouchEventCallback: function(listener, argsObj){
+ //Remove all listeners in _toRemoveListeners list and cleanup
+ _cleanToRemovedListeners: function () {
+ var toRemovedListeners = this._toRemovedListeners;
+ for (var i = 0; i < toRemovedListeners.length; i++) {
+ var selListener = toRemovedListeners[i];
+ var listeners = this._listenersMap[selListener._getListenerID()];
+ if (!listeners)
+ continue;
+
+ var idx, fixedPriorityListeners = listeners.getFixedPriorityListeners(),
+ sceneGraphPriorityListeners = listeners.getSceneGraphPriorityListeners();
+
+ if (sceneGraphPriorityListeners) {
+ idx = sceneGraphPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ sceneGraphPriorityListeners.splice(idx, 1);
+ }
+ }
+ if (fixedPriorityListeners) {
+ idx = fixedPriorityListeners.indexOf(selListener);
+ if (idx !== -1) {
+ fixedPriorityListeners.splice(idx, 1);
+ }
+ }
+ }
+ toRemovedListeners.length = 0;
+ },
+
+ _onTouchEventCallback: function (listener, argsObj) {
// Skip if the listener was removed.
if (!listener._isRegistered)
return false;
@@ -430,14 +485,14 @@ cc.eventManager = /** @lends cc.eventManager# */{
} else if (listener._claimedTouches.length > 0
&& ((removedIdx = listener._claimedTouches.indexOf(selTouch)) !== -1)) {
isClaimed = true;
- if(getCode === eventCode.MOVED && listener.onTouchMoved){
+ if (getCode === eventCode.MOVED && listener.onTouchMoved) {
listener.onTouchMoved(selTouch, event);
- } else if(getCode === eventCode.ENDED){
+ } else if (getCode === eventCode.ENDED) {
if (listener.onTouchEnded)
listener.onTouchEnded(selTouch, event);
if (listener._registered)
listener._claimedTouches.splice(removedIdx, 1);
- } else if(getCode === eventCode.CANCELLED){
+ } else if (getCode === eventCode.CANCELLED) {
if (listener.onTouchCancelled)
listener.onTouchCancelled(selTouch, event);
if (listener._registered)
@@ -447,7 +502,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
// If the event was stopped, return directly.
if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
+ cc.eventManager._updateTouchListeners(event);
return true;
}
@@ -493,7 +548,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (event.isStopped())
return;
}
- this._updateListeners(event);
+ this._updateTouchListeners(event);
},
_onTouchesEventCallback: function (listener, callbackParams) {
@@ -503,18 +558,18 @@ cc.eventManager = /** @lends cc.eventManager# */{
var eventCode = cc.EventTouch.EventCode, event = callbackParams.event, touches = callbackParams.touches, getCode = event.getEventCode();
event._setCurrentTarget(listener._node);
- if(getCode === eventCode.BEGAN && listener.onTouchesBegan)
+ if (getCode === eventCode.BEGAN && listener.onTouchesBegan)
listener.onTouchesBegan(touches, event);
- else if(getCode === eventCode.MOVED && listener.onTouchesMoved)
+ else if (getCode === eventCode.MOVED && listener.onTouchesMoved)
listener.onTouchesMoved(touches, event);
- else if(getCode === eventCode.ENDED && listener.onTouchesEnded)
+ else if (getCode === eventCode.ENDED && listener.onTouchesEnded)
listener.onTouchesEnded(touches, event);
- else if(getCode === eventCode.CANCELLED && listener.onTouchesCancelled)
+ else if (getCode === eventCode.CANCELLED && listener.onTouchesCancelled)
listener.onTouchesCancelled(touches, event);
// If the event was stopped, return directly.
if (event.isStopped()) {
- cc.eventManager._updateListeners(event);
+ cc.eventManager._updateTouchListeners(event);
return true;
}
return false;
@@ -636,7 +691,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
},
- _sortNumberAsc : function (a, b) {
+ _sortNumberAsc: function (a, b) {
return a - b;
},
@@ -656,11 +711,11 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
addListener: function (listener, nodeOrPriority) {
cc.assert(listener && nodeOrPriority, cc._LogInfos.eventManager_addListener_2);
- if(!(listener instanceof cc.EventListener)){
+ if (!(listener instanceof cc.EventListener)) {
cc.assert(!cc.isNumber(nodeOrPriority), cc._LogInfos.eventManager_addListener_3);
listener = cc.EventListener.create(listener);
} else {
- if(listener._isRegistered()){
+ if (listener._isRegistered()) {
cc.log(cc._LogInfos.eventManager_addListener_4);
return;
}
@@ -696,8 +751,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
* @param {function} callback
* @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
*/
- addCustomListener: function (eventName, callback) {
- var listener = new cc._EventListenerCustom(eventName, callback);
+ addCustomListener: function (eventName, callback, target) {
+ var listener = new cc._EventListenerCustom(eventName, callback, target);
this.addListener(listener, 1);
return listener;
},
@@ -747,7 +802,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
},
- _removeListenerInCallback: function(listeners, callback){
+ _removeListenerInCallback: function (listeners, callback) {
if (listeners == null)
return false;
@@ -755,7 +810,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
var selListener = listeners[i];
if (selListener._onCustomEvent === callback || selListener._onEvent === callback) {
selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
+ if (selListener._getSceneGraphPriority() != null) {
this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
}
@@ -768,7 +823,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
return false;
},
- _removeListenerInVector : function(listeners, listener){
+ _removeListenerInVector: function (listeners, listener) {
if (listeners == null)
return false;
@@ -776,13 +831,15 @@ cc.eventManager = /** @lends cc.eventManager# */{
var selListener = listeners[i];
if (selListener === listener) {
selListener._setRegistered(false);
- if (selListener._getSceneGraphPriority() != null){
+ if (selListener._getSceneGraphPriority() != null) {
this._dissociateNodeAndEventListener(selListener._getSceneGraphPriority(), selListener);
selListener._setSceneGraphPriority(null); // NULL out the node pointer so we don't have any dangling pointers to destroyed nodes.
}
if (this._inDispatch === 0)
cc.arrayRemoveObject(listeners, selListener);
+ else
+ this._toRemovedListeners.push(selListener);
return true;
}
}
@@ -859,8 +916,8 @@ cc.eventManager = /** @lends cc.eventManager# */{
*/
removeAllListeners: function () {
var locListeners = this._listenersMap, locInternalCustomEventIDs = this._internalCustomListenerIDs;
- for (var selKey in locListeners){
- if(locInternalCustomEventIDs.indexOf(selKey) === -1)
+ for (var selKey in locListeners) {
+ if (locInternalCustomEventIDs.indexOf(selKey) === -1)
this._removeListenersForListenerID(selKey);
}
},
@@ -881,7 +938,7 @@ cc.eventManager = /** @lends cc.eventManager# */{
if (fixedPriorityListeners) {
var found = fixedPriorityListeners.indexOf(listener);
if (found !== -1) {
- if(listener._getSceneGraphPriority() != null)
+ if (listener._getSceneGraphPriority() != null)
cc.log(cc._LogInfos.eventManager_setPriority);
if (listener._getFixedPriority() !== fixedPriority) {
listener._setFixedPriority(fixedPriority);
@@ -919,25 +976,26 @@ cc.eventManager = /** @lends cc.eventManager# */{
this._updateDirtyFlagForSceneGraph();
this._inDispatch++;
- if(!event || !event.getType)
- throw "event is undefined";
- if (event.getType() === cc.Event.TOUCH) {
+ if (!event || !event.getType)
+ throw new Error("event is undefined");
+ if (event._type === cc.Event.TOUCH) {
this._dispatchTouchEvent(event);
this._inDispatch--;
return;
}
- var listenerID = cc.__getListenerID(event);
+ var listenerID = __getListenerID(event);
this._sortEventListeners(listenerID);
var selListeners = this._listenersMap[listenerID];
- if (selListeners != null)
+ if (selListeners) {
this._dispatchEventToListeners(selListeners, this._onListenerCallback, event);
-
- this._updateListeners(event);
+ this._onUpdateListeners(selListeners);
+ }
+
this._inDispatch--;
},
- _onListenerCallback: function(listener, event){
+ _onListenerCallback: function (listener, event) {
event._setCurrentTarget(listener._getSceneGraphPriority());
listener._onEvent(event);
return event.isStopped();
@@ -955,96 +1013,4 @@ cc.eventManager = /** @lends cc.eventManager# */{
}
};
-// The event helper
-cc.EventHelper = function(){};
-
-cc.EventHelper.prototype = {
- constructor: cc.EventHelper,
-
- apply: function ( object ) {
- object.addEventListener = cc.EventHelper.prototype.addEventListener;
- object.hasEventListener = cc.EventHelper.prototype.hasEventListener;
- object.removeEventListener = cc.EventHelper.prototype.removeEventListener;
- object.dispatchEvent = cc.EventHelper.prototype.dispatchEvent;
- },
-
- addEventListener: function ( type, listener, target ) {
- //check 'type' status, if the status is ready, dispatch event next frame
- if(type === "load" && this._textureLoaded){ //only load event checked.
- setTimeout(function(){
- listener.call(target);
- }, 0);
- return;
- }
-
- if ( this._listeners === undefined )
- this._listeners = {};
-
- var listeners = this._listeners;
- if ( listeners[ type ] === undefined )
- listeners[ type ] = [];
-
- if ( !this.hasEventListener(type, listener, target))
- listeners[ type ].push( {callback:listener, eventTarget: target} );
- },
-
- hasEventListener: function ( type, listener, target ) {
- if ( this._listeners === undefined )
- return false;
-
- var listeners = this._listeners;
- if ( listeners[ type ] !== undefined ) {
- for(var i = 0, len = listeners.length; i < len ; i++){
- var selListener = listeners[i];
- if(selListener.callback === listener && selListener.eventTarget === target)
- return true;
- }
- }
- return false;
- },
-
- removeEventListener: function( type, target){
- if ( this._listeners === undefined )
- return;
-
- var listeners = this._listeners;
- var listenerArray = listeners[ type ];
-
- if ( listenerArray !== undefined ) {
- for(var i = 0; i < listenerArray.length ; ){
- var selListener = listenerArray[i];
- if(selListener.eventTarget === target)
- listenerArray.splice( i, 1 );
- else
- i++
- }
- }
- },
-
- dispatchEvent: function ( event, clearAfterDispatch ) {
- if ( this._listeners === undefined )
- return;
-
- if(clearAfterDispatch == null)
- clearAfterDispatch = true;
- var listeners = this._listeners;
- var listenerArray = listeners[ event];
-
- if ( listenerArray !== undefined ) {
- var array = [];
- var length = listenerArray.length;
-
- for ( var i = 0; i < length; i ++ ) {
- array[ i ] = listenerArray[ i ];
- }
-
- for ( i = 0; i < length; i ++ ) {
- array[ i ].callback.call( array[i].eventTarget, this );
- }
-
- if(clearAfterDispatch)
- listenerArray.length = 0;
- }
- }
-};
-
+})();
diff --git a/cocos2d/core/event-manager/CCTouch.js b/cocos2d/core/event-manager/CCTouch.js
index 8a7c017aad..3c8ea79fb9 100644
--- a/cocos2d/core/event-manager/CCTouch.js
+++ b/cocos2d/core/event-manager/CCTouch.js
@@ -33,6 +33,7 @@
* @param {Number} id
*/
cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
+ _lastModified: 0,
_point:null,
_prevPoint:null,
_id:0,
@@ -40,8 +41,7 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
_startPoint:null,
ctor:function (x, y, id) {
- this._point = cc.p(x || 0, y || 0);
- this._id = id || 0;
+ this.setTouchInfo(id, x, y);
},
/**
@@ -136,7 +136,7 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
* @deprecated since v3.0, please use getID() instead
*/
getId:function () {
- cc.log("getId is deprecated. Please use getID instead.")
+ cc.log("getId is deprecated. Please use getID instead.");
return this._id;
},
@@ -150,8 +150,9 @@ cc.Touch = cc.Class.extend(/** @lends cc.Touch# */{
this._prevPoint = this._point;
this._point = cc.p(x || 0, y || 0);
this._id = id;
- if(!this._startPointCaptured){
+ if (!this._startPointCaptured) {
this._startPoint = cc.p(this._point);
+ cc.view._convertPointWithScale(this._startPoint);
this._startPointCaptured = true;
}
},
diff --git a/cocos2d/core/labelttf/CCLabelTTF.js b/cocos2d/core/labelttf/CCLabelTTF.js
index fb4855e6a5..ac988109b9 100644
--- a/cocos2d/core/labelttf/CCLabelTTF.js
+++ b/cocos2d/core/labelttf/CCLabelTTF.js
@@ -71,6 +71,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
_fontSize: 0.0,
_string: "",
_originalText: null,
+ _onCacheCanvasMode: true,
// font shadow
_shadowEnabled: false,
@@ -134,6 +135,11 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
this._renderCmd._setColorsString();
this._renderCmd._updateTexture();
this._setUpdateTextureDirty();
+
+ // Needed for high dpi text.
+ // In order to render it crisp, we request devicePixelRatio times the
+ // font size and scale it down 1/devicePixelRatio.
+ this._scaleX = this._scaleY = 1 / cc.view.getDevicePixelRatio();
return true;
},
@@ -290,7 +296,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
if (a.r != null && a.g != null && a.b != null && a.a != null) {
this._enableShadow(a, b, c);
} else {
- this._enableShadowNoneColor(a, b, c, d)
+ this._enableShadowNoneColor(a, b, c, d);
}
},
@@ -506,8 +512,8 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
this._fontName = textDefinition.fontName;
this._fontSize = textDefinition.fontSize || 12;
- if(textDefinition.lineHeight)
- this._lineHeight = textDefinition.lineHeight
+ if (textDefinition.lineHeight)
+ this._lineHeight = textDefinition.lineHeight;
else
this._lineHeight = this._fontSize;
@@ -531,7 +537,7 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
if (mustUpdateTexture)
this._renderCmd._updateTexture();
var flags = cc.Node._dirtyFlags;
- this._renderCmd.setDirtyFlag(flags.colorDirty|flags.opacityDirty|flags.textDirty);
+ this._renderCmd.setDirtyFlag(flags.colorDirty | flags.opacityDirty | flags.textDirty);
},
_prepareTextDefinition: function (adjustForResolution) {
@@ -577,6 +583,87 @@ cc.LabelTTF = cc.Sprite.extend(/** @lends cc.LabelTTF# */{
return texDef;
},
+ /*
+ * BEGIN SCALE METHODS
+ *
+ * In order to make the value of scaleX and scaleY consistent across
+ * screens, we provide patched versions that return the same values as if
+ * the screen was not HiDPI.
+ */
+
+ /**
+ * Returns the scale factor of the node.
+ * @warning: Assertion will fail when _scaleX != _scaleY.
+ * @function
+ * @return {Number} The scale factor
+ */
+ getScale: function () {
+ if (this._scaleX !== this._scaleY)
+ cc.log(cc._LogInfos.Node_getScale);
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ * Sets the scale factor of the node. 1.0 is the default scale factor. This function can modify the X and Y scale at the same time.
+ * @function
+ * @param {Number} scale or scaleX value
+ * @param {Number} [scaleY=]
+ */
+ setScale: function (scale, scaleY) {
+ var ratio = cc.view.getDevicePixelRatio();
+ this._scaleX = scale / ratio;
+ this._scaleY = ((scaleY || scaleY === 0) ? scaleY : scale) / ratio;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty);
+ },
+
+ /**
+ * Returns the scale factor on X axis of this node
+ * @function
+ * @return {Number} The scale factor on X axis.
+ */
+ getScaleX: function () {
+ return this._scaleX * cc.view.getDevicePixelRatio();
+ },
+
+ /**
+ *
+ * Changes the scale factor on X axis of this node
+ * Changes the scale factor on Y axis of this node Constructor of cc.Layer, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
@@ -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 5c60928ab0..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,38 +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
@@ -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,35 +299,29 @@ 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) {
var ret = false;
- if (element) {
- if(this._hashTargets[element.target.__instanceId]){
+ if (element && !element.lock) {
+ if (this._hashTargets[element.target.__instanceId]) {
delete this._hashTargets[element.target.__instanceId];
- cc.arrayRemoveObject(this._arrayTargets, element);
+ 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;
}
- element.actions = null;
- element.target = null;
}
return ret;
},
- _actionAllocWithHashElement:function (element) {
- // 4 actions per Node by default
- if (element.actions == null) {
- element.actions = [];
- }
- },
-
/**
* @param {Number} dt delta time in seconds
*/
@@ -341,41 +330,30 @@ 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) {
+ 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.
- ****************************************************************************/
-
-/**
- *
- * 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. *
- *
* - 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
* -# 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
@@ -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--;
+ },
+
/**
*
@@ -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, 1, 0 ]
* 0, 1, 0 ]
+ * The results are reflected in the first matrix.
+ * t' = t1 * t2
+ * @function
+ * @param {cc.AffineTransform} t1 The first transform object
+ * @param {cc.AffineTransform} t2 The transform object to concatenate
+ * @return {cc.AffineTransform} The result of concatenation
+ */
+cc.affineTransformConcatIn = function (t1, t2) {
+ var a = t1.a, b = t1.b, c = t1.c, d = t1.d, tx = t1.tx, ty = t1.ty;
+ t1.a = a * t2.a + b * t2.c;
+ t1.b = a * t2.b + b * t2.d;
+ t1.c = c * t2.a + d * t2.c;
+ t1.d = c * t2.b + d * t2.d;
+ t1.tx = tx * t2.a + ty * t2.c + t2.tx;
+ t1.ty = tx * t2.b + ty * t2.d + t2.ty;
+ return t1;
};
/**
@@ -263,6 +287,19 @@ cc.affineTransformEqualToTransform = function (t1, t2) {
*/
cc.affineTransformInvert = function (t) {
var determinant = 1 / (t.a * t.d - t.b * t.c);
- return {a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
- tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)};
+ return {
+ a: determinant * t.d, b: -determinant * t.b, c: -determinant * t.c, d: determinant * t.a,
+ tx: determinant * (t.c * t.ty - t.d * t.tx), ty: determinant * (t.b * t.tx - t.a * t.ty)
+ };
+};
+
+cc.affineTransformInvertOut = function (t, out) {
+ var a = t.a, b = t.b, c = t.c, d = t.d;
+ var determinant = 1 / (a * d - b * c);
+ out.a = determinant * d;
+ out.b = -determinant * b;
+ out.c = -determinant * c;
+ out.d = determinant * a;
+ out.tx = determinant * (c * t.ty - d * t.tx);
+ out.ty = determinant * (b * t.tx - a * t.ty);
};
diff --git a/cocos2d/core/cocoa/CCGeometry.js b/cocos2d/core/cocoa/CCGeometry.js
index 0eeffd5ad2..a3690f21c1 100644
--- a/cocos2d/core/cocoa/CCGeometry.js
+++ b/cocos2d/core/cocoa/CCGeometry.js
@@ -29,6 +29,9 @@
* @class cc.Point
* @param {Number} x
* @param {Number} y
+ *
+ * @property x {Number}
+ * @property y {Number}
* @see cc.p
*/
cc.Point = function (x, y) {
@@ -79,6 +82,8 @@ cc.pointEqualToPoint = function (point1, point2) {
* @class cc.Size
* @param {Number} width
* @param {Number} height
+ * @property {Number} width
+ * @property {Number} height
* @see cc.size
*/
cc.Size = function (width, height) {
@@ -127,8 +132,16 @@ cc.sizeEqualToSize = function (size1, size2) {
/**
* cc.Rect is the class for rect object, please do not use its constructor to create rects, use cc.rect() alias function instead.
* @class cc.Rect
+ * @param {Number} x
+ * @param {Number} y
* @param {Number} width
* @param {Number} height
+ *
+ * @property {Number} x
+ * @property {Number} y
+ * @property {Number} width
+ * @property {Number} height
+ *
* @see cc.rect
*/
cc.Rect = function (x, y, width, height) {
@@ -323,5 +336,3 @@ cc.rectIntersection = function (rectA, rectB) {
intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection);
return intersection;
};
-
-
diff --git a/cocos2d/core/event-manager/CCEventHelper.js b/cocos2d/core/event-manager/CCEventHelper.js
new file mode 100644
index 0000000000..b005e71c59
--- /dev/null
+++ b/cocos2d/core/event-manager/CCEventHelper.js
@@ -0,0 +1,138 @@
+/****************************************************************************
+ Copyright (c) 2011-2012 cocos2d-x.org
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+
+// The event helper
+cc.EventHelper = function () {
+};
+
+cc.EventHelper.prototype = {
+ constructor: cc.EventHelper,
+
+ apply: function (object) {
+ object.addEventListener = cc.EventHelper.prototype.addEventListener;
+ object.hasEventListener = cc.EventHelper.prototype.hasEventListener;
+ object.removeEventListener = cc.EventHelper.prototype.removeEventListener;
+ object.dispatchEvent = cc.EventHelper.prototype.dispatchEvent;
+ },
+
+ addEventListener: function (type, listener, target) {
+ //check 'type' status, if the status is ready, dispatch event next frame
+ if (type === "load" && this._textureLoaded) { //only load event checked.
+ setTimeout(function () {
+ listener.call(target);
+ }, 0);
+ return;
+ }
+
+ if (this._listeners === undefined)
+ this._listeners = {};
+
+ var listeners = this._listeners;
+ if (listeners[type] === undefined)
+ listeners[type] = [];
+
+ if (!this.hasEventListener(type, listener, target))
+ listeners[type].push({callback: listener, eventTarget: target});
+ },
+
+ hasEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return false;
+
+ var listeners = this._listeners;
+ if (listeners[type] !== undefined) {
+ for (var i = 0, len = listeners.length; i < len; i++) {
+ var selListener = listeners[i];
+ if (selListener.callback === listener && selListener.eventTarget === target)
+ return true;
+ }
+ }
+ return false;
+ },
+
+ removeEventListener: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target && selListener.callback === listener)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ removeEventTarget: function (type, listener, target) {
+ if (this._listeners === undefined)
+ return;
+
+ var listeners = this._listeners;
+ var listenerArray = listeners[type];
+
+ if (listenerArray !== undefined) {
+ for (var i = 0; i < listenerArray.length;) {
+ var selListener = listenerArray[i];
+ if (selListener.eventTarget === target)
+ listenerArray.splice(i, 1);
+ else
+ i++
+ }
+ }
+ },
+
+ dispatchEvent: function (event, clearAfterDispatch) {
+ if (this._listeners === undefined)
+ return;
+
+ if (clearAfterDispatch == null)
+ clearAfterDispatch = true;
+ var listeners = this._listeners;
+ var listenerArray = listeners[event];
+
+ if (listenerArray !== undefined) {
+ var array = [];
+ var length = listenerArray.length;
+
+ for (var i = 0; i < length; i++) {
+ array[i] = listenerArray[i];
+ }
+
+ for (i = 0; i < length; i++) {
+ array[i].callback.call(array[i].eventTarget, this);
+ }
+
+ if (clearAfterDispatch)
+ listenerArray.length = 0;
+ }
+ }
+};
+
+cc.EventHelper.prototype.apply(cc.game);
diff --git a/cocos2d/core/event-manager/CCEventListener.js b/cocos2d/core/event-manager/CCEventListener.js
index 3c9dbab79d..c970c43fdf 100644
--- a/cocos2d/core/event-manager/CCEventListener.js
+++ b/cocos2d/core/event-manager/CCEventListener.js
@@ -261,13 +261,13 @@ cc.EventListener.MOUSE = 4;
* @constant
* @type {number}
*/
-cc.EventListener.ACCELERATION = 5;
+cc.EventListener.ACCELERATION = 6;
/**
- * The type code of focus event listener.
+ * The type code of Focus change event listener.
* @constant
* @type {number}
*/
-cc.EventListener.ACCELERATION = 6;
+cc.EventListener.FOCUS = 7;
/**
* The type code of custom event listener.
* @constant
@@ -275,24 +275,18 @@ cc.EventListener.ACCELERATION = 6;
*/
cc.EventListener.CUSTOM = 8;
-/**
- * The type code of Focus change event listener.
- * @constant
- * @type {number}
- */
-cc.EventListener.FOCUS = 7;
-
cc._EventListenerCustom = cc.EventListener.extend({
_onCustomEvent: null,
- ctor: function (listenerId, callback) {
+ ctor: function (listenerId, callback, target) {
this._onCustomEvent = callback;
- var selfPointer = this;
- var listener = function (event) {
- if (selfPointer._onCustomEvent !== null)
- selfPointer._onCustomEvent(event);
- };
+ this._target = target;
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, this._callback);
+ },
+
+ _callback: function (event) {
+ if (this._onCustomEvent !== null)
+ this._onCustomEvent.call(this._target, event);
},
checkAvailable: function () {
@@ -315,31 +309,31 @@ cc._EventListenerMouse = cc.EventListener.extend({
onMouseScroll: null,
ctor: function () {
- var selfPointer = this;
- var listener = function (event) {
- var eventType = cc.EventMouse;
- switch (event._eventType) {
- case eventType.DOWN:
- if (selfPointer.onMouseDown)
- selfPointer.onMouseDown(event);
- break;
- case eventType.UP:
- if (selfPointer.onMouseUp)
- selfPointer.onMouseUp(event);
- break;
- case eventType.MOVE:
- if (selfPointer.onMouseMove)
- selfPointer.onMouseMove(event);
- break;
- case eventType.SCROLL:
- if (selfPointer.onMouseScroll)
- selfPointer.onMouseScroll(event);
- break;
- default:
- break;
- }
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, this._callback);
+ },
+
+ _callback: function (event) {
+ var eventType = cc.EventMouse;
+ switch (event._eventType) {
+ case eventType.DOWN:
+ if (this.onMouseDown)
+ this.onMouseDown(event);
+ break;
+ case eventType.UP:
+ if (this.onMouseUp)
+ this.onMouseUp(event);
+ break;
+ case eventType.MOVE:
+ if (this.onMouseMove)
+ this.onMouseMove(event);
+ break;
+ case eventType.SCROLL:
+ if (this.onMouseScroll)
+ this.onMouseScroll(event);
+ break;
+ default:
+ break;
+ }
},
clone: function () {
@@ -508,11 +502,12 @@ cc._EventListenerFocus = cc.EventListener.extend({
},
onFocusChanged: null,
ctor: function(){
- var listener = function(event){
- if(this.onFocusChanged)
- this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
- };
- cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, listener);
+ cc.EventListener.prototype.ctor.call(this, cc.EventListener.FOCUS, cc._EventListenerFocus.LISTENER_ID, this._callback);
+ },
+ _callback: function (event) {
+ if (this.onFocusChanged) {
+ this.onFocusChanged(event._widgetLoseFocus, event._widgetGetFocus);
+ }
}
});
diff --git a/cocos2d/core/event-manager/CCEventManager.js b/cocos2d/core/event-manager/CCEventManager.js
index 0d02a9a661..7f54f03939 100644
--- a/cocos2d/core/event-manager/CCEventManager.js
+++ b/cocos2d/core/event-manager/CCEventManager.js
@@ -1,6 +1,6 @@
/****************************************************************************
Copyright (c) 2011-2012 cocos2d-x.org
- Copyright (c) 2013-2014 Chukong Technologies Inc.
+ Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
@@ -23,6 +23,8 @@
THE SOFTWARE.
****************************************************************************/
+(function () {
+
/**
* @ignore
*/
@@ -73,25 +75,25 @@ cc._EventListenerVector = cc.Class.extend({
}
});
-cc.__getListenerID = function (event) {
- var eventType = cc.Event, getType = event.getType();
- if(getType === eventType.ACCELERATION)
+function __getListenerID (event) {
+ var eventType = cc.Event, getType = event._type;
+ if (getType === eventType.ACCELERATION)
return cc._EventListenerAcceleration.LISTENER_ID;
- if(getType === eventType.CUSTOM)
- return event.getEventName();
- if(getType === eventType.KEYBOARD)
+ if (getType === eventType.CUSTOM)
+ return event._eventName;
+ if (getType === eventType.KEYBOARD)
return cc._EventListenerKeyboard.LISTENER_ID;
- if(getType === eventType.MOUSE)
+ if (getType === eventType.MOUSE)
return cc._EventListenerMouse.LISTENER_ID;
- if(getType === eventType.FOCUS)
+ if (getType === eventType.FOCUS)
return cc._EventListenerFocus.LISTENER_ID;
- if(getType === eventType.TOUCH){
+ if (getType === eventType.TOUCH) {
// Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
// return UNKNOWN instead.
cc.log(cc._LogInfos.__getListenerID);
}
return "";
-};
+}
/**
*
+ * The default value is 1.0 if you haven't changed it before
+ *
+ * The Default value is 1.0 if you haven't changed it before.
+ *
+ * @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(
- * 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
*
* 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)
*
- * 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.
- *
* 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 4c17e82812..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,166 +131,62 @@
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){
- this._setOriginalTexture();
- 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) {
- this._setOriginalTexture();
- return;
- }
+ proto._updateColor = function () {
+ var node = this._node;
- var locElement, locTexture = node._texture, locRect = this._textureCoord;
- if (locTexture && locRect.validRect && this._originalTexture) {
- locElement = locTexture.getHtmlElementObj();
- if (!locElement)
- return;
+ var texture = node._texture, rect = this._textureCoord;
+ var dColor = this._displayedColor;
+ 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;
- 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.setTexture(locTexture);
- }
+ } else if (texture) {
+ this._textureToRender = texture;
+ this._colorized = false;
}
- };
- }
-
- proto._setOriginalTexture = function () {
- if (this._colorized) {
- this._colorized = false;
- var node = this._node;
- var rect = cc.rect(node._rect);
- var contentSize = cc.size(node._contentSize);
- var isRotation = node._rectRotated;
- node.setTexture(this._originalTexture);
- node.setTextureRect(rect, isRotation, contentSize);
- }
- };
-
- proto.getQuad = function () {
- //throw an error. it doesn't support this function.
- return null;
- };
-
- proto._updateForSetSpriteFrame = function (pNewTexture, textureLoaded){
- this._originalTexture = pNewTexture; //TODO
- this._colorized = false;
- this._textureCoord.renderX = this._textureCoord.x;
- this._textureCoord.renderY = this._textureCoord.y;
- textureLoaded = textureLoaded || pNewTexture._textureLoaded;
- if (textureLoaded) {
- var curColor = this._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;
-
- // 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);
- }
- }
- 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) {
var node = this;
if (node._textureLoaded)
@@ -307,7 +200,6 @@
locRect.width = sender.width;
locRect.height = sender.height;
}
- locRenderCmd._originalTexture = sender;
node.texture = sender;
node.setTextureRect(locRect, node._rectRotated);
@@ -335,159 +227,6 @@
locTextureRect.validRect = !(locTextureRect.width === 0 || locTextureRect.height === 0 || locTextureRect.x < 0 || locTextureRect.y < 0);
};
- //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.
*
- * 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!
+ * 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
+ * A 3x3 matrix + *
+ * @class + * @param {cc.math.Matrix3} [mat3] + */ cc.math.Matrix3 = function(mat3) { if (mat3 && mat3.mat) { this.mat = new Float32Array(mat3.mat); @@ -36,9 +44,16 @@ window.Float32Array = window.Float32Array || window.Array; } }; cc.kmMat3 = cc.math.Matrix3; - var proto = cc.math.Matrix3.prototype; - - proto.fill = function(mat3) { //cc.kmMat3Fill + var _p = cc.math.Matrix3.prototype; + + /** + * Copy matrix. + * @fn fill + * @memberof cc.math.Matrix3 + * @param {cc.math.Matrix3} mat3 Matrix to copy + * @return {cc.math.Matrix3} this + */ + _p.fill = function(mat3) { //cc.kmMat3Fill var mat = this.mat, matIn = mat3.mat; mat[0] = matIn[0]; mat[1] = matIn[1]; @@ -52,7 +67,7 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.adjugate = function(){ //= cc.kmMat3Adjugate + _p.adjugate = function(){ //= cc.kmMat3Adjugate var mat = this.mat; var m0 = mat[0], m1 = mat[1], m2 = mat[2], m3 = mat[3], m4 = mat[4], m5 = mat[5], m6 = mat[6], m7 = mat[7], m8 = mat[8]; @@ -70,7 +85,13 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.identity = function() { //cc.kmMat3Identity + /** + * Sets pOut to an identity matrix returns pOut + * @memberof cc.math.Matrix3 + * @param {cc.math.Matrix3} pOut - A pointer to the matrix to set to identity + * @return {cc.math.Matrix3} this + */ + _p.identity = function() { //cc.kmMat3Identity var mat = this.mat; mat[1] = mat[2] = mat[3] = mat[5] = mat[6] = mat[7] = 0; @@ -80,7 +101,7 @@ window.Float32Array = window.Float32Array || window.Array; var tmpMatrix = new cc.math.Matrix3(); // internal matrix - proto.inverse = function(determinate){ //cc.kmMat3Inverse + _p.inverse = function(determinate){ //cc.kmMat3Inverse if (determinate === 0.0) return this; tmpMatrix.assignFrom(this); @@ -90,14 +111,14 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.isIdentity = function(){ //= cc.kmMat3IsIdentity + _p.isIdentity = function(){ //= cc.kmMat3IsIdentity var mat = this.mat; return (mat[0] === 1 && mat[1] === 0 && mat[2] === 0 && mat[3] === 0 && mat[4] === 1 && mat[5] === 0 && mat[6] === 0 && mat[7] === 0 && mat[8] === 1); }; - proto.transpose = function(){ // cc.kmMat3Transpose + _p.transpose = function(){ // cc.kmMat3Transpose var mat = this.mat; var m1 = mat[1], m2 = mat[2], m3 = mat[3], m5 = mat[5], m6 = mat[6], m7 = mat[7]; @@ -114,7 +135,7 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.determinant = function(){ + _p.determinant = function(){ var mat = this.mat; /* calculating the determinant following the rule of sarus, @@ -122,14 +143,14 @@ window.Float32Array = window.Float32Array || window.Array; m = | 1 4 7 | 1 4 | | 2 5 8 | 2 5 | now sum up the products of the diagonals going to the right (i.e. 0,4,8) - and substract the products of the other diagonals (i.e. 2,4,6) + and subtract the products of the other diagonals (i.e. 2,4,6) */ var output = mat[0] * mat[4] * mat[8] + mat[1] * mat[5] * mat[6] + mat[2] * mat[3] * mat[7]; output -= mat[2] * mat[4] * mat[6] + mat[0] * mat[5] * mat[7] + mat[1] * mat[3] * mat[8]; return output; }; - proto.multiply = function(mat3){ + _p.multiply = function(mat3){ var m1 = this.mat, m2 = mat3.mat; var a0 = m1[0], a1 = m1[1], a2 = m1[2], a3 = m1[3], a4 = m1[4], a5 = m1[5], a6 = m1[6], a7 = m1[7], a8 = m1[8]; @@ -150,7 +171,7 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.multiplyScalar = function(factor) { + _p.multiplyScalar = function(factor) { var mat = this.mat; mat[0] *= factor; mat[1] *= factor; @@ -184,7 +205,7 @@ window.Float32Array = window.Float32Array || window.Array; return retMat; }; - proto.assignFrom = function(matIn){ // cc.kmMat3Assign + _p.assignFrom = function(matIn){ // cc.kmMat3Assign if(this === matIn) { cc.log("cc.math.Matrix3.assign(): current matrix equals matIn"); return this; @@ -202,7 +223,7 @@ window.Float32Array = window.Float32Array || window.Array; return this; }; - proto.equals = function(mat3) { + _p.equals = function(mat3) { if (this === mat3) return true; var EPSILON = cc.math.EPSILON,m1 = this.mat, m2 = mat3.mat; @@ -330,14 +351,7 @@ window.Float32Array = window.Float32Array || window.Array; return ret; }; - proto.rotationToAxisAngle = function() { //cc.kmMat3RotationToAxisAngle + _p.rotationToAxisAngle = function() { //cc.kmMat3RotationToAxisAngle return cc.math.Quaternion.rotationMatrix(this).toAxisAndAngle(); } })(cc); - - - - - - - diff --git a/cocos2d/kazmath/mat4.js b/cocos2d/kazmath/mat4.js index d211589531..35a56e1050 100644 --- a/cocos2d/kazmath/mat4.js +++ b/cocos2d/kazmath/mat4.js @@ -37,6 +37,7 @@ * | 2 6 10 14 | * | 3 7 11 15 | * + * @class * @param {cc.math.Matrix4} [mat4] */ cc.math.Matrix4 = function (mat4) { @@ -63,8 +64,8 @@ /** * Sets pOut to an identity matrix returns pOut - * @Params pOut - A pointer to the matrix to set to identity - * @Return Returns pOut so that the call can be nested + * @param pOut - A pointer to the matrix to set to identity + * @returns Returns pOut so that the call can be nested */ cc.kmMat4Identity = function (pOut) { var mat = pOut.mat; @@ -106,7 +107,7 @@ //Returns an upper and a lower triangular matrix which are L and R in the Gauss algorithm cc.math.Matrix4._gaussj = function (a, b) { var i, icol = 0, irow = 0, j, k, l, ll, n = 4, m = 4, selElement; - var big, dum, pivinv; + var big, dumb, pivinv; var indxc = [0, 0, 0, 0], indxr = [0, 0, 0, 0], ipiv = [0, 0, 0, 0]; /* for (j = 0; j < n; j++) { @@ -151,13 +152,13 @@ for (ll = 0; ll < n; ll++) { if (ll !== icol) { - dum = a.get(ll, icol); + dumb = a.get(ll, icol); a.set(ll, icol, 0.0); for (l = 0; l < n; l++) - a.set(ll, l, a.get(ll, l) - a.get(icol, l) * dum); + a.set(ll, l, a.get(ll, l) - a.get(icol, l) * dumb); for (l = 0; l < m; l++) - b.set(ll, l, a.get(ll, l) - b.get(icol, l) * dum); + b.set(ll, l, a.get(ll, l) - b.get(icol, l) * dumb); } } } @@ -1008,7 +1009,3 @@ return temp.toAxisAndAngle(); }; })(cc); - - - - diff --git a/cocos2d/kazmath/plane.js b/cocos2d/kazmath/plane.js index 94ab4e9b71..db5f9dd1e6 100644 --- a/cocos2d/kazmath/plane.js +++ b/cocos2d/kazmath/plane.js @@ -81,7 +81,7 @@ Planea = Nx Planeb = Ny Planec = Nz - Planed = −N⋅P + Planned = −N⋅P */ return new cc.math.Plane(normal.x, normal.y, normal.z, -normal.dot(vec3)); }; diff --git a/cocos2d/kazmath/quaternion.js b/cocos2d/kazmath/quaternion.js index ac926ebec2..fcbd652da9 100644 --- a/cocos2d/kazmath/quaternion.js +++ b/cocos2d/kazmath/quaternion.js @@ -155,7 +155,7 @@ proto.normalize = function(){ //=cc.kmQuaternionNormalize var length = this.length(); if (Math.abs(length) <= cc.math.EPSILON) - throw "current quaternion is an invalid value"; + throw new Error("current quaternion is an invalid value"); this.scale(1.0 / length); return this; }; diff --git a/cocos2d/kazmath/simd_benchmark/index.html b/cocos2d/kazmath/simd_benchmark/index.html index 5b115d91c9..8c9cb4f410 100644 --- a/cocos2d/kazmath/simd_benchmark/index.html +++ b/cocos2d/kazmath/simd_benchmark/index.html @@ -7,7 +7,7 @@diff --git a/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js b/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js index 2be997851d..890c98be25 100644 --- a/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelAtlasCanvasRenderCmd.js @@ -41,15 +41,21 @@ var node = this._node; var locString = node._string || ""; var n = locString.length; - var texture = this._texture; + var texture = this._textureToRender; var locItemWidth = node._itemWidth , locItemHeight = node._itemHeight; //needn't multiply cc.contentScaleFactor(), because sprite's draw will do this - for (var i = 0; i < n; i++) { + for (var i = 0, cr = -1; i < n; i++) { var a = locString.charCodeAt(i) - node._mapStartChar.charCodeAt(0); var row = parseInt(a % node._itemsPerRow, 10); var col = parseInt(a / node._itemsPerRow, 10); - + if(row < 0 || col < 0) + continue; var rect = cc.rect(row * locItemWidth, col * locItemHeight, locItemWidth, locItemHeight); + var textureContent = texture._contentSize; + if(rect.x < 0 || rect.y < 0 || rect.x + rect.width > textureContent.width || rect.y + rect.height > textureContent.height) + continue; + + cr++; var c = locString.charCodeAt(i); var fontChar = node.getChildByTag(i); if (!fontChar) { @@ -72,7 +78,16 @@ fontChar.visible = true; } } - fontChar.setPosition(i * locItemWidth + locItemWidth / 2, locItemHeight / 2); + fontChar.setPosition(cr * locItemWidth + locItemWidth / 2, locItemHeight / 2); + } + this.updateContentSize(i, cr+1); + }; + + proto.updateContentSize = function(i, cr){ + var node = this._node, + contentSize = node._contentSize; + if(i !== cr && i*node._itemWidth === contentSize.width && node._itemHeight === contentSize.height){ + node.setContentSize(cr * node._itemWidth, node._itemHeight); } }; diff --git a/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js b/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js index ef548032e3..5edf6c501b 100644 --- a/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js +++ b/cocos2d/labels/CCLabelAtlasWebGLRenderCmd.js @@ -22,8 +22,8 @@ THE SOFTWARE. ****************************************************************************/ -(function(){ - cc.LabelAtlas.WebGLRenderCmd = function(renderable){ +(function () { + cc.LabelAtlas.WebGLRenderCmd = function (renderable) { cc.AtlasNode.WebGLRenderCmd.call(this, renderable); this._needDraw = true; }; @@ -31,23 +31,48 @@ var proto = cc.LabelAtlas.WebGLRenderCmd.prototype = Object.create(cc.AtlasNode.WebGLRenderCmd.prototype); proto.constructor = cc.LabelAtlas.WebGLRenderCmd; - proto.setCascade = function(){ + proto._updateColor = function () { + if (this._colorF32Array) { + var locDisplayedColor = this._displayedColor; + var a = this._displayedOpacity / 255; + if (this._node._opacityModifyRGB) { + this._colorF32Array[0] = locDisplayedColor.r * a / 255; + this._colorF32Array[1] = locDisplayedColor.g * a / 255; + this._colorF32Array[2] = locDisplayedColor.b * a / 255; + this._colorF32Array[3] = a; + } + else { + this._colorF32Array[0] = locDisplayedColor.r / 255; + this._colorF32Array[1] = locDisplayedColor.g / 255; + this._colorF32Array[2] = locDisplayedColor.b / 255; + this._colorF32Array[3] = a; + } + } + }; + + proto.setCascade = function () { var node = this._node; node._cascadeOpacityEnabled = true; node._cascadeColorEnabled = true; }; - proto.rendering = function(ctx){ + proto.rendering = function (ctx) { cc.AtlasNode.WebGLRenderCmd.prototype.rendering.call(this, ctx); if (cc.LABELATLAS_DEBUG_DRAW) { - var s = this._node.getContentSize(); - var vertices = [cc.p(0, 0), cc.p(s.width, 0), - cc.p(s.width, s.height), cc.p(0, s.height)]; + var node = this._node; + var s = node.getContentSize(); + var locRect = node.getBoundingBoxToWorld(); + var posX = locRect.x, + posY = locRect.y; + s.width = locRect.width; + s.height = locRect.height; + var vertices = [cc.p(posX, posY), cc.p(posX + s.width, posY), + cc.p(s.width + posX, s.height + posY), cc.p(posX, posY + s.height)]; cc._drawingUtil.drawPoly(vertices, 4, true); } }; - proto.updateAtlasValues = function(){ + proto.updateAtlasValues = function () { var node = this._node; var locString = node._string; var n = locString.length; @@ -65,14 +90,18 @@ if (n > locTextureAtlas.getCapacity()) cc.log("cc.LabelAtlas._updateAtlasValues(): Invalid String length"); var quads = locTextureAtlas.quads; - var locDisplayedColor = this._displayedColor; - var curColor = {r: locDisplayedColor.r, g: locDisplayedColor.g, b: locDisplayedColor.b, a: node._displayedOpacity}; var locItemWidth = node._itemWidth; - for (var i = 0; i < n; i++) { + var locItemHeight = node._itemHeight; + for (var i = 0, cr = -1; i < n; i++) { var a = locString.charCodeAt(i) - node._mapStartChar.charCodeAt(0); var row = a % node._itemsPerRow; var col = 0 | (a / node._itemsPerRow); + if (row < 0 || col < 0) + continue; + if (row * locItemWidth + locItemWidth > textureWide || col * locItemHeight + locItemHeight > textureHigh) + continue; + cr++; var left, right, top, bottom; if (cc.FIX_ARTIFACTS_BY_STRECHING_TEXEL) { // Issue #938. Don't use texStepX & texStepY @@ -97,23 +126,23 @@ locQuadBR.texCoords.u = right; locQuadBR.texCoords.v = bottom; - locQuadBL.vertices.x = (i * locItemWidth); + locQuadBL.vertices.x = (cr * locItemWidth); locQuadBL.vertices.y = 0; locQuadBL.vertices.z = 0.0; - locQuadBR.vertices.x = (i * locItemWidth + locItemWidth); + locQuadBR.vertices.x = (cr * locItemWidth + locItemWidth); locQuadBR.vertices.y = 0; locQuadBR.vertices.z = 0.0; - locQuadTL.vertices.x = i * locItemWidth; + locQuadTL.vertices.x = cr * locItemWidth; locQuadTL.vertices.y = node._itemHeight; locQuadTL.vertices.z = 0.0; - locQuadTR.vertices.x = i * locItemWidth + locItemWidth; + locQuadTR.vertices.x = cr * locItemWidth + locItemWidth; locQuadTR.vertices.y = node._itemHeight; locQuadTR.vertices.z = 0.0; - locQuadTL.colors = curColor; - locQuadTR.colors = curColor; - locQuadBL.colors = curColor; - locQuadBR.colors = curColor; } + + this._updateColor(); + + this.updateContentSize(i, cr + 1); if (n > 0) { locTextureAtlas.dirty = true; var totalQuads = locTextureAtlas.totalQuads; @@ -122,11 +151,20 @@ } }; - proto.setString = function(label){ + proto.updateContentSize = function (i, cr) { + var node = this._node, + contentSize = node._contentSize; + if (i !== cr && i * node._itemWidth === contentSize.width && node._itemHeight === contentSize.height) { + node.setContentSize(cr * node._itemWidth, node._itemHeight); + } + }; + + proto.setString = function (label) { var len = label.length; if (len > this._textureAtlas.totalQuads) this._textureAtlas.resizeCapacity(len); }; - proto._addChild = function(){}; -})(); \ No newline at end of file + proto._addChild = function () { + }; +})(); diff --git a/cocos2d/labels/CCLabelBMFont.js b/cocos2d/labels/CCLabelBMFont.js index e79df5a28a..388f0e858c 100644 --- a/cocos2d/labels/CCLabelBMFont.js +++ b/cocos2d/labels/CCLabelBMFont.js @@ -29,11 +29,6 @@ http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java) http://www.angelcode.com/products/bmfont/ (Free, Windows only) ****************************************************************************/ -/** - * @constant - * @type Number - */ -cc.LABEL_AUTOMATIC_WIDTH = -1; /** *
cc.LabelBMFont is a subclass of cc.SpriteBatchNode.
@@ -108,13 +103,11 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ _lineBreakWithoutSpaces: false, _imageOffset: null, - _reusedChar: null, - _textureLoaded: false, _className: "LabelBMFont", - _createRenderCmd: function(){ - if(cc._renderType === cc._RENDER_TYPE_WEBGL) + _createRenderCmd: function () { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new cc.LabelBMFont.WebGLRenderCmd(this); else return new cc.LabelBMFont.CanvasRenderCmd(this); @@ -126,6 +119,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ } else { this._initialString = newString; } + var locChildren = this._children; if (locChildren) { for (var i = 0; i < locChildren.length; i++) { @@ -135,7 +129,9 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ } } if (this._textureLoaded) { - this.createFontChars(); + if(this._string && this._string.length > 0) { + this.createFontChars(); + } if (needUpdateLabel) this.updateLabel(); } @@ -153,7 +149,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ ctor: function (str, fntFile, width, alignment, imageOffset) { cc.SpriteBatchNode.prototype.ctor.call(this); this._imageOffset = cc.p(0, 0); - this._reusedChar = []; this._cascadeColorEnabled = true; this._cascadeOpacityEnabled = true; this.initWithString(str, fntFile, width, alignment, imageOffset); @@ -224,7 +219,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ */ initWithString: function (str, fntFile, width, alignment, imageOffset) { var self = this, theString = str || ""; - var cmd = this._renderCmd; if (self._config) cc.log("cc.LabelBMFont.initWithString(): re-init is no longer supported"); @@ -233,13 +227,23 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ if (fntFile) { var newConf = cc.loader.getRes(fntFile); if (!newConf) { - cc.log("cc.LabelBMFont.initWithString(): Impossible to create font. Please check file"); - return false; + newConf = cc.FntFrameCache[fntFile] || cc.FntFrameCache[cc.path.basename(fntFile)]; + if(!newConf) { + cc.log("cc.LabelBMFont.initWithString(): Impossible to create font. Please check file"); + return false; + } } self._config = newConf; self._fntFile = fntFile; - texture = cc.textureCache.addImage(newConf.atlasName); + var spriteFrameBaseName = newConf.atlasName; + var spriteFrame = cc.spriteFrameCache.getSpriteFrame(spriteFrameBaseName) || cc.spriteFrameCache.getSpriteFrame(cc.path.basename(spriteFrameBaseName)); + if(spriteFrame) { + texture = spriteFrame.getTexture(); + this._spriteFrame = spriteFrame; + } else { + texture = cc.textureCache.addImage(newConf.atlasName); + } var locIsLoaded = texture.isLoaded(); self._textureLoaded = locIsLoaded; if (!locIsLoaded) { @@ -262,7 +266,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ if (self.initWithTexture(texture, theString.length)) { self._alignment = alignment || cc.TEXT_ALIGNMENT_LEFT; self._imageOffset = imageOffset || cc.p(0, 0); - self._width = (width == null) ? -1 : width; + self._width = (width === undefined) ? -1 : width; self._realOpacity = 255; self._realColor = cc.color(255, 255, 255, 255); @@ -272,9 +276,8 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ self.setAnchorPoint(0.5, 0.5); - this._renderCmd._initBatchTexture(); - self.setString(theString, true); + return true; } return false; @@ -284,9 +287,12 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ * updates the font chars based on the string to render */ createFontChars: function () { + var locStr = this._string; + var stringLen = locStr ? locStr.length : 0; + var self = this; var cmd = this._renderCmd; - var locTexture = cmd._texture || self.textureAtlas.texture; + var locTexture = cmd._texture || this._texture; var nextFontPositionX = 0; @@ -296,11 +302,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var quantityOfLines = 1; - var locStr = self._string; - var stringLen = locStr ? locStr.length : 0; - - if (stringLen === 0) - return; var i, locCfg = self._config, locKerningDict = locCfg.kerningDict, locCommonH = locCfg.commonHeight, locFontDict = locCfg.fontDefDictionary; @@ -312,6 +313,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var nextFontPositionY = -(locCommonH - locCommonH * quantityOfLines); var prev = -1; + var fontDef; for (i = 0; i < stringLen; i++) { var key = locStr.charCodeAt(i); if (key === 0) continue; @@ -324,7 +326,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ } var kerningAmount = locKerningDict[(prev << 16) | (key & 0xffff)] || 0; - var fontDef = locFontDict[key]; + fontDef = locFontDict[key]; if (!fontDef) { cc.log("cocos2d: LabelBMFont: character not found " + locStr[i]); @@ -346,20 +348,35 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ rect.x += self._imageOffset.x; rect.y += self._imageOffset.y; + var isRotated = false; + if(this._spriteFrame) { + var textureWidth = locTexture.width; + var spriteFrameRect = this._spriteFrame._rect; + if(!this._spriteFrame._rotated) { + rect.x = rect.x + spriteFrameRect.x; + rect.y = rect.y + spriteFrameRect.y; + } else { + isRotated = true; + var originalX = rect.x; + rect.x = rect.y + spriteFrameRect.x; + rect.y = originalX + spriteFrameRect.y; + } + } + var fontChar = self.getChildByTag(i); - if(!fontChar){ + if (!fontChar) { fontChar = new cc.Sprite(); - fontChar.initWithTexture(locTexture, rect, false); + fontChar.initWithTexture(locTexture, rect, isRotated); fontChar._newTextureWhenChangeColor = true; this.addChild(fontChar, 0, i); - }else{ - this._renderCmd._updateCharTexture(fontChar, rect, key); + } else { + cmd._updateCharTexture(fontChar, rect, key, isRotated); } // Apply label properties fontChar.opacityModifyRGB = this._opacityModifyRGB; - this._renderCmd._updateCharColorAndOpacity(fontChar); + cmd._updateCharColorAndOpacity(fontChar); var yOffset = locCfg.commonHeight - fontDef.yOffset; var fontPos = cc.p(nextFontPositionX + fontDef.xOffset + fontDef.rect.width * 0.5 + kerningAmount, @@ -376,7 +393,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ //If the last character processed has an xAdvance which is less that the width of the characters image, then we need // to adjust the width of the string to take this into account, or the character will overlap the end of the bounding box - if(fontDef && fontDef.xAdvance < fontDef.rect.width) + if (fontDef && fontDef.xAdvance < fontDef.rect.width) tmpSize.width = longestLine - fontDef.xAdvance + fontDef.rect.width; else tmpSize.width = longestLine; @@ -393,13 +410,17 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var self = this; var locChildren = self._children; if (locChildren) { - for (var i = 0, li = locChildren.length; i < li; i++) { + var length = locChildren.length; + for (var i = 0, li = length; i < li; i++) { var node = locChildren[i]; if (node) node.visible = false; } } - if (self._config) - self.createFontChars(); + if (self._config) { + if(self._string && self._string.length > 0) { + self.createFontChars(); + } + } if (!fromUpdate) self.updateLabel(); @@ -420,9 +441,9 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ */ setString: function (newString, needUpdateLabel) { newString = String(newString); - if (needUpdateLabel == null) + if (needUpdateLabel === undefined) needUpdateLabel = true; - if (newString == null || !cc.isString(newString)) + if (newString === undefined || typeof newString !== 'string') newString = newString + ""; this._initialString = newString; @@ -444,9 +465,8 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ }, // calc the text all with in a line - _getCharsWidth:function (startIndex, endIndex) { - if (endIndex <= 0) - { + _getCharsWidth: function (startIndex, endIndex) { + if (endIndex <= 0) { return 0; } var curTextFirstSprite = this.getChildByTag(startIndex); @@ -454,12 +474,11 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ return this._getLetterPosXLeft(curTextLastSprite) - this._getLetterPosXLeft(curTextFirstSprite); }, - _checkWarp:function (strArr, i, maxWidth, initStringWrapNum) { + _checkWarp: function (strArr, i, maxWidth, initStringWrapNum) { var self = this; var text = strArr[i]; var curLength = 0; - for (var strArrIndex = 0; strArrIndex < i; strArrIndex++) - { + for (var strArrIndex = 0; strArrIndex < i; strArrIndex++) { curLength += strArr[strArrIndex].length; } @@ -550,6 +569,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ updateLabel: function () { var self = this; self.string = self._initialString; + var i, j, characterSprite; // process string // Step 1: Make multiline @@ -564,8 +584,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ if (oldArrLength < stringArr.length) { newWrapNum++; } - if (i > 0) - { + if (i > 0) { wrapString += "\n"; } wrapString += stringArr[i]; @@ -573,7 +592,6 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ wrapString = wrapString + String.fromCharCode(0); self._setString(wrapString, false); } - // Step 2: Make alignment if (self._alignment !== cc.TEXT_ALIGNMENT_LEFT) { i = 0; @@ -723,21 +741,25 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ var texture = cc.textureCache.addImage(newConf.atlasName); var locIsLoaded = texture.isLoaded(); self._textureLoaded = locIsLoaded; - self.texture = texture; - this._renderCmd._updateFntFileTexture(); if (!locIsLoaded) { texture.addEventListener("load", function (sender) { var self1 = this; self1._textureLoaded = true; - self1.texture = sender; - self1.createFontChars(); + self1.setTexture(sender); + if(self1._string && self1._string.length > 0) { + self1.createFontChars(); + } + self1._changeTextureColor(); self1.updateLabel(); self1.dispatchEvent("load"); }, self); } else { - self.createFontChars(); + self.setTexture(texture); + if(self._string && self._string.length > 0) { + self.createFontChars(); + } } } }, @@ -750,7 +772,8 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ return this._fntFile; }, - setTexture: function(texture){ + setTexture: function (texture) { + this._texture = texture; this._renderCmd.setTexture(texture); }, @@ -776,7 +799,8 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ this.updateLabel(); }, - _atlasNameFromFntFile: function (fntFile) {}, + _atlasNameFromFntFile: function (fntFile) { + }, _kerningAmountForFirst: function (first, second) { var ret = 0; @@ -798,14 +822,14 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ }, //Checking whether the character is a whitespace - _isspace_unicode: function(ch){ + _isspace_unicode: function (ch) { ch = ch.charCodeAt(0); - return ((ch >= 9 && ch <= 13) || ch === 32 || ch === 133 || ch === 160 || ch === 5760 - || (ch >= 8192 && ch <= 8202) || ch === 8232 || ch === 8233 || ch === 8239 - || ch === 8287 || ch === 12288) + return ((ch >= 9 && ch <= 13) || ch === 32 || ch === 133 || ch === 160 || ch === 5760 + || (ch >= 8192 && ch <= 8202) || ch === 8232 || ch === 8233 || ch === 8239 + || ch === 8287 || ch === 12288); }, - _utf8_trim_ws: function(str){ + _utf8_trim_ws: function (str) { var len = str.length; if (len <= 0) @@ -829,7 +853,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ //Trims str st str=[0, index) after the operation. //Return value: the trimmed string. - _utf8_trim_from: function(str, index){ + _utf8_trim_from: function (str, index) { var len = str.length; if (index >= len || index < 0) return; @@ -837,7 +861,7 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ } }); -(function(){ +(function () { var p = cc.LabelBMFont.prototype; cc.EventHelper.prototype.apply(p); @@ -850,6 +874,9 @@ cc.LabelBMFont = cc.SpriteBatchNode.extend(/** @lends cc.LabelBMFont# */{ /** @expose */ p.textAlign; cc.defineGetterSetter(p, "textAlign", p._getAlignment, p.setAlignment); + + // Override properties + cc.defineGetterSetter(p, "texture", p.getTexture, p.setTexture); })(); /** @@ -866,7 +893,11 @@ cc.LabelBMFont.create = function (str, fntFile, width, alignment, imageOffset) { return new cc.LabelBMFont(str, fntFile, width, alignment, imageOffset); }; -cc._fntLoader = { +cc.FntFrameCache = {}; + +var _fntLoader = { + FNT_HEAD: /fntframes [^\n]*(\n|$)/gi, + FNT_FRAME_NAME: /fntframe [^\n]*(\n|$)/gi, INFO_EXP: /info [^\n]*(\n|$)/gi, COMMON_EXP: /common [^\n]*(\n|$)/gi, PAGE_EXP: /page [^\n]*(\n|$)/gi, @@ -892,28 +923,12 @@ cc._fntLoader = { return obj; }, - /** - * Parse Fnt string. - * @param fntStr - * @param url - * @returns {{}} - */ - parseFnt: function (fntStr, url) { - var self = this, fnt = {}; - //padding - var infoObj = self._parseStrToObj(fntStr.match(self.INFO_EXP)[0]); - var paddingArr = infoObj["padding"].split(","); - var padding = { - left: parseInt(paddingArr[0]), - top: parseInt(paddingArr[1]), - right: parseInt(paddingArr[2]), - bottom: parseInt(paddingArr[3]) - }; - + _parseFntContent: function (fnt, fntStr, url, useAtlas) { + var self = this; //common var commonObj = self._parseStrToObj(fntStr.match(self.COMMON_EXP)[0]); fnt.commonHeight = commonObj["lineHeight"]; - if (cc._renderType === cc._RENDER_TYPE_WEBGL) { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { var texSize = cc.configuration.getMaxTextureSize(); if (commonObj["scaleW"] > texSize.width || commonObj["scaleH"] > texSize.height) cc.log("cc.LabelBMFont._parseCommonArguments(): page can't be larger than supported"); @@ -923,7 +938,11 @@ cc._fntLoader = { //page var pageObj = self._parseStrToObj(fntStr.match(self.PAGE_EXP)[0]); if (pageObj["id"] !== 0) cc.log("cc.LabelBMFont._parseImageFileName() : file could not be found"); - fnt.atlasName = cc.path.changeBasename(url, pageObj["file"]); + if(!useAtlas) { + fnt.atlasName = cc.path.changeBasename(url, pageObj["file"]); + } else { + fnt.atlasName = cc.path.join(cc.path.dirname(useAtlas.path) + pageObj["file"]); + } //char var charLines = fntStr.match(self.CHAR_EXP); @@ -948,6 +967,40 @@ cc._fntLoader = { kerningDict[(kerningObj["first"] << 16) | (kerningObj["second"] & 0xffff)] = kerningObj["amount"]; } } + + return fnt; + }, + + /** + * Parse Fnt string. + * @param fntStr + * @param url + * @returns {{}} + */ + parseFnt: function (fntStr, url) { + var self = this, fnt = {}; + var headString = fntStr.match(self.FNT_HEAD); + if(headString) { + var headObj = self._parseStrToObj(headString[0]); + if(headObj && headObj.count) { + fntStr = fntStr.substr(headString[0].length); + var fntFrames = fntStr.split("----"); + for(var i = 0; i < headObj.count; ++i) { + var contentString = fntFrames[i]; + var frameNameStr = contentString.match(self.FNT_FRAME_NAME); + if(frameNameStr) { + var frameName = self._parseStrToObj(frameNameStr[0]); + if(frameName && frameName.name) { + fnt = {}; + var realFntPathKey = cc.path.join(cc.path.dirname(url), frameName.name); + cc.FntFrameCache[realFntPathKey] = this._parseFntContent(fnt, contentString.substr(frameNameStr[0].length), url, {path: frameName.name}); + } + } + } + } + } else { + fnt = this._parseFntContent(fnt, fntStr, url); + } return fnt; }, @@ -966,4 +1019,4 @@ cc._fntLoader = { }); } }; -cc.loader.register(["fnt"], cc._fntLoader); +cc.loader.register(["fnt"], _fntLoader); diff --git a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js index 2fd0ac9792..5861daa30a 100644 --- a/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontCanvasRenderCmd.js @@ -30,20 +30,15 @@ http://www.angelcode.com/products/bmfont/ (Free, Windows only) ****************************************************************************/ -(function(){ - cc.LabelBMFont.CanvasRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderableObject); - this._needDraw = true; +(function () { + cc.LabelBMFont.CanvasRenderCmd = function (renderableObject) { + this._rootCtor(renderableObject); }; - var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype); + var proto = cc.LabelBMFont.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype); proto.constructor = cc.LabelBMFont.CanvasRenderCmd; - proto.rendering = function(){ - void 0; - }; - - proto._updateCharTexture = function(fontChar, rect, key){ + proto._updateCharTexture = function (fontChar, rect, key) { if (key === 32) { fontChar.setTextureRect(rect, false, cc.size(0, 0)); } else { @@ -54,7 +49,7 @@ } }; - proto._updateCharColorAndOpacity = function(fontChar){ + proto._updateCharColorAndOpacity = function (fontChar) { // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on fontChar._displayedColor = this._displayedColor; fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.colorDirty); @@ -62,11 +57,6 @@ fontChar._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.opacityDirty); }; - proto._updateFntFileTexture = function(){ - var node = this._node; - node._originalTexture = node.texture; - }; - proto.setTexture = function (texture) { var node = this._node; var locChildren = node._children; @@ -75,68 +65,37 @@ var selChild = locChildren[i]; var cm = selChild._renderCmd; var childDColor = cm._displayedColor; - if (this._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r || + if (node._texture !== cm._texture && (childDColor.r !== locDisplayedColor.r || childDColor.g !== locDisplayedColor.g || childDColor.b !== locDisplayedColor.b)) continue; selChild.texture = texture; } - this._texture = texture; + node._texture = texture; }; - if(cc.sys._supportCanvasNewBlendModes) - proto._changeTextureColor = function(){ - var node = this._node; - var locTexture = node.getTexture(); - if (locTexture && locTexture.getContentSize().width>0) { - 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 && !node._rectRotated){ - cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(element, this._displayedColor, textureRect, locElement); - node.setTexture(locTexture); - } else { - locElement = cc.Sprite.CanvasRenderCmd._generateTintImageWithMultiply(element, this._displayedColor, 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 && locTexture.getContentSize().width > 0) { - locElement = locTexture.getHtmlElementObj(); - if (!locElement) - return; - var cacheTextureForColor = cc.textureCache.getTextureColors(this._originalTexture.getHtmlElementObj()); - if (cacheTextureForColor) { - if (locElement instanceof HTMLCanvasElement && !this._rectRotated) { - cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, this._displayedColor, null, locElement); - this.setTexture(locTexture); - } else { - locElement = cc.Sprite.CanvasRenderCmd._generateTintImage(locElement, cacheTextureForColor, this._displayedColor); - locTexture = new cc.Texture2D(); - locTexture.initWithElement(locElement); - locTexture.handleLoadedTexture(); - node.setTexture(locTexture); - } - } - } - }; + proto._changeTextureColor = function () { + var node = this._node; + var texture = node._texture, + contentSize = texture.getContentSize(); + + var oTexture = node._texture, + oElement = oTexture.getHtmlElementObj(); + var disColor = this._displayedColor; + var textureRect = cc.rect(0, 0, oElement.width, oElement.height); + if (texture && contentSize.width > 0) { + if (!oElement) + return; + var textureToRender = oTexture._generateColorTexture(disColor.r, disColor.g, disColor.b, textureRect); + node.setTexture(textureToRender); + } + }; - proto._updateChildrenDisplayedOpacity = function(locChild){ + proto._updateChildrenDisplayedOpacity = function (locChild) { cc.Node.prototype.updateDisplayedOpacity.call(locChild, this._displayedOpacity); }; - proto._updateChildrenDisplayedColor = function(locChild){ + proto._updateChildrenDisplayedColor = function (locChild) { cc.Node.prototype.updateDisplayedColor.call(locChild, this._displayedColor); }; - proto._initBatchTexture = function(){}; - -})(); \ No newline at end of file +})(); diff --git a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js index 8d0aee5e13..09e18a5f6b 100644 --- a/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js +++ b/cocos2d/labels/CCLabelBMFontWebGLRenderCmd.js @@ -30,58 +30,28 @@ http://www.angelcode.com/products/bmfont/ (Free, Windows only) ****************************************************************************/ -(function(){ - cc.LabelBMFont.WebGLRenderCmd = function(renderableObject){ - cc.SpriteBatchNode.WebGLRenderCmd.call(this, renderableObject); - this._needDraw = true; +(function () { + cc.LabelBMFont.WebGLRenderCmd = function (renderableObject) { + this._rootCtor(renderableObject); }; - var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.SpriteBatchNode.WebGLRenderCmd.prototype); + var proto = cc.LabelBMFont.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype); proto.constructor = cc.LabelBMFont.WebGLRenderCmd; - proto._updateCharTexture = function(fontChar, rect, key){ + proto.setTexture = function (texture) { + this._node.setOpacityModifyRGB(this._node._texture.hasPremultipliedAlpha()); + }; + + proto._updateCharTexture = function(fontChar, rect, key, isRotated){ // updating previous sprite - fontChar.setTextureRect(rect, false); + fontChar.setTextureRect(rect, isRotated); // restore to default in case they were modified fontChar.visible = true; }; - - proto._updateFntFileTexture = function(){}; - - proto._changeTextureColor = function(){}; - - proto._updateChildrenDisplayedOpacity = function(locChild){ - locChild.updateDisplayedOpacity(this._displayedOpacity); - }; - - proto._updateChildrenDisplayedColor = function(locChild){ - locChild.updateDisplayedColor(this._displayedColor); - }; - - proto._initBatchTexture = function(){ - var node = this._node; - var locTexture = node.textureAtlas.texture; - node._opacityModifyRGB = locTexture.hasPremultipliedAlpha(); - - var reusedChar = node._reusedChar = new cc.Sprite(); - reusedChar.initWithTexture(locTexture, cc.rect(0, 0, 0, 0), false); - reusedChar.batchNode = node; + proto._changeTextureColor = function () { }; - proto.rendering = function(ctx){ - cc.SpriteBatchNode.WebGLRenderCmd.prototype.rendering.call(this, ctx); - - var node = this._node; - //LabelBMFont - Debug draw - if (cc.LABELBMFONT_DEBUG_DRAW) { - var size = node.getContentSize(); - var pos = cc.p(0 | ( -this._anchorPointInPoints.x), 0 | ( -this._anchorPointInPoints.y)); - var vertices = [cc.p(pos.x, pos.y), cc.p(pos.x + size.width, pos.y), cc.p(pos.x + size.width, pos.y + size.height), cc.p(pos.x, pos.y + size.height)]; - cc._drawingUtil.setDrawColor(0, 255, 0, 255); - cc._drawingUtil.drawPoly(vertices, 4, true); - } + proto._updateCharColorAndOpacity = function () { }; - - proto._updateCharColorAndOpacity = function(){}; -})(); \ No newline at end of file +})(); diff --git a/cocos2d/menus/CCMenu.js b/cocos2d/menus/CCMenu.js index 53c34e6a1f..e3edd737ee 100644 --- a/cocos2d/menus/CCMenu.js +++ b/cocos2d/menus/CCMenu.js @@ -51,7 +51,7 @@ cc.DEFAULT_PADDING = 5; * - But the only accepted children are MenuItem objects * @class * @extends cc.Layer - * @param {...cc.MenuItem|null} menuItems} + * @param {...cc.MenuItem|null} menuItems * @example * var layer = new cc.Menu(menuitem1, menuitem2, menuitem3); */ @@ -84,19 +84,14 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ onTouchCancelled: this._onTouchCancelled }); - if ((arguments.length > 0) && (arguments[arguments.length - 1] == null)) - cc.log("parameters should not be ending with null in Javascript"); - var argc = arguments.length, items; - if (argc === 0) { + if (menuItems instanceof Array) { + items = menuItems; + } + else if (argc === 0) { items = []; - } else if (argc === 1) { - if (menuItems instanceof Array) { - items = menuItems; - } - else items = [menuItems]; } - else if (argc > 1) { + else if (argc > 0) { items = []; for (var i = 0; i < argc; i++) { if (arguments[i]) @@ -194,10 +189,21 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ */ addChild: function (child, zOrder, tag) { if (!(child instanceof cc.MenuItem)) - throw "cc.Menu.addChild() : Menu only supports MenuItem objects as children"; + throw new Error("cc.Menu.addChild() : Menu only supports MenuItem objects as children"); cc.Layer.prototype.addChild.call(this, child, zOrder, tag); }, + updateAlign: function () { + switch (this._align) { + case 'vertically': + this.alignItemsVertically(); + break; + case 'horizontally': + this.alignItemsHorizontally(); + break; + } + }, + /** * align items vertically with default padding */ @@ -210,6 +216,7 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ * @param {Number} padding */ alignItemsVerticallyWithPadding: function (padding) { + this._align = 'vertically'; var height = -padding, locChildren = this._children, len, i, locScaleY, locHeight, locChild; if (locChildren && locChildren.length > 0) { for (i = 0, len = locChildren.length; i < len; i++) @@ -239,6 +246,7 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ * @param {Number} padding */ alignItemsHorizontallyWithPadding: function (padding) { + this._align = 'horizontally'; var width = -padding, locChildren = this._children, i, len, locScaleX, locWidth, locChild; if (locChildren && locChildren.length > 0) { for (i = 0, len = locChildren.length; i < len; i++) @@ -268,8 +276,8 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ if ((arguments.length > 0) && (arguments[arguments.length - 1] == null)) cc.log("parameters should not be ending with null in Javascript"); - var rows = []; - for (var i = 0; i < arguments.length; i++) { + var i, rows = []; + for (i = 0; i < arguments.length; i++) { rows.push(arguments[i]); } var height = -5; @@ -350,7 +358,7 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ alignItemsInRows: function (/*Multiple arguments*/) { if ((arguments.length > 0) && (arguments[arguments.length - 1] == null)) cc.log("parameters should not be ending with null in Javascript"); - var columns = [], i; + var i, columns = []; for (i = 0; i < arguments.length; i++) { columns.push(arguments[i]); } @@ -492,7 +500,7 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ cc.log("cc.Menu.onTouchCancelled(): invalid state"); return; } - if (this._selectedItem) { + if (target._selectedItem) { target._selectedItem.unselected(); target._selectedItem.setNodeDirty(); } @@ -545,7 +553,7 @@ cc.Menu = cc.Layer.extend(/** @lends cc.Menu# */{ }, /** * only use for jsbinding - * @returns {boolean} + * @returns {boolean} */ isOpacityModifyRGB: function () { return false; diff --git a/cocos2d/menus/CCMenuItem.js b/cocos2d/menus/CCMenuItem.js index ef9d3549a8..de25beecd9 100644 --- a/cocos2d/menus/CCMenuItem.js +++ b/cocos2d/menus/CCMenuItem.js @@ -241,6 +241,16 @@ cc.MenuItemLabel = cc.MenuItem.extend(/** @lends cc.MenuItemLabel# */{ this._disabledColor = cc.color(126, 126, 126); this.setLabel(label); + if (label.textureLoaded && !label.textureLoaded()) { + label.addEventListener("load", function (sender) { + this.width = sender.width; + this.height = sender.height; + if (this.parent instanceof cc.Menu) { + this.parent.updateAlign(); + } + }, this); + } + this.setCascadeColorEnabled(true); this.setCascadeOpacityEnabled(true); } @@ -338,7 +348,7 @@ cc.MenuItemLabel = cc.MenuItem.extend(/** @lends cc.MenuItemLabel# */{ }, /** * return the string of cc.MenuItemLabel - * @returns {*|string|_p.string|ret.string|q.string|String} + * @returns {String} */ getString: function () { return this._label.string; @@ -461,7 +471,7 @@ cc.MenuItemAtlasFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemAtlasFont# */ initWithString: function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) { if (!value || value.length === 0) - throw "cc.MenuItemAtlasFont.initWithString(): value should be non-null and its length should be greater than 0"; + throw new Error("cc.MenuItemAtlasFont.initWithString(): value should be non-null and its length should be greater than 0"); var label = new cc.LabelAtlas(); label.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap); @@ -535,7 +545,7 @@ cc.MenuItemFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemFont# */{ */ initWithString: function (value, callback, target) { if (!value || value.length === 0) - throw "Value should be non-null and its length should be greater than 0"; + throw new Error("Value should be non-null and its length should be greater than 0"); this._fontName = cc._globalFontName; this._fontSize = cc._globalFontSize; @@ -691,10 +701,11 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ this._normalImage = null; this._selectedImage = null; this._disabledImage = null; + this._loader = new cc.Sprite.LoadManager(); - if (selectedSprite !== undefined) { + if (normalSprite !== undefined) { //normalSprite = normalSprite; - //selectedSprite = selectedSprite; + selectedSprite = selectedSprite || null; var disabledImage, target, callback; //when you send 4 arguments, five is undefined if (five !== undefined) { @@ -711,7 +722,17 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ } else if (three === undefined) { disabledImage = null; } + + this._loader.clear(); + if (normalSprite.textureLoaded && !normalSprite.textureLoaded()) { + this._loader.once(normalSprite, function () { + this.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target); + }, this); + return false; + } + this.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target); + return true; } }, @@ -741,6 +762,9 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ } this._normalImage = normalImage; + if(!this._normalImage) + return; + this.width = this._normalImage.width; this.height = this._normalImage.height; this._updateImagesVisibility(); @@ -749,6 +773,9 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ normalImage.addEventListener("load", function (sender) { this.width = sender.width; this.height = sender.height; + if (this.parent instanceof cc.Menu) { + this.parent.updateAlign(); + } }, this); } }, @@ -822,6 +849,13 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ * @return {Boolean} */ initWithNormalSprite: function (normalSprite, selectedSprite, disabledSprite, callback, target) { + this._loader.clear(); + if (normalSprite.textureLoaded && !normalSprite.textureLoaded()) { + this._loader.once(normalSprite, function () { + this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target); + }, this); + return false; + } this.initWithCallback(callback, target); this.setNormalImage(normalSprite); this.setSelectedImage(selectedSprite); @@ -830,15 +864,6 @@ cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ if (locNormalImage) { this.width = locNormalImage.width; this.height = locNormalImage.height; - - if (locNormalImage.textureLoaded && !locNormalImage.textureLoaded()) { - locNormalImage.addEventListener("load", function (sender) { - this.width = sender.width; - this.height = sender.height; - this.setCascadeColorEnabled(true); - this.setCascadeOpacityEnabled(true); - }, this); - } } this.setCascadeColorEnabled(true); this.setCascadeOpacityEnabled(true); @@ -978,13 +1003,14 @@ cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{ callback = null, target = null; - if (normalImage === undefined) { + if (normalImage === undefined || normalImage === null) { cc.MenuItemSprite.prototype.ctor.call(this); } else { normalSprite = new cc.Sprite(normalImage); selectedImage && (selectedSprite = new cc.Sprite(selectedImage)); + if (four === undefined) { callback = three; } @@ -1208,9 +1234,9 @@ cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{ /** * initializes a cc.MenuItemToggle with items - * @param {cc.MenuItem} args[0...last-2] the rest in the array are cc.MenuItems - * @param {function|String} args[last-1] the second item in the args array is the callback - * @param {cc.Node} args[last] the first item in the args array is a target + * @param {...cc.MenuItem} array the rest in the array are cc.MenuItems + * @param {function|String} secondTolast the second item in the args array is the callback + * @param {cc.Node} last the first item in the args array is a target * @return {Boolean} */ initWithItems: function (args) { @@ -1335,7 +1361,6 @@ cc.defineGetterSetter(_p, "selectedIndex", _p.getSelectedIndex, _p.setSelectedIn * The inner items can be any MenuItem * @deprecated since v3.0 please use new cc.MenuItemToggle(params) instead * @return {cc.MenuItemToggle} - * @example */ cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) { if ((arguments.length > 0) && (arguments[arguments.length - 1] == null)) diff --git a/cocos2d/motion-streak/CCMotionStreak.js b/cocos2d/motion-streak/CCMotionStreak.js index 85b43531dd..158393454a 100644 --- a/cocos2d/motion-streak/CCMotionStreak.js +++ b/cocos2d/motion-streak/CCMotionStreak.js @@ -44,33 +44,33 @@ * new cc.MotionStreak(2, 3, 32, cc.color.GREEN, s_streak); */ cc.MotionStreak = cc.Node.extend(/** @lends cc.MotionStreak# */{ - texture:null, - fastMode:false, - startingPositionInitialized:false, + texture: null, + fastMode: false, + startingPositionInitialized: false, - _blendFunc:null, + _blendFunc: null, - _stroke:0, - _fadeDelta:0, - _minSeg:0, + _stroke: 0, + _fadeDelta: 0, + _minSeg: 0, - _maxPoints:0, - _nuPoints:0, - _previousNuPoints:0, + _maxPoints: 0, + _nuPoints: 0, + _previousNuPoints: 0, /* Pointers */ - _pointVertexes:null, - _pointState:null, + _pointVertexes: null, + _pointState: null, // webgl - _vertices:null, - _colorPointer:null, - _texCoords:null, + _vertices: null, + _colorPointer: null, + _texCoords: null, - _verticesBuffer:null, - _colorPointerBuffer:null, - _texCoordsBuffer:null, - _className:"MotionStreak", + _verticesBuffer: null, + _colorPointerBuffer: null, + _texCoordsBuffer: null, + _className: "MotionStreak", /** * creates and initializes a motion streak with fade in seconds, minimum segments, stroke's width, color, texture filename or texture
* Particle System base class.
* Attributes of a Particle System:
- * - emmision rate of the particles
+ * - emission rate of the particles
* - Gravity Mode (Mode A):
* - gravity
* - direction
@@ -204,14 +204,14 @@ cc.Particle.TemporaryPoints = [
* @property {Number} positionType - Particles movement type: cc.ParticleSystem.TYPE_FREE | cc.ParticleSystem.TYPE_GROUPED.
* @property {Number} totalParticles - Maximum particles of the system.
* @property {Boolean} autoRemoveOnFinish - Indicate whether the node will be auto-removed when it has no particles left.
- * @property {cc.Texture2D} texture - Texture of Particle System.
+ * @property {cc.Texture2D|HTMLImageElement|HTMLCanvasElement} texture - Texture of Particle System.
*
* @example
* emitter.radialAccel = 15;
* emitter.startSpin = 0;
*/
cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
- _className:"ParticleSystem",
+ _className: "ParticleSystem",
//***********variables*************
_plistFile: "",
//! time elapsed since the start of the system (in seconds)
@@ -285,12 +285,12 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
* Constructor of cc.ParticleSystem
* @param {String|Number} plistFile
*/
- ctor:function (plistFile) {
+ ctor: function (plistFile) {
cc.Node.prototype.ctor.call(this);
this.emitterMode = cc.ParticleSystem.MODE_GRAVITY;
this.modeA = new cc.ParticleSystem.ModeA();
this.modeB = new cc.ParticleSystem.ModeB();
- this._blendFunc = {src:cc.BLEND_SRC, dst:cc.BLEND_DST};
+ this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
this._particles = [];
this._sourcePosition = cc.p(0, 0);
@@ -348,8 +348,8 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
}
},
- _createRenderCmd: function(){
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ _createRenderCmd: function () {
+ if (cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new cc.ParticleSystem.CanvasRenderCmd(this);
else
return new cc.ParticleSystem.WebGLRenderCmd(this);
@@ -360,8 +360,8 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
* It's very expensive to change color on Canvas mode, so if set it to true, particle system will ignore the changing color operation.
* @param {boolean} ignore
*/
- ignoreColor: function(ignore){
- this._dontTint = ignore;
+ ignoreColor: function (ignore) {
+ this._dontTint = ignore;
},
/**
@@ -370,7 +370,7 @@ cc.ParticleSystem = cc.Node.extend(/** @lends cc.ParticleSystem# */{
*
* Update does the work of mapping the texture onto the triangles for the bar
@@ -193,7 +263,7 @@
*
Code for "auto" update
- // Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
- // They can be OR'ed. Valid when "autoDraw is YES.
Code for "auto" update
+ // Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.
+ // They can be OR'ed. Valid when "autoDraw is YES.
- * Will enable the vertex attribs that are passed as flags.
- * Possible flags:
- * cc.VERTEX_ATTRIB_FLAG_POSITION
- * cc.VERTEX_ATTRIB_FLAG_COLOR
- * cc.VERTEX_ATTRIB_FLAG_TEX_COORDS
- *
- * These flags can be ORed. The flags that are not present, will be disabled.
- *
CCDrawNode
* Node that draws dots, segments and polygons.
- * Faster than the "drawing primitives" since they it draws everything in one single batch.
The cc.DrawNodeCanvas's constructor.
- * This function will automatically be invoked when you create a node using new construction: "var node = new cc.DrawNodeCanvas()".
- * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
The cc.DrawNodeCanvas's constructor.
+ * This function will automatically be invoked when you create a node using new construction: "var node = new cc.DrawNodeCanvas()".
+ * Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
The cc.BinaryStreamReader's constructor.
@@ -302,7 +302,7 @@ cc.BinaryStreamReader = cc.Class.extend({
* Override it to extend its behavior, remember to call "this._super()" in the extended "ctor" function.
Sets the tile gid (gid = tile global id) at a given tile coordinate.
* The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor . Tileset Mgr +1.
@@ -427,8 +478,9 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
* @param {Number} [flags]
*/
setTileGID: function(gid, posOrX, flagsOrY, flags) {
- if(!posOrX)
- throw "cc.TMXLayer.setTileGID(): pos should be non-null";
+ if (posOrX === undefined) {
+ throw new Error("cc.TMXLayer.setTileGID(): pos should be non-null");
+ }
var pos;
if (flags !== undefined) {
pos = cc.p(posOrX, flagsOrY);
@@ -436,19 +488,19 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
pos = posOrX;
flags = flagsOrY;
}
- if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0)
- throw "cc.TMXLayer.setTileGID(): invalid position";
- if(!this.tiles || !this._atlasIndexArray){
+ if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) {
+ throw new Error("cc.TMXLayer.setTileGID(): invalid position");
+ }
+ if (!this.tiles) {
cc.log("cc.TMXLayer.setTileGID(): TMXLayer: the tiles map has been released");
return;
}
- if(gid !== 0 && gid < this.tileset.firstGid){
+ if (gid !== 0 && gid < this.tileset.firstGid) {
cc.log( "cc.TMXLayer.setTileGID(): invalid gid:" + gid);
return;
}
flags = flags || 0;
- this._setNodeDirtyForCache();
var currentFlags = this.getTileFlagsAt(pos);
var currentGID = this.getTileGIDAt(pos);
@@ -458,75 +510,101 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
if (gid === 0)
this.removeTileAt(pos);
else if (currentGID === 0) // empty tile. create a new one
- this._insertTileForGID(gidAndFlags, pos);
+ this._updateTileForGID(gidAndFlags, pos);
else { // modifying an existing tile with a non-empty tile
var z = pos.x + pos.y * this._layerSize.width;
var sprite = this.getChildByTag(z);
if (sprite) {
- var rect = this.tileset.rectForGID(gid);
+ var rect = this._texGrids[gid];
+ var tex = this._textures[rect.texId];
rect = cc.rectPixelsToPoints(rect);
-
+ sprite.setTexture(tex);
sprite.setTextureRect(rect, false);
if (flags != null)
this._setupTileSprite(sprite, pos, gidAndFlags);
this.tiles[z] = gidAndFlags;
- } else
+ } else {
this._updateTileForGID(gidAndFlags, pos);
+ }
}
}
},
+ addChild: function (child, localZOrder, tag) {
+ cc.Node.prototype.addChild.call(this, child, localZOrder, tag);
+ if (tag !== undefined) {
+ this._spriteTiles[tag] = child;
+ child._vertexZ = this._vertexZ + cc.renderer.assignedZStep * tag / this.tiles.length;
+ // child._renderCmd._needDraw = false;
+ }
+ },
+
+ removeChild: function (child, cleanup) {
+ if (this._spriteTiles[child.tag]) {
+ this._spriteTiles[child.tag] = null;
+ // child._renderCmd._needDraw = true;
+ }
+ cc.Node.prototype.removeChild.call(this, child, cleanup);
+ },
+
/**
- * Removes a tile at given tile coordinate
- * @param {cc.Point|Number} pos position or x
+ * lipped tiles can be changed dynamically
+ * @param {cc.Point|Number} pos or x
* @param {Number} [y]
+ * @return {Number}
*/
- removeTileAt:function (pos, y) {
+ getTileFlagsAt:function (pos, y) {
if(!pos)
- throw "cc.TMXLayer.removeTileAt(): pos should be non-null";
+ throw new Error("cc.TMXLayer.getTileFlagsAt(): pos should be non-null");
if(y !== undefined)
pos = cc.p(pos, y);
if(pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0)
- throw "cc.TMXLayer.removeTileAt(): invalid position";
- if(!this.tiles || !this._atlasIndexArray){
+ throw new Error("cc.TMXLayer.getTileFlagsAt(): invalid position");
+ if(!this.tiles){
+ cc.log("cc.TMXLayer.getTileFlagsAt(): TMXLayer: the tiles map has been released");
+ return null;
+ }
+
+ var idx = 0 | (pos.x + pos.y * this._layerSize.width);
+ // Bits on the far end of the 32-bit global tile ID are used for tile flags
+ var tile = this.tiles[idx];
+
+ return (tile & cc.TMX_TILE_FLIPPED_ALL) >>> 0;
+ },
+ // XXX: deprecated
+ // tileFlagAt:getTileFlagsAt,
+
+ /**
+ * Removes a tile at given tile coordinate
+ * @param {cc.Point|Number} pos position or x
+ * @param {Number} [y]
+ */
+ removeTileAt:function (pos, y) {
+ if (!pos) {
+ throw new Error("cc.TMXLayer.removeTileAt(): pos should be non-null");
+ }
+ if (y !== undefined) {
+ pos = cc.p(pos, y);
+ }
+ if (pos.x >= this._layerSize.width || pos.y >= this._layerSize.height || pos.x < 0 || pos.y < 0) {
+ throw new Error("cc.TMXLayer.removeTileAt(): invalid position");
+ }
+ if (!this.tiles) {
cc.log("cc.TMXLayer.removeTileAt(): TMXLayer: the tiles map has been released");
return;
}
var gid = this.getTileGIDAt(pos);
if (gid !== 0) {
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
- this._setNodeDirtyForCache();
var z = 0 | (pos.x + pos.y * this._layerSize.width);
- var atlasIndex = this._atlasIndexForExistantZ(z);
// remove tile from GID map
this.tiles[z] = 0;
- // remove tile from atlas position array
- this._atlasIndexArray.splice(atlasIndex, 1);
-
// remove it from sprites and/or texture atlas
- var sprite = this.getChildByTag(z);
-
- if (sprite)
- cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, true); //this.removeChild(sprite, true);
- else {
- if(cc._renderType === cc._RENDER_TYPE_WEBGL)
- this.textureAtlas.removeQuadAtIndex(atlasIndex);
-
- // update possible children
- if (this._children) {
- var locChildren = this._children;
- for (var i = 0, len = locChildren.length; i < len; i++) {
- var child = locChildren[i];
- if (child) {
- var ai = child.atlasIndex;
- if (ai >= atlasIndex)
- child.atlasIndex = ai - 1;
- }
- }
- }
+ var sprite = this._spriteTiles[z];
+ if (sprite) {
+ this.removeChild(sprite, true);
}
}
},
@@ -557,100 +635,6 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
// XXX: Deprecated. For backward compatibility only
// positionAt:getPositionAt,
- /**
- * Return the value for the specific property name
- * @param {String} propertyName
- * @return {*}
- */
- getProperty:function (propertyName) {
- return this.properties[propertyName];
- },
-
- /**
- * Creates the tiles
- */
- setupTiles:function () {
- // Optimization: quick hack that sets the image size on the tileset
- this._renderCmd.initImageSize();
-
- // Parse cocos2d properties
- this._parseInternalProperties();
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
- this._setNodeDirtyForCache();
-
- var locLayerHeight = this._layerSize.height, locLayerWidth = this._layerSize.width;
- for (var y = 0; y < locLayerHeight; y++) {
- for (var x = 0; x < locLayerWidth; x++) {
- var pos = x + locLayerWidth * y;
- var gid = this.tiles[pos];
-
- // XXX: gid == 0 -. empty tile
- if (gid !== 0) {
- this._appendTileForGID(gid, cc.p(x, y));
- // Optimization: update min and max GID rendered by the layer
- this._minGID = Math.min(gid, this._minGID);
- this._maxGID = Math.max(gid, this._maxGID);
- }
- }
- }
-
- if (!((this._maxGID >= this.tileset.firstGid) && (this._minGID >= this.tileset.firstGid))) {
- cc.log("cocos2d:TMX: Only 1 tileset per layer is supported");
- }
- },
-
- /**
- * cc.TMXLayer doesn't support adding a cc.Sprite manually.
- * @warning addChild(child); is not supported on cc.TMXLayer. Instead of setTileGID.
- * @param {cc.Node} child
- * @param {number} zOrder
- * @param {number} tag
- */
- addChild:function (child, zOrder, tag) {
- cc.log("addChild: is not supported on cc.TMXLayer. Instead use setTileGID or tileAt.");
- },
-
- /**
- * Remove child
- * @param {cc.Sprite} sprite
- * @param {Boolean} cleanup
- */
- removeChild:function (sprite, cleanup) {
- // allows removing nil objects
- if (!sprite)
- return;
-
- if(this._children.indexOf(sprite) === -1){
- cc.log("cc.TMXLayer.removeChild(): Tile does not belong to TMXLayer");
- return;
- }
-
- if (cc._renderType === cc._RENDER_TYPE_CANVAS)
- this._setNodeDirtyForCache();
- var atlasIndex = sprite.atlasIndex;
- var zz = this._atlasIndexArray[atlasIndex];
- this.tiles[zz] = 0;
- this._atlasIndexArray.splice(atlasIndex, 1);
- cc.SpriteBatchNode.prototype.removeChild.call(this, sprite, cleanup);
- cc.renderer.childrenOrderDirty = true;
- },
-
- /**
- * Gets the layer name
- * @return {String}
- */
- getLayerName:function () {
- return this.layerName;
- },
-
- /**
- * Set the layer name
- * @param {String} layerName
- */
- setLayerName:function (layerName) {
- this.layerName = layerName;
- },
-
_positionForIsoAt:function (pos) {
return cc.p(this._mapTileSize.width / 2 * ( this._layerSize.width + pos.x - pos.y - 1),
this._mapTileSize.height / 2 * (( this._layerSize.height * 2 - pos.x - pos.y) - 2));
@@ -685,76 +669,15 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
return ret;
},
- _appendTileForGID:function (gid, pos) {
- var rect = this.tileset.rectForGID(gid);
- rect = cc.rectPixelsToPoints(rect);
-
- var z = 0 | (pos.x + pos.y * this._layerSize.width);
- var tile = this._renderCmd._reusedTileWithRect(rect);
- this._setupTileSprite(tile, pos, gid);
-
- // optimization:
- // The difference between appendTileForGID and insertTileforGID is that append is faster, since
- // it appends the tile at the end of the texture atlas
- var indexForZ = this._atlasIndexArray.length;
-
- // don't add it using the "standard" way.
- this.insertQuadFromSprite(tile, indexForZ);
-
- // append should be after addQuadFromSprite since it modifies the quantity values
- this._atlasIndexArray.splice(indexForZ, 0, z);
- return tile;
- },
-
- _insertTileForGID:function (gid, pos) {
- var rect = this.tileset.rectForGID(gid);
- rect = cc.rectPixelsToPoints(rect);
-
- var z = 0 | (pos.x + pos.y * this._layerSize.width);
- var tile = this._renderCmd._reusedTileWithRect(rect);
- this._setupTileSprite(tile, pos, gid);
-
- // get atlas index
- var indexForZ = this._atlasIndexForNewZ(z);
-
- // Optimization: add the quad without adding a child
- this.insertQuadFromSprite(tile, indexForZ);
-
- // insert it into the local atlasindex array
- this._atlasIndexArray.splice(indexForZ, 0, z);
- // update possible children
- if (this._children) {
- var locChildren = this._children;
- for (var i = 0, len = locChildren.length; i < len; i++) {
- var child = locChildren[i];
- if (child) {
- var ai = child.atlasIndex;
- if (ai >= indexForZ)
- child.atlasIndex = ai + 1;
- }
- }
- }
- this.tiles[z] = gid;
- return tile;
- },
-
_updateTileForGID:function (gid, pos) {
- var rect = this.tileset.rectForGID(gid);
- var locScaleFactor = this._contentScaleFactor;
- rect = cc.rect(rect.x / locScaleFactor, rect.y / locScaleFactor,
- rect.width / locScaleFactor, rect.height / locScaleFactor);
- var z = pos.x + pos.y * this._layerSize.width;
-
- var tile = this._renderCmd._reusedTileWithRect(rect);
- this._setupTileSprite(tile, pos, gid);
-
- // get atlas index
- tile.atlasIndex = this._atlasIndexForExistantZ(z);
- tile.dirty = true;
- tile.updateTransform();
- this.tiles[z] = gid;
+ if (!this._texGrids[gid]) {
+ return;
+ }
- return tile;
+ var idx = 0 | (pos.x + pos.y * this._layerSize.width);
+ if (idx < this.tiles.length) {
+ this.tiles[idx] = gid;
+ }
},
//The layer recognizes some special properties, like cc_vertez
@@ -769,12 +692,11 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
if (alphaFuncVal)
alphaFuncValue = parseFloat(alphaFuncVal);
- if (cc._renderType === cc._RENDER_TYPE_WEBGL) { //todo: need move to WebGL render cmd
- this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
- var alphaValueLocation = cc._renderContext.getUniformLocation(this.shaderProgram.getProgram(), cc.UNIFORM_ALPHA_TEST_VALUE_S);
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) { //todo: need move to WebGL render cmd
+ this.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
// NOTE: alpha test shader is hard-coded to use the equivalent of a glAlphaFunc(GL_GREATER) comparison
this.shaderProgram.use();
- this.shaderProgram.setUniformLocationWith1f(alphaValueLocation, alphaFuncValue);
+ this.shaderProgram.setUniformLocationWith1f(cc.UNIFORM_ALPHA_TEST_VALUE_S, alphaFuncValue);
}
} else
this._vertexZvalue = parseInt(vertexz, 10);
@@ -783,65 +705,59 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
_setupTileSprite:function (sprite, pos, gid) {
var z = pos.x + pos.y * this._layerSize.width;
- sprite.setPosition(this.getPositionAt(pos));
- if (cc._renderType === cc._RENDER_TYPE_WEBGL)
- sprite.vertexZ = this._vertexZForPos(pos);
- else
- sprite.tag = z;
-
- sprite.anchorX = 0;
- sprite.anchorY = 0;
- sprite.opacity = this._opacity;
- if (cc._renderType === cc._RENDER_TYPE_WEBGL) {
- sprite.rotation = 0.0;
- }
-
+ var posInPixel = this.getPositionAt(pos);
+ sprite.setPosition(posInPixel);
+ sprite.setVertexZ(this._vertexZForPos(pos));
+ sprite.setAnchorPoint(0, 0);
+ sprite.setOpacity(this._opacity);
sprite.setFlippedX(false);
sprite.setFlippedY(false);
+ sprite.setRotation(0.0);
// Rotation in tiled is achieved using 3 flipped states, flipping across the horizontal, vertical, and diagonal axes of the tiles.
if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) {
// put the anchor in the middle for ease of rotation.
- sprite.anchorX = 0.5;
- sprite.anchorY = 0.5;
- sprite.x = this.getPositionAt(pos).x + sprite.width / 2;
- sprite.y = this.getPositionAt(pos).y + sprite.height / 2;
+ sprite.setAnchorPoint(0.5, 0.5);
+ sprite.setPosition(posInPixel.x + sprite.width/2, posInPixel.y + sprite.height/2);
var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0;
// handle the 4 diagonally flipped states.
if (flag === cc.TMX_TILE_HORIZONTAL_FLAG)
- sprite.rotation = 90;
+ sprite.setRotation(90);
else if (flag === cc.TMX_TILE_VERTICAL_FLAG)
- sprite.rotation = 270;
+ sprite.setRotation(270);
else if (flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
- sprite.rotation = 90;
- sprite.setFlippedX(true);
+ sprite.setRotation(90);
+ sprite.setFlippedX(true);
} else {
- sprite.rotation = 270;
- sprite.setFlippedX(true);
+ sprite.setRotation(270);
+ sprite.setFlippedX(true);
}
} else {
if ((gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
sprite.setFlippedX(true);
}
-
if ((gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0) {
sprite.setFlippedY(true);
}
}
},
- _vertexZForPos:function (pos) {
+ _vertexZForPos:function (x, y) {
+ if (y === undefined) {
+ y = x.y;
+ x = x.x;
+ }
var ret = 0;
var maxVal = 0;
if (this._useAutomaticVertexZ) {
switch (this.layerOrientation) {
case cc.TMX_ORIENTATION_ISO:
maxVal = this._layerSize.width + this._layerSize.height;
- ret = -(maxVal - (pos.x + pos.y));
+ ret = -(maxVal - (x + y));
break;
case cc.TMX_ORIENTATION_ORTHO:
- ret = -(this._layerSize.height - pos.y);
+ ret = -(this._layerSize.height - y);
break;
case cc.TMX_ORIENTATION_HEX:
cc.log("TMX Hexa zOrder not supported");
@@ -850,42 +766,15 @@ cc.TMXLayer = cc.SpriteBatchNode.extend(/** @lends cc.TMXLayer# */{
cc.log("TMX invalid value");
break;
}
- } else
+ } else {
ret = this._vertexZvalue;
- return ret;
- },
-
- _atlasIndexForExistantZ:function (z) {
- var item;
- if (this._atlasIndexArray) {
- var locAtlasIndexArray = this._atlasIndexArray;
- for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) {
- item = locAtlasIndexArray[i];
- if (item === z)
- break;
- }
}
- if(!cc.isNumber(item))
- cc.log("cc.TMXLayer._atlasIndexForExistantZ(): TMX atlas index not found. Shall not happen");
- return i;
- },
-
- _atlasIndexForNewZ:function (z) {
- var locAtlasIndexArray = this._atlasIndexArray;
- for (var i = 0, len = locAtlasIndexArray.length; i < len; i++) {
- var val = locAtlasIndexArray[i];
- if (z < val)
- break;
- }
- return i;
+ return ret;
}
});
var _p = cc.TMXLayer.prototype;
-/** @expose */
-cc.defineGetterSetter(_p, "texture", _p.getTexture, _p.setTexture);
-
// Extended properties
/** @expose */
_p.layerWidth;
diff --git a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js
index 6589bb2643..f354284de2 100644
--- a/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js
+++ b/cocos2d/tilemap/CCTMXLayerCanvasRenderCmd.js
@@ -22,199 +22,238 @@
THE SOFTWARE.
****************************************************************************/
-(function(){
- cc.TMXLayer.CanvasRenderCmd = function(renderable){
- cc.SpriteBatchNode.CanvasRenderCmd.call(this, renderable);
+(function () {
+ cc.TMXLayer.CanvasRenderCmd = function (renderable) {
+ this._rootCtor(renderable);
this._needDraw = true;
- this._realWorldTransform = {a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0};
-
- var locCanvas = cc._canvas;
- var tmpCanvas = cc.newElement('canvas');
- tmpCanvas.width = locCanvas.width;
- tmpCanvas.height = locCanvas.height;
- this._cacheCanvas = tmpCanvas;
- this._cacheContext = new cc.CanvasContextWrapper(this._cacheCanvas.getContext('2d'));
- var tempTexture = new cc.Texture2D();
- tempTexture.initWithElement(tmpCanvas);
- tempTexture.handleLoadedTexture();
- this._cacheTexture = tempTexture;
- // This class uses cache, so its default cachedParent should be himself
- this._cacheDirty = false;
};
- var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.SpriteBatchNode.CanvasRenderCmd.prototype);
+ var proto = cc.TMXLayer.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
proto.constructor = cc.TMXLayer.CanvasRenderCmd;
- //set the cache dirty flag for canvas
- proto._setNodeDirtyForCache = function () {
- this._cacheDirty = true;
- };
+ proto.visit = function (parentCmd) {
+ var node = this._node, renderer = cc.renderer;
- proto._renderingChildToCache = function () {
- if (this._cacheDirty) {
- var wrapper = this._cacheContext,
- context = wrapper.getContext(), locCanvas = this._cacheCanvas;
-
- //wrapper.save();
- context.setTransform(1, 0, 0, 1, 0, 0);
- context.clearRect(0, 0, locCanvas.width, locCanvas.height);
- //reset the cache context
-
- var locChildren = this._node._children;
- for (var i = 0, len = locChildren.length; i < len; i++) {
- if (locChildren[i]){
- var selCmd = locChildren[i]._renderCmd;
- if(selCmd){
- selCmd.rendering(wrapper, 1, 1);
- selCmd._cacheDirty = false;
- }
+ parentCmd = parentCmd || this.getParentRenderCmd();
+ if (parentCmd) {
+ this._curLevel = parentCmd._curLevel + 1;
+ }
+
+ // quick return if not visible
+ if (!node._visible)
+ return;
+
+ if (isNaN(node._customZ)) {
+ node._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+
+ this._syncStatus(parentCmd);
+
+ // Visit children
+ var children = node._children, child,
+ spTiles = node._spriteTiles,
+ i, 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;
}
}
- //wrapper.restore();
- this._cacheDirty = false;
+ renderer.pushRenderCommand(this);
+ for (; i < len; i++) {
+ child = children[i];
+ if (child._localZOrder === 0 && spTiles[child.tag]) {
+ if (isNaN(child._customZ)) {
+ child._vertexZ = renderer.assignedZ;
+ renderer.assignedZ += renderer.assignedZStep;
+ }
+ child._renderCmd.updateStatus();
+ continue;
+ }
+ child._renderCmd.visit(this);
+ }
+ } else {
+ renderer.pushRenderCommand(this);
}
+ this._dirtyFlag = 0;
};
proto.rendering = function (ctx, scaleX, scaleY) {
- var alpha = this._displayedOpacity / 255;
- if (alpha <= 0)
+ var node = this._node, hasRotation = (node._rotationX || node._rotationY),
+ layerOrientation = node.layerOrientation,
+ tiles = node.tiles,
+ alpha = node._opacity / 255;
+
+ if (!tiles || alpha <= 0) {
return;
+ }
+
+ var maptw = node._mapTileSize.width,
+ mapth = node._mapTileSize.height,
+ tilew = node.tileset._tileSize.width / cc.director._contentScaleFactor,
+ tileh = node.tileset._tileSize.height / cc.director._contentScaleFactor,
+ extw = tilew - maptw,
+ exth = tileh - mapth,
+ winw = cc.winSize.width,
+ winh = cc.winSize.height,
+ rows = node._layerSize.height,
+ cols = node._layerSize.width,
+ grids = node._texGrids,
+ spTiles = node._spriteTiles,
+ wt = this._worldTransform,
+ ox = -node._contentSize.width * node._anchorPoint.x,
+ oy = -node._contentSize.height * node._anchorPoint.y,
+ a = wt.a, b = wt.b, c = wt.c, d = wt.d,
+ mapx = ox * a + oy * c + wt.tx,
+ mapy = ox * b + oy * d + wt.ty;
- var node = this._node;
- this._renderingChildToCache();
var wrapper = ctx || cc._renderContext, context = wrapper.getContext();
- wrapper.setGlobalAlpha(alpha);
- var locCacheCanvas = this._cacheCanvas;
- //direct draw image by canvas drawImage
- if (locCacheCanvas && locCacheCanvas.width !== 0 && locCacheCanvas.height !== 0) {
- wrapper.setTransform(this._realWorldTransform, scaleX, scaleY);
- var locCanvasHeight = locCacheCanvas.height * scaleY;
- if (node.layerOrientation === cc.TMX_ORIENTATION_HEX) {
- var halfTileSize = node._mapTileSize.height * 0.5 * scaleY;
- context.drawImage(locCacheCanvas, 0, 0, locCacheCanvas.width, locCacheCanvas.height,
- 0, -locCanvasHeight + halfTileSize, locCacheCanvas.width * scaleX, locCanvasHeight);
- } else {
- context.drawImage(locCacheCanvas, 0, 0, locCacheCanvas.width, locCacheCanvas.height,
- 0, -locCanvasHeight, locCacheCanvas.width * scaleX, locCanvasHeight);
- }
+ // Culling
+ var startCol = 0, startRow = 0,
+ maxCol = cols, maxRow = rows;
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ORTHO) {
+ startCol = Math.floor(-(mapx - extw * a) / (maptw * a));
+ startRow = Math.floor((mapy - exth * d + mapth * rows * d - winh) / (mapth * d));
+ maxCol = Math.ceil((winw - mapx + extw * a) / (maptw * a));
+ maxRow = rows - Math.floor(-(mapy + exth * d) / (mapth * d));
+ // Adjustment
+ if (startCol < 0) startCol = 0;
+ if (startRow < 0) startRow = 0;
+ if (maxCol > cols) maxCol = cols;
+ if (maxRow > rows) maxRow = rows;
}
- cc.g_NumberOfDraws++;
- };
- proto._updateCacheContext = function(size, height){
- var node = this._node,
- locContentSize = node._contentSize,
- locCanvas = this._cacheCanvas,
- scaleFactor = cc.contentScaleFactor();
- locCanvas.width = 0 | (locContentSize.width * 1.5 * scaleFactor);
- locCanvas.height = 0 | (locContentSize.height * 1.5 * scaleFactor);
-
- //todo: need change the wrapper's height
- if(node.layerOrientation === cc.TMX_ORIENTATION_HEX)
- this._cacheContext.setOffset(0, -node._mapTileSize.height * 0.5); //translate for hexagonal
- else
- this._cacheContext.setOffset(0, 0);
- var locTexContentSize = this._cacheTexture._contentSize;
- locTexContentSize.width = locCanvas.width;
- locTexContentSize.height = locCanvas.height;
- };
+ var i, row, col, colOffset = startRow * cols, z,
+ gid, grid, tex, cmd,
+ mask = cc.TMX_TILE_FLIPPED_MASK,
+ top, left, bottom, right, dw = tilew, dh = tileh,
+ w = tilew * a, h = tileh * d, gt, gl, gb, gr,
+ flippedX = false, flippedY = false;
- proto.getTexture = function(){
- return this._cacheTexture;
- };
+ // Draw culled sprite tiles
+ z = colOffset + startCol;
+ for (i in spTiles) {
+ if (i < z && spTiles[i]) {
+ cmd = spTiles[i]._renderCmd;
+ if (spTiles[i]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ }
+ }
+ else if (i >= z) {
+ break;
+ }
+ }
- proto.visit = function(parentCmd){
- var node = this._node;
- //TODO: it will implement dynamic compute child cutting automation.
- var i, len, locChildren = node._children;
- // quick return if not visible
- if (!node._visible || !locChildren || locChildren.length === 0)
- return;
+ wrapper.setTransform(wt, scaleX, scaleY);
+ wrapper.setGlobalAlpha(alpha);
- parentCmd = parentCmd || this.getParentRenderCmd();
- if (parentCmd)
- this._curLevel = parentCmd._curLevel + 1;
+ for (row = startRow; row < maxRow; ++row) {
+ for (col = startCol; col < maxCol; ++col) {
+ z = colOffset + col;
+ // Skip sprite tiles
+ if (spTiles[z]) {
+ cmd = spTiles[z]._renderCmd;
+ if (spTiles[z]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ wrapper.setTransform(wt, scaleX, scaleY);
+ wrapper.setGlobalAlpha(alpha);
+ }
+ continue;
+ }
- this._syncStatus(parentCmd);
- if (this._cacheDirty) {
- var wrapper = this._cacheContext, locCanvas = this._cacheCanvas, context = wrapper.getContext(),
- instanceID = node.__instanceId, renderer = cc.renderer;
- //begin cache
- renderer._turnToCacheMode(instanceID);
+ gid = node.tiles[z];
+ grid = grids[(gid & mask) >>> 0];
+ if (!grid) {
+ continue;
+ }
+ tex = node._textures[grid.texId];
+ if (!tex || !tex._htmlElementObj) {
+ continue;
+ }
- node.sortAllChildren();
- for (i = 0, len = locChildren.length; i < len; i++) {
- if (locChildren[i]){
- var selCmd = locChildren[i]._renderCmd;
- if(selCmd){
- selCmd.visit(this);
- selCmd._cacheDirty = false;
+ switch (layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ left = col * maptw;
+ bottom = -(rows - row - 1) * mapth;
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ left = maptw / 2 * ( cols + col - row - 1);
+ bottom = -mapth / 2 * ( rows * 2 - col - row - 2);
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ left = col * maptw * 3 / 4;
+ bottom = -(rows - row - 1) * mapth + ((col % 2 === 1) ? (-mapth / 2) : 0);
+ break;
+ }
+ right = left + tilew;
+ top = bottom - tileh;
+ // TMX_ORIENTATION_ISO trim
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ISO) {
+ gb = -mapy + bottom * d;
+ if (gb < -winh - h) {
+ col += Math.floor((-winh - gb) * 2 / h) - 1;
+ continue;
+ }
+ gr = mapx + right * a;
+ if (gr < -w) {
+ col += Math.floor((-gr) * 2 / w) - 1;
+ continue;
+ }
+ gl = mapx + left * a;
+ gt = -mapy + top * d;
+ if (gl > winw || gt > 0) {
+ col = maxCol;
+ continue;
}
}
- }
- //wrapper.save();
- context.setTransform(1, 0, 0, 1, 0, 0);
- context.clearRect(0, 0, locCanvas.width, locCanvas.height);
- //set the wrapper's offset
-
- //draw to cache canvas
- renderer._renderingToCacheCanvas(wrapper, instanceID);
- //wrapper.restore(); //todo: it can be reserve.
- this._cacheDirty = false
- }
- cc.renderer.pushRenderCommand(this);
- this._dirtyFlag = 0;
- };
+ // Rotation and Flip
+ if (gid > cc.TMX_TILE_DIAGONAL_FLAG) {
+ flippedX = (gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0;
+ flippedY = (gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0;
+ }
- proto.transform = function (parentCmd, recursive) {
- // transform for canvas
- var t = this.getNodeToParentTransform(),
- worldT = this._realWorldTransform; //get the world transform
+ if (flippedX) {
+ left = -right;
+ context.scale(-1, 1);
+ }
+ if (flippedY) {
+ top = -bottom;
+ context.scale(1, -1);
+ }
- 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);
+ context.drawImage(tex._htmlElementObj,
+ grid.x, grid.y, grid.width, grid.height,
+ left, top, dw, dh);
+ // Revert flip
+ if (flippedX) {
+ context.scale(-1, 1);
+ }
+ if (flippedY) {
+ context.scale(1, -1);
+ }
+ cc.g_NumberOfDraws++;
}
+ colOffset += cols;
}
- };
-
- proto.initImageSize = function(){
- var node = this._node;
- node.tileset.imageSize = this._originalTexture.getContentSizeInPixels();
- };
- proto._reusedTileWithRect = function(rect){
- var node = this._node;
- node._reusedTile = new cc.Sprite();
- node._reusedTile.initWithTexture(node._renderCmd._texture, rect, false);
- node._reusedTile.batchNode = node;
- node._reusedTile.parent = node;
- node._reusedTile._renderCmd._cachedParent = node._renderCmd;
- return node._reusedTile;
+ // Draw culled sprite tiles
+ for (i in spTiles) {
+ if (i > z && spTiles[i]) {
+ cmd = spTiles[i]._renderCmd;
+ if (spTiles[i]._localZOrder === 0 && !!cmd.rendering) {
+ cmd.rendering(ctx, scaleX, scaleY);
+ }
+ }
+ }
};
-})();
\ No newline at end of file
+})();
diff --git a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js
index 8c1906f640..d0e90bebc9 100644
--- a/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js
+++ b/cocos2d/tilemap/CCTMXLayerWebGLRenderCmd.js
@@ -22,46 +22,238 @@
THE SOFTWARE.
****************************************************************************/
-(function(){
- cc.TMXLayer.WebGLRenderCmd = function(renderableObject){
- cc.SpriteBatchNode.WebGLRenderCmd.call(this, renderableObject);
+(function () {
+ cc.TMXLayer.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
this._needDraw = true;
+ this._vertices = [
+ {x: 0, y: 0},
+ {x: 0, y: 0},
+ {x: 0, y: 0},
+ {x: 0, y: 0}
+ ];
+ this._color = new Uint32Array(1);
+ this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
+
+ var radian = Math.PI * 90 / 180;
+ this._sin90 = Math.sin(radian);
+ this._cos90 = Math.cos(radian);
+ radian = radian * 3;
+ this._sin270 = Math.sin(radian);
+ this._cos270 = Math.cos(radian);
};
- var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.SpriteBatchNode.WebGLRenderCmd.prototype);
+ var proto = cc.TMXLayer.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
proto.constructor = cc.TMXLayer.WebGLRenderCmd;
- proto._updateCacheContext = function(){};
+ proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset) {
+ var node = this._node, hasRotation = (node._rotationX || node._rotationY),
+ layerOrientation = node.layerOrientation,
+ tiles = node.tiles;
+
+ if (!tiles) {
+ return 0;
+ }
- proto.initImageSize = function(){
- var node = this._node;
- node.tileset.imageSize = this._textureAtlas.texture.getContentSizeInPixels();
+ var scalex = cc.view._scaleX,
+ scaley = cc.view._scaleY,
+ maptw = node._mapTileSize.width,
+ mapth = node._mapTileSize.height,
+ tilew = node.tileset._tileSize.width / cc.director._contentScaleFactor,
+ tileh = node.tileset._tileSize.height / cc.director._contentScaleFactor,
+ extw = tilew - maptw,
+ exth = tileh - mapth,
+ winw = cc.winSize.width,
+ winh = cc.winSize.height,
+ rows = node._layerSize.height,
+ cols = node._layerSize.width,
+ grids = node._texGrids,
+ spTiles = node._spriteTiles,
+ wt = this._worldTransform,
+ a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
+ ox = -node._contentSize.width * node._anchorPoint.x,
+ oy = -node._contentSize.height * node._anchorPoint.y,
+ mapx = ox * a + oy * c + tx,
+ mapy = ox * b + oy * d + ty;
- // By default all the tiles are aliased
- // pros:
- // - easier to render
- // cons:
- // - difficult to scale / rotate / etc.
- this._textureAtlas.texture.setAliasTexParameters();
- };
+ var opacity = node._opacity,
+ cr = this._displayedColor.r,
+ cg = this._displayedColor.g,
+ cb = this._displayedColor.b;
+ if (node._opacityModifyRGB) {
+ var ca = opacity / 255;
+ cr *= ca;
+ cg *= ca;
+ cb *= ca;
+ }
+ this._color[0] = ((opacity << 24) | (cb << 16) | (cg << 8) | cr);
+
+ // Culling
+ var startCol = 0, startRow = 0,
+ maxCol = cols, maxRow = rows;
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ORTHO) {
+ startCol = Math.floor(-(mapx - extw * a) / (maptw * a));
+ startRow = Math.floor((mapy - exth * d + mapth * rows * d - winh) / (mapth * d));
+ maxCol = Math.ceil((winw - mapx + extw * a) / (maptw * a));
+ maxRow = rows - Math.floor(-(mapy + exth * d) / (mapth * d));
+ // Adjustment
+ if (startCol < 0) startCol = 0;
+ if (startRow < 0) startRow = 0;
+ if (maxCol > cols) maxCol = cols;
+ if (maxRow > rows) maxRow = rows;
+ }
+
+ var row, col,
+ offset = vertexDataOffset,
+ colOffset = startRow * cols, z, gid, grid,
+ mask = cc.TMX_TILE_FLIPPED_MASK,
+ i, top, left, bottom, right,
+ w = tilew * a, h = tileh * d, gt, gl, gb, gr,
+ wa = a, wb = b, wc = c, wd = d, wtx = tx, wty = ty, // world
+ flagged = false, flippedX = false, flippedY = false,
+ vertices = this._vertices;
+ for (row = startRow; row < maxRow; ++row) {
+ for (col = startCol; col < maxCol; ++col) {
+ // No more buffer
+ if (offset + 24 > f32buffer.length) {
+ cc.renderer._increaseBatchingSize((offset - vertexDataOffset) / 6);
+ cc.renderer._batchRendering();
+ vertexDataOffset = 0;
+ offset = 0;
+ }
+
+ z = colOffset + col;
+ // Skip sprite tiles
+ if (spTiles[z]) {
+ continue;
+ }
+
+ gid = node.tiles[z];
+ grid = grids[(gid & mask) >>> 0];
+ if (!grid) {
+ continue;
+ }
+
+ // Vertices
+ switch (layerOrientation) {
+ case cc.TMX_ORIENTATION_ORTHO:
+ left = col * maptw;
+ bottom = (rows - row - 1) * mapth;
+ z = node._vertexZ + cc.renderer.assignedZStep * z / tiles.length;
+ break;
+ case cc.TMX_ORIENTATION_ISO:
+ left = maptw / 2 * ( cols + col - row - 1);
+ bottom = mapth / 2 * ( rows * 2 - col - row - 2);
+ z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height;
+ break;
+ case cc.TMX_ORIENTATION_HEX:
+ left = col * maptw * 3 / 4;
+ bottom = (rows - row - 1) * mapth + ((col % 2 === 1) ? (-mapth / 2) : 0);
+ z = node._vertexZ + cc.renderer.assignedZStep * (node.height - bottom) / node.height;
+ break;
+ }
+ right = left + tilew;
+ top = bottom + tileh;
+ // TMX_ORIENTATION_ISO trim
+ if (!hasRotation && layerOrientation === cc.TMX_ORIENTATION_ISO) {
+ gb = mapy + bottom * d;
+ if (gb > winh + h) {
+ col += Math.floor((gb - winh) * 2 / h) - 1;
+ continue;
+ }
+ gr = mapx + right * a;
+ if (gr < -w) {
+ col += Math.floor((-gr) * 2 / w) - 1;
+ continue;
+ }
+ gl = mapx + left * a;
+ gt = mapy + top * d;
+ if (gl > winw || gt < 0) {
+ col = maxCol;
+ continue;
+ }
+ }
+ // Rotation and Flip
+ if (gid > cc.TMX_TILE_DIAGONAL_FLAG) {
+ flagged = true;
+ flippedX = (gid & cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0;
+ flippedY = (gid & cc.TMX_TILE_VERTICAL_FLAG) >>> 0;
+ // if ((gid & cc.TMX_TILE_DIAGONAL_FLAG) >>> 0) {
+ // var flag = (gid & (cc.TMX_TILE_HORIZONTAL_FLAG | cc.TMX_TILE_VERTICAL_FLAG) >>> 0) >>> 0;
+ // // handle the 4 diagonally flipped states.
+ // var la, lb, lc, ld;
+ // if (flag === cc.TMX_TILE_HORIZONTAL_FLAG || flag === (cc.TMX_TILE_VERTICAL_FLAG | cc.TMX_TILE_HORIZONTAL_FLAG) >>> 0) {
+ // lb = -(lc = this._sin90);
+ // la = ld = this._cos90;
+ // }
+ // else {
+ // lb = -(lc = this._sin270);
+ // la = ld = this._cos270;
+ // }
+ // left += grid.width * scalex / 2;
+ // bottom += grid.height * scaley / 2;
+ // wa = la * a + lb * c;
+ // wb = la * b + lb * d;
+ // wc = lc * a + ld * c;
+ // wd = lc * b + ld * d;
+ // wtx = a * left + c * bottom + tx;
+ // wty = d * bottom + ty + b * left;
+ // right = right - left;
+ // top = top - bottom;
+ // left = -right;
+ // bottom = -top;
+ // }
+ }
+
+ vertices[0].x = left * wa + top * wc + wtx; // tl
+ vertices[0].y = left * wb + top * wd + wty;
+ vertices[1].x = left * wa + bottom * wc + wtx; // bl
+ vertices[1].y = left * wb + bottom * wd + wty;
+ vertices[2].x = right * wa + top * wc + wtx; // tr
+ vertices[2].y = right * wb + top * wd + wty;
+ vertices[3].x = right * wa + bottom * wc + wtx; // br
+ vertices[3].y = right * wb + bottom * wd + wty;
+
+ for (i = 0; i < 4; ++i) {
+ f32buffer[offset] = vertices[i].x;
+ f32buffer[offset + 1] = vertices[i].y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = this._color[0];
+ switch (i) {
+ case 0: // tl
+ f32buffer[offset + 4] = flippedX ? grid.r : grid.l;
+ f32buffer[offset + 5] = flippedY ? grid.b : grid.t;
+ break;
+ case 1: // bl
+ f32buffer[offset + 4] = flippedX ? grid.r : grid.l;
+ f32buffer[offset + 5] = flippedY ? grid.t : grid.b;
+ break;
+ case 2: // tr
+ f32buffer[offset + 4] = flippedX ? grid.l : grid.r;
+ f32buffer[offset + 5] = flippedY ? grid.b : grid.t;
+ break;
+ case 3: // br
+ f32buffer[offset + 4] = flippedX ? grid.l : grid.r;
+ f32buffer[offset + 5] = flippedY ? grid.t : grid.b;
+ break;
+ }
- proto._reusedTileWithRect = function(rect){
- var node = this._node;
- if (!node._reusedTile) {
- node._reusedTile = new cc.Sprite();
- node._reusedTile.initWithTexture(node.texture, rect, false);
- node._reusedTile.batchNode = node;
- } else {
- // XXX HACK: Needed because if "batch node" is nil,
- // then the Sprite'squad will be reset
- node._reusedTile.batchNode = null;
-
- // Re-init the sprite
- node._reusedTile.setTextureRect(rect, false);
-
- // restore the batch node
- node._reusedTile.batchNode = node;
+ offset += 6;
+ }
+ if (flagged) {
+ wa = a;
+ wb = b;
+ wc = c;
+ wd = d;
+ wtx = tx;
+ wty = ty;
+ flippedX = false;
+ flippedY = false;
+ flagged = false;
+ }
+ }
+ colOffset += cols;
}
- return node._reusedTile;
+ return (offset - vertexDataOffset) / 6;
};
})();
diff --git a/cocos2d/tilemap/CCTMXTiledMap.js b/cocos2d/tilemap/CCTMXTiledMap.js
index 97165dd3b2..5ca4107ed2 100644
--- a/cocos2d/tilemap/CCTMXTiledMap.js
+++ b/cocos2d/tilemap/CCTMXTiledMap.js
@@ -72,7 +72,7 @@ cc.TMX_ORIENTATION_ISO = 2;
*
*
Limitations:
* - It only supports one tileset per layer.
- * - Embeded images are not supported
+ * - Embedded images are not supported
* - It only supports the XML format (the JSON format is not supported)
Technical description:
@@ -270,7 +270,7 @@ cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{
*/
initWithTMXFile:function (tmxFile) {
if(!tmxFile || tmxFile.length === 0)
- throw "cc.TMXTiledMap.initWithTMXFile(): tmxFile should be non-null or non-empty string.";
+ throw new Error("cc.TMXTiledMap.initWithTMXFile(): tmxFile should be non-null or non-empty string.");
this.width = 0;
this.height = 0;
var mapInfo = new cc.TMXMapInfo(tmxFile);
@@ -349,7 +349,7 @@ cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{
*/
getLayer:function (layerName) {
if(!layerName || layerName.length === 0)
- throw "cc.TMXTiledMap.getLayer(): layerName should be non-null or non-empty string.";
+ throw new Error("cc.TMXTiledMap.getLayer(): layerName should be non-null or non-empty string.");
var locChildren = this._children;
for (var i = 0; i < locChildren.length; i++) {
var layer = locChildren[i];
@@ -367,7 +367,7 @@ cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{
*/
getObjectGroup:function (groupName) {
if(!groupName || groupName.length === 0)
- throw "cc.TMXTiledMap.getObjectGroup(): groupName should be non-null or non-empty string.";
+ throw new Error("cc.TMXTiledMap.getObjectGroup(): groupName should be non-null or non-empty string.");
if (this.objectGroups) {
for (var i = 0; i < this.objectGroups.length; i++) {
var objectGroup = this.objectGroups[i];
@@ -414,7 +414,6 @@ cc.TMXTiledMap = cc.Node.extend(/** @lends cc.TMXTiledMap# */{
var layer = new cc.TMXLayer(tileset, layerInfo, mapInfo);
// tell the layerinfo to release the ownership of the tiles map.
layerInfo.ownTiles = false;
- layer.setupTiles();
return layer;
},
diff --git a/cocos2d/tilemap/CCTMXXMLParser.js b/cocos2d/tilemap/CCTMXXMLParser.js
index 63b295d0e7..70509e6802 100644
--- a/cocos2d/tilemap/CCTMXXMLParser.js
+++ b/cocos2d/tilemap/CCTMXXMLParser.js
@@ -123,7 +123,7 @@ cc.TMXLayerInfo = cc.Class.extend(/** @lends cc.TMXLayerInfo# */{
this.properties = [];
this.name = "";
this._layerSize = null;
- this._tiles = [];
+ this._tiles = null;
this.visible = true;
this._opacity = 0;
this.ownTiles = true;
@@ -200,8 +200,8 @@ cc.TMXTilesetInfo = cc.Class.extend(/** @lends cc.TMXTilesetInfo# */{
* @param {Number} gid
* @return {cc.Rect}
*/
- rectForGID:function (gid) {
- var rect = cc.rect(0, 0, 0, 0);
+ rectForGID:function (gid, result) {
+ var rect = result || cc.rect(0, 0, 0, 0);
rect.width = this._tileSize.width;
rect.height = this._tileSize.height;
gid &= cc.TMX_TILE_FLIPPED_MASK;
@@ -531,7 +531,7 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{
parseXMLFile:function (tmxFile, isXmlString) {
isXmlString = isXmlString || false;
var xmlStr = isXmlString ? tmxFile : cc.loader.getRes(tmxFile);
- if(!xmlStr) throw "Please load the resource first : " + tmxFile;
+ if(!xmlStr) throw new Error("Please load the resource first : " + tmxFile);
var mapXML = this._parseXML(xmlStr);
var i, j;
@@ -682,30 +682,31 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{
cc.log("cc.TMXMapInfo.parseXMLFile(): unsupported compression method");
return null;
}
+ var tiles;
switch (compression) {
case 'gzip':
- layer._tiles = cc.unzipBase64AsArray(nodeValue, 4);
+ tiles = cc.unzipBase64AsArray(nodeValue, 4);
break;
case 'zlib':
var inflator = new Zlib.Inflate(cc.Codec.Base64.decodeAsArray(nodeValue, 1));
- layer._tiles = cc.uint8ArrayToUint32Array(inflator.decompress());
+ tiles = cc.uint8ArrayToUint32Array(inflator.decompress());
break;
case null:
case '':
// Uncompressed
if (encoding === "base64")
- layer._tiles = cc.Codec.Base64.decodeAsArray(nodeValue, 4);
+ tiles = cc.Codec.Base64.decodeAsArray(nodeValue, 4);
else if (encoding === "csv") {
- layer._tiles = [];
+ tiles = [];
var csvTiles = nodeValue.split(',');
for (var csvIdx = 0; csvIdx < csvTiles.length; csvIdx++)
- layer._tiles.push(parseInt(csvTiles[csvIdx]));
+ tiles.push(parseInt(csvTiles[csvIdx]));
} else {
//XML format
var selDataTiles = data.getElementsByTagName("tile");
- layer._tiles = [];
+ tiles = [];
for (var xmlIdx = 0; xmlIdx < selDataTiles.length; xmlIdx++)
- layer._tiles.push(parseInt(selDataTiles[xmlIdx].getAttribute("gid")));
+ tiles.push(parseInt(selDataTiles[xmlIdx].getAttribute("gid")));
}
break;
default:
@@ -713,6 +714,9 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{
cc.log("cc.TMXMapInfo.parseXMLFile(): Only base64 and/or gzip/zlib maps are supported");
break;
}
+ if (tiles) {
+ layer._tiles = new Uint32Array(tiles);
+ }
// The parent element is the last layer
var layerProps = selLayer.querySelectorAll("properties > property");
@@ -783,7 +787,7 @@ cc.TMXMapInfo = cc.SAXParser.extend(/** @lends cc.TMXMapInfo# */{
if(polygonProps && polygonProps.length > 0) {
var selPgPointStr = polygonProps[0].getAttribute('points');
if(selPgPointStr)
- objectProp["polygonPoints"] = this._parsePointsString(selPgPointStr);
+ objectProp["points"] = this._parsePointsString(selPgPointStr);
}
//polyline
diff --git a/cocos2d/transitions/CCTransition.js b/cocos2d/transitions/CCTransition.js
index 204f3897a7..09b18228e6 100644
--- a/cocos2d/transitions/CCTransition.js
+++ b/cocos2d/transitions/CCTransition.js
@@ -64,12 +64,12 @@ cc.TRANSITION_ORIENTATION_DOWN_OVER = 1;
* var trans = new TransitionScene(time,scene);
*/
cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{
- _inScene:null,
- _outScene:null,
- _duration:null,
- _isInSceneOnTop:false,
- _isSendCleanupToScene:false,
- _className:"TransitionScene",
+ _inScene: null,
+ _outScene: null,
+ _duration: null,
+ _isInSceneOnTop: false,
+ _isSendCleanupToScene: false,
+ _className: "TransitionScene",
/**
* creates a base transition with duration and incoming scene
@@ -77,14 +77,14 @@ cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{
* @param {Number} t time in seconds
* @param {cc.Scene} scene the scene to transit with
*/
- ctor:function (t, scene) {
+ ctor: function (t, scene) {
cc.Scene.prototype.ctor.call(this);
- if(t !== undefined && scene !== undefined)
+ if (t !== undefined && scene !== undefined)
this.initWithDuration(t, scene);
},
//private
- _setNewScene:function (dt) {
+ _setNewScene: function (dt) {
this.unschedule(this._setNewScene);
// Before replacing, save the "send cleanup to scene"
var director = cc.director;
@@ -99,14 +99,14 @@ cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{
},
//protected
- _sceneOrder:function () {
+ _sceneOrder: function () {
this._isInSceneOnTop = true;
},
/**
* stuff gets drawn here
*/
- visit:function () {
+ visit: function () {
if (this._isInSceneOnTop) {
this._outScene.visit();
this._inScene.visit();
@@ -125,7 +125,7 @@ cc.TransitionScene = cc.Scene.extend(/** @lends cc.TransitionScene# */{
* If you override onEnter, you must call its parent's onEnter function with this._super().
*
* Adds a child to the container with z order and tag
@@ -55,25 +115,25 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @param {Number} [localZOrder] Z order for drawing priority. Please refer to `setLocalZOrder(int)`
* @param {Number} [tag] An integer to identify the node easily. Please refer to `setTag(int)`
*/
- addProtectedChild: function(child, localZOrder, tag){
- cc.assert(child != null, "child must be non-nil");
- cc.assert(!child.parent, "child already added. It can't be added again");
+ addProtectedChild: function (child, localZOrder, tag) {
+ cc.assert(child != null, "child must be non-nil");
+ cc.assert(!child.parent, "child already added. It can't be added again");
localZOrder = localZOrder || child.getLocalZOrder();
- if(tag)
+ if (tag)
child.setTag(tag);
this._insertProtectedChild(child, localZOrder);
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();
+ if (this._isTransitionFinished)
+ child._performRecursive(cc.Node._stateCallbackType.onEnterTransitionDidFinish);
}
- if(this._cascadeColorEnabled)
+ if (this._cascadeColorEnabled)
this._renderCmd.setCascadeColorEnabledDirty();
if (this._cascadeOpacityEnabled)
this._renderCmd.setCascadeOpacityEnabledDirty();
@@ -84,11 +144,11 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @param {Number} tag An identifier to find the child node.
* @return {cc.Node} a Node object whose tag equals to the input parameter
*/
- getProtectedChildByTag: function(tag){
+ getProtectedChildByTag: function (tag) {
cc.assert(tag !== cc.NODE_TAG_INVALID, "Invalid tag");
var locChildren = this._protectedChildren;
- for(var i = 0, len = locChildren.length; i < len; i++)
- if(locChildren.getTag() === tag)
+ for (var i = 0, len = locChildren.length; i < len; i++)
+ if (locChildren.getTag() === tag)
return locChildren[i];
return null;
},
@@ -98,23 +158,23 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @param {cc.Node} child The child node which will be removed.
* @param {Boolean} [cleanup=true] true if all running actions and callbacks on the child node will be cleanup, false otherwise.
*/
- removeProtectedChild: function(child, cleanup){
- if(cleanup == null)
+ removeProtectedChild: function (child, cleanup) {
+ if (cleanup == null)
cleanup = true;
- var locChildren = this._protectedChildren;
- if(locChildren.length === 0)
+ var locChildren = this._protectedChildren;
+ if (locChildren.length === 0)
return;
var idx = locChildren.indexOf(child);
- if(idx > -1){
- if(this._running){
- child.onExitTransitionDidStart();
- child.onExit();
- }
+ if (idx > -1) {
+ if (this._running) {
+ 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
// its scheduledSelectors_ dict will not get released!
if (cleanup)
- child.cleanup();
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
// set parent nil at the end
child.setParent(null);
@@ -128,10 +188,10 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @param {Number} tag
* @param {Boolean} [cleanup=true]
*/
- removeProtectedChildByTag: function(tag, cleanup){
- cc.assert( tag !== cc.NODE_TAG_INVALID, "Invalid tag");
+ removeProtectedChildByTag: function (tag, cleanup) {
+ cc.assert(tag !== cc.NODE_TAG_INVALID, "Invalid tag");
- if(cleanup == null)
+ if (cleanup == null)
cleanup = true;
var child = this.getProtectedChildByTag(tag);
@@ -146,7 +206,7 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* Removes all children from the container with a cleanup.
* @see cc.ProtectedNode#removeAllProtectedChildrenWithCleanup
*/
- removeAllProtectedChildren: function(){
+ removeAllProtectedChildren: function () {
this.removeAllProtectedChildrenWithCleanup(true);
},
@@ -154,23 +214,23 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* Removes all children from the container, and do a cleanup to all running actions depending on the cleanup parameter.
* @param {Boolean} [cleanup=true] true if all running actions on all children nodes should be cleanup, false otherwise.
*/
- removeAllProtectedChildrenWithCleanup: function(cleanup){
- if(cleanup == null)
+ removeAllProtectedChildrenWithCleanup: function (cleanup) {
+ if (cleanup == null)
cleanup = true;
var locChildren = this._protectedChildren;
// not using detachChild improves speed here
- for (var i = 0, len = locChildren.length; i< len; i++) {
+ for (var i = 0, len = locChildren.length; i < len; i++) {
var child = locChildren[i];
// IMPORTANT:
// -1st do onExit
// -2nd cleanup
- if(this._running){
- child.onExitTransitionDidStart();
- child.onExit();
+ if (this._running) {
+ child._performRecursive(cc.Node._stateCallbackType.onExitTransitionDidStart);
+ child._performRecursive(cc.Node._stateCallbackType.onExit);
}
if (cleanup)
- child.cleanup();
+ child._performRecursive(cc.Node._stateCallbackType.cleanup);
// set parent nil at the end
child.setParent(null);
}
@@ -182,8 +242,8 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @param {cc.Node} child An already added child node. It MUST be already added.
* @param {Number} localZOrder Z order for drawing priority. Please refer to setLocalZOrder(int)
*/
- reorderProtectedChild: function(child, localZOrder){
- cc.assert( child != null, "Child must be non-nil");
+ reorderProtectedChild: function (child, localZOrder) {
+ cc.assert(child != null, "Child must be non-nil");
this._reorderProtectedChildDirty = true;
child.setOrderOfArrival(cc.s_globalOrderOfArrival++);
child._setLocalZOrder(localZOrder);
@@ -196,27 +256,27 @@ cc.ProtectedNode = cc.Node.extend(/** @lends cc.ProtectedNode# */{
* @note Don't call this manually unless a child added needs to be removed in the same frame
*
- * Event callback that is invoked when the Node enters in the 'stage'.
- * If the Node enters the 'stage' with a transition, this event is called when the transition finishes.
- * If you override onEnterTransitionDidFinish, you shall call its parent's one, e.g. Node::onEnterTransitionDidFinish()
- *
- * Event callback that is called every time the Node leaves the 'stage'.
- * If the Node leaves the 'stage' with a transition, this callback is called when the transition starts.
- *
@@ -35,7 +329,6 @@
* to specific areas of a sprite. With 9-slice scaling (3x3 grid),
* you can ensure that the sprite does not become distorted when
* scaled.
- * @note: it will refactor in v3.1
* @see http://yannickloriot.com/library/ios/cccontrolextension/Classes/CCScale9Sprite.html
*
- * Returns the flag which indicates whether the widget is flipped horizontally or not.
- *
- * It only flips the texture of the widget, and not the texture of the widget's children.
- * Also, flipping the texture doesn't alter the anchorPoint.
- * If you want to flip the anchorPoint too, and/or to flip the children too use:
- * widget->setScaleX(sprite->getScaleX() * -1);
- *
- * Return the flag which indicates whether the widget is flipped vertically or not.
- *
- * It only flips the texture of the widget, and not the texture of the widget's children.
- * Also, flipping the texture doesn't alter the anchorPoint.
- * If you want to flip the anchorPoint too, and/or to flip the children too use:
- * widget->setScaleY(widget->getScaleY() * -1);
- *
* Sets whether the widget is enabled
@@ -345,12 +332,14 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
*/
setEnabled: function (enabled) {
this._enabled = enabled;
+ this.setBright(enabled);
},
/**
* initializes renderer of widget.
*/
- _initRenderer: function () {},
+ _initRenderer: function () {
+ },
/**
* Sets _customSize of ccui.Widget, if ignoreSize is true, the content size is its renderer's contentSize, otherwise the content size is parameter.
@@ -360,15 +349,16 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @override
*/
setContentSize: function(contentSize, height){
- var locWidth = (height === undefined) ? contentSize.width : contentSize;
- var locHeight = (height === undefined) ? contentSize.height : height;
- cc.Node.prototype.setContentSize.call(this, locWidth, locHeight);
+ cc.Node.prototype.setContentSize.call(this, contentSize, height);
+
+ var locWidth = this._contentSize.width;
+ var locHeight = this._contentSize.height;
this._customSize.width = locWidth;
this._customSize.height = locHeight;
if(this._unifySize){
//unify size logic
- } else if (this._ignoreSize){
+ } else if (this._ignoreSize) {
this._contentSize = this.getVirtualRendererSize();
}
if (!this._usingLayoutComponent && this._running) {
@@ -377,15 +367,23 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
this._sizePercent.x = (pSize.width > 0.0) ? locWidth / pSize.width : 0.0;
this._sizePercent.y = (pSize.height > 0.0) ? locHeight / pSize.height : 0.0;
}
- this._onSizeChanged();
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
},
_setWidth: function (w) {
+ if (w === this._contentSize.width) {
+ return;
+ }
cc.Node.prototype._setWidth.call(this, w);
this._customSize.width = w;
if(this._unifySize){
//unify size logic
- } else if (this._ignoreSize){
+ } else if (this._ignoreSize) {
this._contentSize = this.getVirtualRendererSize();
}
@@ -394,14 +392,23 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
var locWidth = widgetParent ? widgetParent.width : this._parent.width;
this._sizePercent.x = locWidth > 0 ? this._customSize.width / locWidth : 0;
}
- this._onSizeChanged();
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
},
_setHeight: function (h) {
+ if (h === this._contentSize.height) {
+ return;
+ }
+
cc.Node.prototype._setHeight.call(this, h);
this._customSize.height = h;
if(this._unifySize){
//unify size logic
- } else if (this._ignoreSize){
+ } else if (this._ignoreSize) {
this._contentSize = this.getVirtualRendererSize();
}
@@ -410,7 +417,12 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
var locH = widgetParent ? widgetParent.height : this._parent.height;
this._sizePercent.y = locH > 0 ? this._customSize.height / locH : 0;
}
- this._onSizeChanged();
+
+ if (this._running) {
+ this._onSizeChanged();
+ } else {
+ this._sizeDirty = true;
+ }
},
/**
@@ -480,9 +492,9 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @param {cc.Size} [parentSize] parent size
*/
updateSizeAndPosition: function (parentSize) {
- if(!parentSize){
+ if (!parentSize) {
var widgetParent = this.getWidgetParent();
- if(widgetParent)
+ if (widgetParent)
parentSize = widgetParent.getLayoutSize();
else
parentSize = this._parent.getContentSize();
@@ -490,7 +502,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
switch (this._sizeType) {
case ccui.Widget.SIZE_ABSOLUTE:
- if(this._ignoreSize)
+ if (this._ignoreSize)
this.setContentSize(this.getVirtualRendererSize());
else
this.setContentSize(this._customSize);
@@ -498,8 +510,8 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
this._sizePercent.y = (parentSize.height > 0) ? this._customSize.height / parentSize.height : 0;
break;
case ccui.Widget.SIZE_PERCENT:
- var cSize = cc.size(parentSize.width * this._sizePercent.x , parentSize.height * this._sizePercent.y);
- if(this._ignoreSize)
+ var cSize = cc.size(parentSize.width * this._sizePercent.x, parentSize.height * this._sizePercent.y);
+ if (this._ignoreSize)
this.setContentSize(this.getVirtualRendererSize());
else
this.setContentSize(cSize);
@@ -526,9 +538,9 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
default:
break;
}
- if(this._parent instanceof ccui.ImageView){
+ if (this._parent instanceof ccui.ImageView) {
var renderer = this._parent._imageRenderer;
- if(renderer && !renderer._textureLoaded)
+ if (renderer && !renderer._textureLoaded)
return;
}
this.setPosition(absPos);
@@ -564,11 +576,11 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
return;
}
- if(this._ignoreSize === ignore)
+ if (this._ignoreSize === ignore)
return;
this._ignoreSize = ignore;
- this.setContentSize( ignore ? this.getVirtualRendererSize() : this._customSize );
+ this.setContentSize(ignore ? this.getVirtualRendererSize() : this._customSize);
//this._onSizeChanged();
},
@@ -592,7 +604,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* Gets layout size of ccui.Widget.
* @returns {cc.Size}
*/
- getLayoutSize: function(){
+ getLayoutSize: function () {
return cc.size(this._contentSize);
},
@@ -633,7 +645,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
/**
* Gets the content size of widget. Content size is widget's texture size.
*/
- getVirtualRendererSize:function(){
+ getVirtualRendererSize: function () {
return cc.size(this._contentSize);
},
@@ -642,12 +654,13 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
*/
_onSizeChanged: function () {
if(!this._usingLayoutComponent){
- var locChildren = this.getChildren();
+ var locChildren = this.getChildren();
for (var i = 0, len = locChildren.length; i < len; i++) {
var child = locChildren[i];
- if(child instanceof ccui.Widget)
+ if (child instanceof ccui.Widget)
child.updateSizeAndPosition();
}
+ this._sizeDirty = false;
}
},
@@ -661,7 +674,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
this._touchEnabled = enable; //TODO need consider remove and re-add.
if (this._touchEnabled) {
- if(!this._touchListener)
+ if (!this._touchListener)
this._touchListener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
swallowTouches: true,
@@ -687,7 +700,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* Determines if the widget is highlighted
* @returns {boolean} true if the widget is highlighted, false if the widget is not highlighted .
*/
- isHighlighted: function(){
+ isHighlighted: function () {
return this._highlight;
},
@@ -695,7 +708,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* Sets whether the widget is highlighted. The default value is false, a widget is default to not highlighted
* @param highlight true if the widget is highlighted, false if the widget is not highlighted.
*/
- setHighlighted:function(highlight){
+ setHighlighted: function (highlight) {
if (highlight === this._highlight)
return;
this._highlight = highlight;
@@ -724,9 +737,9 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
setFocused: function (focus) {
this._focused = focus;
//make sure there is only one focusedWidget
- if (focus){
+ if (focus) {
ccui.Widget._focusedWidget = this;
- if(ccui.Widget._focusNavigationController)
+ if (ccui.Widget._focusNavigationController)
ccui.Widget._focusNavigationController._setFirstFocsuedWidget(this);
}
},
@@ -735,7 +748,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* returns whether the widget could accept focus.
* @returns {boolean} true represent the widget could accept focus, false represent the widget couldn't accept focus
*/
- isFocusEnabled: function(){
+ isFocusEnabled: function () {
return this._focusEnabled;
},
@@ -743,7 +756,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* sets whether the widget could accept focus.
* @param {Boolean} enable true represent the widget could accept focus, false represent the widget couldn't accept focus
*/
- setFocusEnabled: function(enable){
+ setFocusEnabled: function (enable) {
this._focusEnabled = enable;
},
@@ -756,12 +769,12 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @param current the current focused widget
* @return the next focused widget in a layout
*/
- findNextFocusedWidget: function( direction, current){
- if (null === this.onNextFocusedWidget || null == this.onNextFocusedWidget(direction) ) {
+ findNextFocusedWidget: function (direction, current) {
+ if (null === this.onNextFocusedWidget || null == this.onNextFocusedWidget(direction)) {
var isLayout = current instanceof ccui.Layout;
if (this.isFocused() || isLayout) {
var layout = this.getParent();
- if (null === layout || !(layout instanceof ccui.Layout)){
+ if (null === layout || !(layout instanceof ccui.Layout)) {
//the outer layout's default behaviour is : loop focus
if (isLayout)
return current.findNextFocusedWidget(direction, current);
@@ -780,7 +793,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
/**
* when a widget calls this method, it will get focus immediately.
*/
- requestFocus: function(){
+ requestFocus: function () {
if (this === ccui.Widget._focusedWidget)
return;
this.dispatchFocusEvent(ccui.Widget._focusedWidget, this);
@@ -789,7 +802,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
/**
* no matter what widget object you call this method on , it will return you the exact one focused widget
*/
- getCurrentFocusedWidget: function(){
+ getCurrentFocusedWidget: function () {
return ccui.Widget._focusedWidget;
},
@@ -812,10 +825,10 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @param {ccui.Widget} sender
* @param {cc.Touch} touch
*/
- interceptTouchEvent: function(eventType, sender, touch){
+ interceptTouchEvent: function (eventType, sender, touch) {
var widgetParent = this.getWidgetParent();
if (widgetParent)
- widgetParent.interceptTouchEvent(eventType,sender,touch);
+ widgetParent.interceptTouchEvent(eventType, sender, touch);
},
/**
@@ -823,7 +836,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @param {ccui.Widget} widgetLostFocus
* @param {ccui.Widget} widgetGetFocus
*/
- onFocusChange: function(widgetLostFocus, widgetGetFocus){
+ onFocusChange: function (widgetLostFocus, widgetGetFocus) {
//only change focus when there is indeed a get&lose happens
if (widgetLostFocus)
widgetLostFocus.setFocused(false);
@@ -836,12 +849,12 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
* @param {ccui.Widget} widgetLostFocus
* @param {ccui.Widget} widgetGetFocus
*/
- dispatchFocusEvent: function(widgetLostFocus, widgetGetFocus){
+ dispatchFocusEvent: function (widgetLostFocus, widgetGetFocus) {
//if the widgetLoseFocus doesn't get focus, it will use the previous focused widget instead
if (widgetLostFocus && !widgetLostFocus.isFocused())
widgetLostFocus = ccui.Widget._focusedWidget;
- if (widgetGetFocus !== widgetLostFocus){
+ if (widgetGetFocus !== widgetLostFocus) {
if (widgetGetFocus && widgetGetFocus.onFocusChanged)
widgetGetFocus.onFocusChanged(widgetLostFocus, widgetGetFocus);
if (widgetLostFocus && widgetGetFocus.onFocusChanged)
@@ -885,13 +898,16 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
}
},
- _onPressStateChangedToNormal: function () {},
+ _onPressStateChangedToNormal: function () {
+ },
- _onPressStateChangedToPressed: function () {},
+ _onPressStateChangedToPressed: function () {
+ },
- _onPressStateChangedToDisabled: function () {},
+ _onPressStateChangedToDisabled: function () {
+ },
- _updateChildrenDisplayedRGBA: function(){
+ _updateChildrenDisplayedRGBA: function () {
this.setColor(this.getColor());
this.setOpacity(this.getOpacity());
},
@@ -899,7 +915,8 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
/**
* A call back function when widget lost of focus.
*/
- didNotSelectSelf: function () {},
+ didNotSelectSelf: function () {
+ },
/**
*
@@ -918,11 +935,11 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ */ onTouchBegan: function (touch, event) { this._hit = false; - if (this.isVisible() && this.isEnabled() && this._isAncestorsEnabled() && this._isAncestorsVisible(this) ){ + if (this.isVisible() && this.isEnabled() && this._isAncestorsEnabled() && this._isAncestorsVisible(this)) { var touchPoint = touch.getLocation(); this._touchBeganPosition.x = touchPoint.x; this._touchBeganPosition.y = touchPoint.y; - if(this.hitTest(this._touchBeganPosition) && this.isClippingParentContainsPoint(this._touchBeganPosition)) + if (this.hitTest(this._touchBeganPosition) && this.isClippingParentContainsPoint(this._touchBeganPosition)) this._hit = true; } if (!this._hit) { @@ -941,9 +958,9 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ return true; }, - propagateTouchEvent: function(event, sender, touch){ + propagateTouchEvent: function (event, sender, touch) { var widgetParent = this.getWidgetParent(); - if (widgetParent){ + if (widgetParent) { widgetParent.interceptTouchEvent(event, sender, touch); } }, @@ -1055,7 +1072,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @param {Object} target */ addTouchEventListener: function (selector, target) { - if(target === undefined) + if (target === undefined) this._touchEventCallback = selector; else { this._touchEventSelector = selector; @@ -1063,7 +1080,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ } }, - addClickEventListener: function(callback){ + addClickEventListener: function (callback) { this._clickEventListener = callback; }, @@ -1073,7 +1090,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @returns {boolean} true if the point is in widget's space, false otherwise. */ hitTest: function (pt) { - var bb = cc.rect(0,0, this._contentSize.width, this._contentSize.height); + var bb = cc.rect(0, 0, this._contentSize.width, this._contentSize.height); return cc.rectContainsPoint(bb, this.convertToNodeSpace(pt)); }, @@ -1082,7 +1099,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @param {cc.Point} pt location point * @returns {Boolean} */ - isClippingParentContainsPoint: function(pt){ + isClippingParentContainsPoint: function (pt) { this._affectByClipping = false; var parent = this.getParent(); var clippingParent = null; @@ -1205,6 +1222,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ return; } this._positionPercent.x = percent; + this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); }, _setYPercent: function (percent) { if (this._usingLayoutComponent){ @@ -1214,6 +1232,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ return; } this._positionPercent.y = percent; + this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.transformDirty); }, /** @@ -1321,7 +1340,8 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ return this._flippedY; }, - _adaptRenderers: function(){}, + _adaptRenderers: function () { + }, /** * Determines if the widget is bright @@ -1375,15 +1395,15 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * Gets the position of touch began event. * @returns {cc.Point} */ - getTouchBeganPosition: function(){ - return cc.p(this._touchBeganPosition); + getTouchBeganPosition: function () { + return cc.p(this._touchBeganPosition); }, /** * Gets the position of touch moved event * @returns {cc.Point} */ - getTouchMovePosition: function(){ + getTouchMovePosition: function () { return cc.p(this._touchMovePosition); }, @@ -1391,7 +1411,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * Gets the position of touch end event * @returns {cc.Point} */ - getTouchEndPosition:function(){ + getTouchEndPosition: function () { return cc.p(this._touchEndPosition); }, @@ -1408,7 +1428,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @param {ccui.LayoutParameter} parameter */ setLayoutParameter: function (parameter) { - if(!parameter) + if (!parameter) return; this._layoutParameterDictionary[parameter.getLayoutType()] = parameter; this._layoutParameterType = parameter.getLayoutType(); @@ -1456,7 +1476,8 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ } }, - _copySpecialProperties: function (model) {}, + _copySpecialProperties: function (model) { + }, _copyProperties: function (widget) { this.setEnabled(widget.isEnabled()); @@ -1508,7 +1529,6 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ if (parameter) this.setLayoutParameter(parameter.clone()); } - this._onSizeChanged(); }, /*temp action*/ @@ -1525,7 +1545,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @deprecated since v3.0, please use getLeftBoundary instead. * @returns {number} */ - getLeftInParent: function(){ + getLeftInParent: function () { cc.log("getLeftInParent is deprecated. Please use getLeftBoundary instead."); return this.getLeftBoundary(); }, @@ -1535,7 +1555,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @deprecated since v3.0, please use getBottomBoundary instead. * @returns {number} */ - getBottomInParent: function(){ + getBottomInParent: function () { cc.log("getBottomInParent is deprecated. Please use getBottomBoundary instead."); return this.getBottomBoundary(); }, @@ -1545,7 +1565,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @deprecated since v3.0, please use getRightBoundary instead. * @returns {number} */ - getRightInParent: function(){ + getRightInParent: function () { cc.log("getRightInParent is deprecated. Please use getRightBoundary instead."); return this.getRightBoundary(); }, @@ -1555,7 +1575,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @deprecated since v3.0, please use getTopBoundary instead. * @returns {number} */ - getTopInParent: function(){ + getTopInParent: function () { cc.log("getTopInParent is deprecated. Please use getTopBoundary instead."); return this.getTopBoundary(); }, @@ -1672,6 +1692,14 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ cc.arrayRemoveObject(this._nodes, node); }, + _getNormalGLProgram: function () { + return cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR); + }, + + _getGrayGLProgram: function () { + return cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR_GRAY); + }, + /** * Removes node by tag * @deprecated since v3.0, please use removeChildByTag instead. @@ -1698,14 +1726,14 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ this._nodes.length = 0; }, - _findLayout: function(){ + _findLayout: function () { cc.renderer.childrenOrderDirty = true; var layout = this._parent; - while(layout){ - if(layout._doLayout){ + while (layout) { + if (layout._doLayout) { layout._doLayoutDirty = true; break; - }else + } else layout = layout._parent; } }, @@ -1733,42 +1761,42 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @since v3.3 * @param {function} callback */ - addCCSEventListener: function(callback){ + addCCSEventListener: function (callback) { this._ccEventCallback = callback; }, //override the scale functions. - setScaleX: function(scaleX){ + setScaleX: function (scaleX) { if (this._flippedX) scaleX = scaleX * -1; cc.Node.prototype.setScaleX.call(this, scaleX); }, - setScaleY: function(scaleY){ + setScaleY: function (scaleY) { if (this._flippedY) scaleY = scaleY * -1; cc.Node.prototype.setScaleY.call(this, scaleY); }, - setScale: function(scaleX, scaleY){ - if(scaleY === undefined) + setScale: function (scaleX, scaleY) { + if (scaleY === undefined) scaleY = scaleX; this.setScaleX(scaleX); this.setScaleY(scaleY); }, - getScaleX: function(){ + getScaleX: function () { var originalScale = cc.Node.prototype.getScaleX.call(this); if (this._flippedX) originalScale = originalScale * -1.0; return originalScale; }, - getScaleY: function(){ + getScaleY: function () { var originalScale = cc.Node.prototype.getScaleY.call(this); if (this._flippedY) originalScale = originalScale * -1.0; return originalScale; }, - getScale: function(){ - if(this.getScaleX() !== this.getScaleY()) + getScale: function () { + if (this.getScaleX() !== this.getScaleY()) cc.log("Widget#scale. ScaleX != ScaleY. Don't know which one to return"); return this.getScaleX(); }, @@ -1778,7 +1806,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @since v3.3 * @param {String} callbackName */ - setCallbackName: function(callbackName){ + setCallbackName: function (callbackName) { this._callbackName = callbackName; }, @@ -1787,7 +1815,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @since v3.3 * @returns {String|Null} */ - getCallbackName: function(){ + getCallbackName: function () { return this._callbackName; }, @@ -1796,7 +1824,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @since v3.3 * @param {String} callbackType */ - setCallbackType: function(callbackType){ + setCallbackType: function (callbackType) { this._callbackType = callbackType; }, @@ -1805,7 +1833,7 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ * @since v3.3 * @returns {String|null} */ - getCallbackType: function(){ + getCallbackType: function () { return this._callbackType; }, @@ -1827,8 +1855,8 @@ ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{ }, - _createRenderCmd: function(){ - if(cc._renderType === cc._RENDER_TYPE_WEBGL) + _createRenderCmd: function () { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new ccui.Widget.WebGLRenderCmd(this); else return new ccui.Widget.CanvasRenderCmd(this); @@ -1903,8 +1931,8 @@ ccui.Widget._focusNavigationController = null; * @note it doesn't implemented on Web * @param {Boolean} enable set true to enable dpad focus navigation, otherwise disable dpad focus navigation */ -ccui.Widget.enableDpadNavigation = function(enable){ - if (enable){ +ccui.Widget.enableDpadNavigation = function (enable) { + if (enable) { if (null == ccui.Widget._focusNavigationController) { ccui.Widget._focusNavigationController = new ccui._FocusNavigationController(); if (ccui.Widget._focusedWidget) { @@ -1913,7 +1941,7 @@ ccui.Widget.enableDpadNavigation = function(enable){ } ccui.Widget._focusNavigationController.enableFocusNavigation(true); } else { - if(ccui.Widget._focusNavigationController){ + if (ccui.Widget._focusNavigationController) { ccui.Widget._focusNavigationController.enableFocusNavigation(false); ccui.Widget._focusNavigationController = null; } @@ -1925,7 +1953,7 @@ ccui.Widget.enableDpadNavigation = function(enable){ * @function * @returns {null|ccui.Widget} */ -ccui.Widget.getCurrentFocusedWidget = function(){ +ccui.Widget.getCurrentFocusedWidget = function () { return ccui.Widget._focusedWidget; }; diff --git a/extensions/ccui/base-classes/UIWidgetRenderCmd.js b/extensions/ccui/base-classes/UIWidgetRenderCmd.js index 3faca0b751..fca76f9735 100644 --- a/extensions/ccui/base-classes/UIWidgetRenderCmd.js +++ b/extensions/ccui/base-classes/UIWidgetRenderCmd.js @@ -22,10 +22,10 @@ THE SOFTWARE. ****************************************************************************/ -if (cc._renderType === cc._RENDER_TYPE_CANVAS) { - (function () { +cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { + if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { ccui.Widget.CanvasRenderCmd = function (renderable) { - cc.ProtectedNode.CanvasRenderCmd.call(this, renderable); + this._pNodeCmdCtor(renderable); this._needDraw = false; }; @@ -33,17 +33,29 @@ if (cc._renderType === cc._RENDER_TYPE_CANVAS) { proto.constructor = ccui.Widget.CanvasRenderCmd; proto.visit = function (parentCmd) { - var node = this._node; - if (node._visible) { - node._adaptRenderers(); - cc.ProtectedNode.CanvasRenderCmd.prototype.visit.call(this, 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; } + + node._adaptRenderers(); + this._syncStatus(parentCmd); }; proto.transform = function (parentCmd, recursive) { - var node = this._node; + 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}; + } - if (node._visible) { + var node = this._node; + if (node._visible && node._running) { node._adaptRenderers(); if(!this._usingLayoutComponent){ var widgetParent = node.getWidgetParent(); @@ -55,14 +67,14 @@ if (cc._renderType === cc._RENDER_TYPE_CANVAS) { } } } - cc.ProtectedNode.CanvasRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.pNodeTransform(parentCmd, recursive); } }; - })(); -} else { - (function () { + + proto.widgetTransform = proto.transform; + } else { ccui.Widget.WebGLRenderCmd = function (renderable) { - cc.ProtectedNode.WebGLRenderCmd.call(this, renderable); + this._pNodeCmdCtor(renderable); this._needDraw = false; }; @@ -70,16 +82,29 @@ if (cc._renderType === cc._RENDER_TYPE_CANVAS) { proto.constructor = ccui.Widget.WebGLRenderCmd; proto.visit = function (parentCmd) { - var node = this._node; - if (node._visible) { - node._adaptRenderers(); - cc.ProtectedNode.WebGLRenderCmd.prototype.visit.call(this, 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; } + + node._adaptRenderers(); + this._syncStatus(parentCmd); }; - proto.transform = function(parentCmd, recursive){ + proto.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; - if (node._visible) { + if (node._visible && node._running) { node._adaptRenderers(); if(!this._usingLayoutComponent) { @@ -92,9 +117,10 @@ if (cc._renderType === cc._RENDER_TYPE_CANVAS) { } } } - cc.ProtectedNode.WebGLRenderCmd.prototype.transform.call(this, parentCmd, recursive); + this.pNodeTransform(parentCmd, recursive); } }; - })(); -} + proto.widgetTransform = proto.transform; + } +}); diff --git a/extensions/ccui/layouts/UIHBox.js b/extensions/ccui/layouts/UIHBox.js index 4e32002dd4..f808668c22 100644 --- a/extensions/ccui/layouts/UIHBox.js +++ b/extensions/ccui/layouts/UIHBox.js @@ -35,37 +35,12 @@ ccui.HBox = ccui.Layout.extend(/** @lends ccui.HBox# */{ * @param {cc.Size} [size] */ ctor: function(size){ - ccui.Layout.prototype.ctor.call(this, size); - if(size !== undefined) - this.initWithSize(size); - else - this.init(); - }, + ccui.Layout.prototype.ctor.call(this); + this.setLayoutType(ccui.Layout.LINEAR_HORIZONTAL); - /** - * Initialize a HBox. please do not call this function by yourself, you should pass the parameters to constructor to initialize it. - * @override - * @returns {boolean} - */ - init: function(){ - if(ccui.Layout.prototype.init.call(this)){ - this.setLayoutType(ccui.Layout.LINEAR_HORIZONTAL); - return true; - } - return false; - }, - - /** - * Initializes a HBox with size. - * @param size - * @returns {boolean} - */ - initWithSize: function(size){ - if(this.init()){ + if(size) { this.setContentSize(size); - return true; } - return false; } }); diff --git a/extensions/ccui/layouts/UILayout.js b/extensions/ccui/layouts/UILayout.js index 7768e12cf2..34361aa8a9 100644 --- a/extensions/ccui/layouts/UILayout.js +++ b/extensions/ccui/layouts/UILayout.js @@ -63,11 +63,11 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ _finalPositionX: 0, _finalPositionY: 0, - _backGroundImageOpacity:0, + _backGroundImageOpacity: 0, _loopFocus: false, //whether enable loop focus or not __passFocusToChild: true, //on default, it will pass the focus to the next nearest widget - _isFocusPassing:false, //when finding the next focused widget, use this variable to pass focus between layout & widget + _isFocusPassing: false, //when finding the next focused widget, use this variable to pass focus between layout & widget _isInterceptTouch: false, /** @@ -81,10 +81,16 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ ctor: function () { this._layoutType = ccui.Layout.ABSOLUTE; this._widgetType = ccui.Widget.TYPE_CONTAINER; - this._clippingType = ccui.Layout.CLIPPING_STENCIL; + this._clippingType = ccui.Layout.CLIPPING_SCISSOR; this._colorType = ccui.Layout.BG_COLOR_NONE; ccui.Widget.prototype.ctor.call(this); + + this.ignoreContentAdaptWithSize(false); + this.setContentSize(cc.size(0, 0)); + this.setAnchorPoint(0, 0); + this.onPassFocusToChild = this._findNearestChildWidgetIndex.bind(this); + this._backGroundImageCapInsets = cc.rect(0, 0, 0, 0); this._color = cc.color(255, 255, 255, 255); @@ -101,10 +107,10 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * Calls its parent's onEnter, and calls its clippingStencil's onEnter if clippingStencil isn't null. * @override */ - onEnter: function(){ + onEnter: function () { ccui.Widget.prototype.onEnter.call(this); if (this._clippingStencil) - this._clippingStencil.onEnter(); + this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onEnter); this._doLayoutDirty = true; this._clippingRectDirty = true; }, @@ -113,17 +119,91 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * Calls its parent's onExit, and calls its clippingStencil's onExit if clippingStencil isn't null. * @override */ - onExit: function(){ + onExit: function () { ccui.Widget.prototype.onExit.call(this); if (this._clippingStencil) - this._clippingStencil.onExit(); + this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onExit); + }, + + /** + *
+ * Calls adaptRenderers (its subclass will override it.) and do layout. + * If clippingEnabled is true, it will clip/scissor area. + *
+ * @override + * @param {cc.Node} [parent] + */ + visit: function (parent) { + var cmd = this._renderCmd, parentCmd = parent ? parent._renderCmd : null; + + // quick return if not visible + if (!this._visible) { + cmd._propagateFlagsDown(parentCmd); + return; + } + + this._adaptRenderers(); + this._doLayout(); + + var renderer = cc.renderer; + cmd.visit(parentCmd); + + var stencilClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_STENCIL; + var scissorClipping = this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_SCISSOR; + + if (stencilClipping) { + cmd.stencilClippingVisit(parentCmd); + } + else if (scissorClipping) { + cmd.scissorClippingVisit(parentCmd); + } + + var i, children = this._children, len = children.length, child; + var j, pChildren = this._protectedChildren, pLen = pChildren.length, pChild; + + if (this._reorderChildDirty) this.sortAllChildren(); + if (this._reorderProtectedChildDirty) this.sortAllProtectedChildren(); + // draw children zOrder < 0 + for (i = 0; i < len; i++) { + child = children[i]; + if (child._localZOrder < 0) { + child.visit(this); + } + else break; + } + for (j = 0; j < pLen; j++) { + pChild = pChildren[j]; + if (pChild._localZOrder < 0) { + cmd._changeProtectedChild(pChild); + pChild.visit(this); + } + else break; + } + // draw children zOrder >= 0 + for (; i < len; i++) { + children[i].visit(this); + } + for (; j < pLen; j++) { + pChild = pChildren[j]; + cmd._changeProtectedChild(pChild); + pChild.visit(this); + } + + if (stencilClipping) { + cmd.postStencilVisit(); + } + else if (scissorClipping) { + cmd.postScissorVisit(); + } + + cmd._dirtyFlag = 0; }, /** * If a layout is loop focused which means that the focus movement will be inside the layout * @param {Boolean} loop pass true to let the focus movement loop inside the layout */ - setLoopFocus: function(loop){ + setLoopFocus: function (loop) { this._loopFocus = loop; }, @@ -131,7 +211,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * Gets whether enable focus loop * @returns {boolean} If focus loop is enabled, then it will return true, otherwise it returns false. The default value is false. */ - isLoopFocus: function(){ + isLoopFocus: function () { return this._loopFocus; }, @@ -139,7 +219,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * Specifies whether the layout pass its focus to its child * @param pass To specify whether the layout pass its focus to its child */ - setPassFocusToChild: function(pass){ + setPassFocusToChild: function (pass) { this.__passFocusToChild = pass; }, @@ -147,7 +227,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * Returns whether the layout will pass the focus to its children or not. The default value is true * @returns {boolean} To query whether the layout will pass the focus to its children or not. The default value is true */ - isPassFocusToChild: function(){ + isPassFocusToChild: function () { return this.__passFocusToChild; }, @@ -158,7 +238,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @param {ccui.Widget} current the current focused widget * @returns {ccui.Widget} return the index of widget in the layout */ - findNextFocusedWidget: function(direction, current){ + findNextFocusedWidget: function (direction, current) { if (this._isFocusPassing || this.isFocused()) { var parent = this.getParent(); this._isFocusPassing = false; @@ -175,31 +255,31 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ return this; parent._isFocusPassing = true; return parent.findNextFocusedWidget(direction, this); - } else if(current.isFocused() || current instanceof ccui.Layout) { + } else if (current.isFocused() || current instanceof ccui.Layout) { if (this._layoutType === ccui.Layout.LINEAR_HORIZONTAL) { - switch (direction){ + switch (direction) { case ccui.Widget.LEFT: return this._getPreviousFocusedWidget(direction, current); - break; + break; case ccui.Widget.RIGHT: return this._getNextFocusedWidget(direction, current); - break; + break; case ccui.Widget.DOWN: case ccui.Widget.UP: - if (this._isLastWidgetInContainer(this, direction)){ + if (this._isLastWidgetInContainer(this, direction)) { if (this._isWidgetAncestorSupportLoopFocus(current, direction)) return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this); return current; } else { return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this); } - break; + break; default: cc.assert(0, "Invalid Focus Direction"); return current; } } else if (this._layoutType === ccui.Layout.LINEAR_VERTICAL) { - switch (direction){ + switch (direction) { case ccui.Widget.LEFT: case ccui.Widget.RIGHT: if (this._isLastWidgetInContainer(this, direction)) { @@ -209,7 +289,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ } else return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this); - break; + break; case ccui.Widget.DOWN: return this._getNextFocusedWidget(direction, current); break; @@ -236,22 +316,6 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ */ onPassFocusToChild: null, - /** - * override "init" method of widget. please do not call this function by yourself, you should pass the parameters to constructor to initialize it. - * @returns {boolean} - * @override - */ - init: function () { - if (ccui.Widget.prototype.init.call(this)) { - this.ignoreContentAdaptWithSize(false); - this.setContentSize(cc.size(0, 0)); - this.setAnchorPoint(0, 0); - this.onPassFocusToChild = this._findNearestChildWidgetIndex.bind(this); - return true; - } - return false; - }, - /** * Adds a widget to the container. * @param {ccui.Widget} widget @@ -292,7 +356,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * and sets the layout dirty flag to true. * @param {Boolean} cleanup true if all running actions on all children nodes should be cleanup, false otherwise. */ - removeAllChildrenWithCleanup: function(cleanup){ + removeAllChildrenWithCleanup: function (cleanup) { ccui.Widget.prototype.removeAllChildrenWithCleanup.call(this, cleanup); this._doLayoutDirty = true; }, @@ -305,35 +369,6 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ return this._clippingEnabled; }, - /** - *- * Calls adaptRenderers (its subclass will override it.) and do layout. - * If clippingEnabled is true, it will clip/scissor area. - *
- * @override - * @param {cc.Node.RenderCmd} [parentCmd] - */ - visit: function (parentCmd) { - if (!this._visible) - return; - this._adaptRenderers(); - this._doLayout(); - - if (this._clippingEnabled) { - switch (this._clippingType) { - case ccui.Layout.CLIPPING_STENCIL: - this._renderCmd.stencilClippingVisit(parentCmd); - break; - case ccui.Layout.CLIPPING_SCISSOR: - this._renderCmd.scissorClippingVisit(parentCmd); - break; - default: - break; - } - } else - ccui.Widget.prototype.visit.call(this, parentCmd); - }, - /** * Changes if layout can clip it's content and locChild. * If you really need this, please enable it. But it would reduce the rendering efficiency. @@ -344,16 +379,17 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ return; this._clippingEnabled = able; switch (this._clippingType) { + case ccui.Layout.CLIPPING_SCISSOR: case ccui.Layout.CLIPPING_STENCIL: - if (able){ + if (able) { this._clippingStencil = new cc.DrawNode(); this._renderCmd.rebindStencilRendering(this._clippingStencil); if (this._running) - this._clippingStencil.onEnter(); + this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onEnter); this._setStencilClippingSize(this._contentSize); } else { if (this._running && this._clippingStencil) - this._clippingStencil.onExit(); + this._clippingStencil._performRecursive(cc.Node._stateCallbackType.onExit); this._clippingStencil = null; } break; @@ -369,10 +405,6 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ setClippingType: function (type) { if (type === this._clippingType) return; - if(cc._renderType === cc._RENDER_TYPE_CANVAS && type === ccui.Layout.CLIPPING_SCISSOR){ - cc.log("Only supports STENCIL on canvas mode."); - return; - } var clippingEnabled = this.isClippingEnabled(); this.setClippingEnabled(false); this._clippingType = type; @@ -388,7 +420,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ }, _setStencilClippingSize: function (size) { - if (this._clippingEnabled && this._clippingType === ccui.Layout.CLIPPING_STENCIL) { + if (this._clippingEnabled) { var rect = []; rect[0] = cc.p(0, 0); rect[1] = cc.p(size.width, 0); @@ -396,6 +428,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ rect[3] = cc.p(0, size.height); var green = cc.color.GREEN; this._clippingStencil.clear(); + this._clippingStencil.setLocalBB && this._clippingStencil.setLocalBB(0, 0, size.width, size.height); this._clippingStencil.drawPoly(rect, 4, green, 0, green); } }, @@ -419,38 +452,18 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ if (this._clippingParent) { parentClippingRect = this._clippingParent._getClippingRect(); - var finalX = worldPos.x - (scissorWidth * this._anchorPoint.x); - var finalY = worldPos.y - (scissorHeight * this._anchorPoint.y); - var finalWidth = scissorWidth; - var finalHeight = scissorHeight; - - var leftOffset = worldPos.x - parentClippingRect.x; - if (leftOffset < 0) { - finalX = parentClippingRect.x; - finalWidth += leftOffset; - } - var rightOffset = (worldPos.x + scissorWidth) - (parentClippingRect.x + parentClippingRect.width); - if (rightOffset > 0) - finalWidth -= rightOffset; - var topOffset = (worldPos.y + scissorHeight) - (parentClippingRect.y + parentClippingRect.height); - if (topOffset > 0) - finalHeight -= topOffset; - var bottomOffset = worldPos.y - parentClippingRect.y; - if (bottomOffset < 0) { - finalY = parentClippingRect.x; - finalHeight += bottomOffset; - } - if (finalWidth < 0) - finalWidth = 0; - if (finalHeight < 0) - finalHeight = 0; - this._clippingRect.x = finalX; - this._clippingRect.y = finalY; - this._clippingRect.width = finalWidth; - this._clippingRect.height = finalHeight; + + this._clippingRect.x = Math.max(worldPos.x, parentClippingRect.x); + this._clippingRect.y = Math.max(worldPos.y, parentClippingRect.y); + + var right = Math.min(worldPos.x + scissorWidth, parentClippingRect.x + parentClippingRect.width); + var top = Math.min(worldPos.y + scissorHeight, parentClippingRect.y + parentClippingRect.height); + + this._clippingRect.width = Math.max(0.0, right - this._clippingRect.x); + this._clippingRect.height = Math.max(0.0, top - this._clippingRect.y); } else { - this._clippingRect.x = worldPos.x - (scissorWidth * this._anchorPoint.x); - this._clippingRect.y = worldPos.y - (scissorHeight * this._anchorPoint.y); + this._clippingRect.x = worldPos.x; + this._clippingRect.y = worldPos.y; this._clippingRect.width = scissorWidth; this._clippingRect.height = scissorHeight; } @@ -508,7 +521,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ if (!fileName) return; texType = texType || ccui.Widget.LOCAL_TEXTURE; - if (this._backGroundImage === null){ + if (this._backGroundImage === null) { this._addBackGroundImage(); this.setBackGroundImageScale9Enabled(this._backGroundScale9Enabled); } @@ -538,7 +551,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @param {cc.Rect} capInsets capinsets of background image. */ setBackGroundImageCapInsets: function (capInsets) { - if(!capInsets) + if (!capInsets) return; var locInsets = this._backGroundImageCapInsets; locInsets.x = capInsets.x; @@ -811,7 +824,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ }, _updateBackGroundImageColor: function () { - if(this._backGroundImage) + if (this._backGroundImage) this._backGroundImage.setColor(this._backGroundImageColor); }, @@ -833,7 +846,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ var locChild = null; for (var i = 0; i < layoutChildrenArray.length; i++) { locChild = layoutChildrenArray[i]; - if(locChild instanceof ccui.Widget) + if (locChild instanceof ccui.Widget) this._supplyTheLayoutParameterLackToChild(locChild); } this._doLayoutDirty = true; @@ -866,20 +879,20 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ this._doLayoutDirty = false; }, - _getLayoutContentSize: function(){ + _getLayoutContentSize: function () { return this.getContentSize(); }, - _getLayoutElements: function(){ + _getLayoutElements: function () { return this.getChildren(); }, - _updateBackGroundImageOpacity: function(){ + _updateBackGroundImageOpacity: function () { if (this._backGroundImage) this._backGroundImage.setOpacity(this._backGroundImageOpacity); }, - _updateBackGroundImageRGBA: function(){ + _updateBackGroundImageRGBA: function () { if (this._backGroundImage) { this._backGroundImage.setColor(this._backGroundImageColor); this._backGroundImage.setOpacity(this._backGroundImageOpacity); @@ -891,13 +904,13 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {cc.Size} * @private */ - _getLayoutAccumulatedSize: function(){ + _getLayoutAccumulatedSize: function () { var children = this.getChildren(); - var layoutSize = cc.size(0, 0); + var layoutSize = cc.size(0, 0); var widgetCount = 0, locSize; - for(var i = 0, len = children.length; i < len; i++) { + for (var i = 0, len = children.length; i < len; i++) { var layout = children[i]; - if (null !== layout && layout instanceof ccui.Layout){ + if (null !== layout && layout instanceof ccui.Layout) { locSize = layout._getLayoutAccumulatedSize(); layoutSize.width += locSize.width; layoutSize.height += locSize.height; @@ -906,8 +919,8 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ widgetCount++; var m = layout.getLayoutParameter().getMargin(); locSize = layout.getContentSize(); - layoutSize.width += locSize.width + (m.right + m.left) * 0.5; - layoutSize.height += locSize.height + (m.top + m.bottom) * 0.5; + layoutSize.width += locSize.width + (m.right + m.left) * 0.5; + layoutSize.height += locSize.height + (m.top + m.bottom) * 0.5; } } } @@ -915,10 +928,10 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ //substract extra size var type = this.getLayoutType(); if (type === ccui.Layout.LINEAR_HORIZONTAL) - layoutSize.height = layoutSize.height - layoutSize.height/widgetCount * (widgetCount-1); + layoutSize.height = layoutSize.height - layoutSize.height / widgetCount * (widgetCount - 1); if (type === ccui.Layout.LINEAR_VERTICAL) - layoutSize.width = layoutSize.width - layoutSize.width/widgetCount * (widgetCount-1); + layoutSize.width = layoutSize.width - layoutSize.width / widgetCount * (widgetCount - 1); return layoutSize; }, @@ -930,7 +943,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {Number} * @private */ - _findNearestChildWidgetIndex: function(direction, baseWidget){ + _findNearestChildWidgetIndex: function (direction, baseWidget) { if (baseWidget == null || baseWidget === this) return this._findFirstFocusEnabledWidgetIndex(); @@ -943,9 +956,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ while (index < count) { var w = locChildren[index]; if (w && w instanceof ccui.Widget && w.isFocusEnabled()) { - var length = (w instanceof ccui.Layout)? w._calculateNearestDistance(baseWidget) + var length = (w instanceof ccui.Layout) ? w._calculateNearestDistance(baseWidget) : cc.pLength(cc.pSub(this._getWorldCenterPoint(w), widgetPosition)); - if (length < distance){ + if (length < distance) { found = index; distance = length; } @@ -966,7 +979,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {Number} The index of child widget in the container * @private */ - _findFarthestChildWidgetIndex: function(direction, baseWidget){ + _findFarthestChildWidgetIndex: function (direction, baseWidget) { if (baseWidget == null || baseWidget === this) return this._findFirstFocusEnabledWidgetIndex(); @@ -975,20 +988,20 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ var distance = -cc.FLT_MAX, found = 0; if (direction === ccui.Widget.LEFT || direction === ccui.Widget.RIGHT || direction === ccui.Widget.DOWN || direction === ccui.Widget.UP) { - var widgetPosition = this._getWorldCenterPoint(baseWidget); - while (index < count) { + var widgetPosition = this._getWorldCenterPoint(baseWidget); + while (index < count) { var w = locChildren[index]; if (w && w instanceof ccui.Widget && w.isFocusEnabled()) { - var length = (w instanceof ccui.Layout)?w._calculateFarthestDistance(baseWidget) + var length = (w instanceof ccui.Layout) ? w._calculateFarthestDistance(baseWidget) : cc.pLength(cc.pSub(this._getWorldCenterPoint(w), widgetPosition)); - if (length > distance){ + if (length > distance) { found = index; distance = length; } } index++; } - return found; + return found; } cc.log("invalid focus direction!!!"); return 0; @@ -1000,9 +1013,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {Number} return the nearest distance between the baseWidget and the layout's children * @private */ - _calculateNearestDistance: function(baseWidget){ + _calculateNearestDistance: function (baseWidget) { var distance = cc.FLT_MAX; - var widgetPosition = this._getWorldCenterPoint(baseWidget); + var widgetPosition = this._getWorldCenterPoint(baseWidget); var locChildren = this._children; for (var i = 0, len = locChildren.length; i < len; i++) { @@ -1027,9 +1040,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {number} * @private */ - _calculateFarthestDistance:function(baseWidget){ + _calculateFarthestDistance: function (baseWidget) { var distance = -cc.FLT_MAX; - var widgetPosition = this._getWorldCenterPoint(baseWidget); + var widgetPosition = this._getWorldCenterPoint(baseWidget); var locChildren = this._children; for (var i = 0, len = locChildren.length; i < len; i++) { @@ -1057,25 +1070,25 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @param baseWidget * @private */ - _findProperSearchingFunctor: function(direction, baseWidget){ - if (baseWidget == null) + _findProperSearchingFunctor: function (direction, baseWidget) { + if (baseWidget === undefined) return; var previousWidgetPosition = this._getWorldCenterPoint(baseWidget); var widgetPosition = this._getWorldCenterPoint(this._findFirstNonLayoutWidget()); if (direction === ccui.Widget.LEFT) { - this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findNearestChildWidgetIndex.bind(this) - : this._findFarthestChildWidgetIndex.bind(this); + this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findNearestChildWidgetIndex + : this._findFarthestChildWidgetIndex; } else if (direction === ccui.Widget.RIGHT) { - this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findFarthestChildWidgetIndex.bind(this) - : this._findNearestChildWidgetIndex.bind(this); - }else if(direction === ccui.Widget.DOWN) { - this.onPassFocusToChild = (previousWidgetPosition.y > widgetPosition.y) ? this._findNearestChildWidgetIndex.bind(this) - : this._findFarthestChildWidgetIndex.bind(this); - }else if(direction === ccui.Widget.UP) { - this.onPassFocusToChild = (previousWidgetPosition.y < widgetPosition.y) ? this._findNearestChildWidgetIndex.bind(this) - : this._findFarthestChildWidgetIndex.bind(this); - }else + this.onPassFocusToChild = (previousWidgetPosition.x > widgetPosition.x) ? this._findFarthestChildWidgetIndex + : this._findNearestChildWidgetIndex; + } else if (direction === ccui.Widget.DOWN) { + this.onPassFocusToChild = (previousWidgetPosition.y > widgetPosition.y) ? this._findNearestChildWidgetIndex + : this._findFarthestChildWidgetIndex; + } else if (direction === ccui.Widget.UP) { + this.onPassFocusToChild = (previousWidgetPosition.y < widgetPosition.y) ? this._findNearestChildWidgetIndex + : this._findFarthestChildWidgetIndex; + } else cc.log("invalid direction!"); }, @@ -1084,15 +1097,15 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {ccui.Widget} * @private */ - _findFirstNonLayoutWidget:function(){ + _findFirstNonLayoutWidget: function () { var locChildren = this._children; - for(var i = 0, len = locChildren.length; i < len; i++) { + for (var i = 0, len = locChildren.length; i < len; i++) { var child = locChildren[i]; - if (child instanceof ccui.Layout){ + if (child instanceof ccui.Layout) { var widget = child._findFirstNonLayoutWidget(); - if(widget) + if (widget) return widget; - } else{ + } else { if (child instanceof ccui.Widget) return child; } @@ -1105,7 +1118,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {number} * @private */ - _findFirstFocusEnabledWidgetIndex: function(){ + _findFirstFocusEnabledWidgetIndex: function () { var index = 0, locChildren = this.getChildren(); var count = locChildren.length; while (index < count) { @@ -1123,9 +1136,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {*} * @private */ - _findFocusEnabledChildWidgetByIndex: function(index){ + _findFocusEnabledChildWidgetByIndex: function (index) { var widget = this._getChildWidgetByIndex(index); - if (widget){ + if (widget) { if (widget.isFocusEnabled()) return widget; index = index + 1; @@ -1140,10 +1153,10 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {cc.Point} * @private */ - _getWorldCenterPoint: function(widget){ + _getWorldCenterPoint: function (widget) { //FIXEDME: we don't need to calculate the content size of layout anymore - var widgetSize = widget instanceof ccui.Layout ? widget._getLayoutAccumulatedSize() : widget.getContentSize(); - return widget.convertToWorldSpace(cc.p(widgetSize.width /2, widgetSize.height /2)); + var widgetSize = widget instanceof ccui.Layout ? widget._getLayoutAccumulatedSize() : widget.getContentSize(); + return widget.convertToWorldSpace(cc.p(widgetSize.width / 2, widgetSize.height / 2)); }, /** @@ -1153,9 +1166,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {ccui.Widget} the next focused widget * @private */ - _getNextFocusedWidget: function(direction, current){ + _getNextFocusedWidget: function (direction, current) { var nextWidget = null, locChildren = this._children; - var previousWidgetPos = locChildren.indexOf(current); + var previousWidgetPos = locChildren.indexOf(current); previousWidgetPos = previousWidgetPos + 1; if (previousWidgetPos < locChildren.length) { nextWidget = this._getChildWidgetByIndex(previousWidgetPos); @@ -1190,8 +1203,8 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ return this._getNextFocusedWidget(direction, nextWidget); } else return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget; - } else{ - if (this._isLastWidgetInContainer(current, direction)){ + } else { + if (this._isLastWidgetInContainer(current, direction)) { if (this._isWidgetAncestorSupportLoopFocus(this, direction)) return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, this); return (current instanceof ccui.Layout) ? current : ccui.Widget._focusedWidget; @@ -1208,14 +1221,14 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {ccui.Widget} the next focused widget * @private */ - _getPreviousFocusedWidget: function(direction, current){ + _getPreviousFocusedWidget: function (direction, current) { var nextWidget = null, locChildren = this._children; var previousWidgetPos = locChildren.indexOf(current); previousWidgetPos = previousWidgetPos - 1; - if (previousWidgetPos >= 0){ + if (previousWidgetPos >= 0) { nextWidget = this._getChildWidgetByIndex(previousWidgetPos); if (nextWidget.isFocusEnabled()) { - if (nextWidget instanceof ccui.Layout){ + if (nextWidget instanceof ccui.Layout) { nextWidget._isFocusPassing = true; return nextWidget.findNextFocusedWidget(direction, nextWidget); } @@ -1223,13 +1236,13 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ return nextWidget; } else return this._getPreviousFocusedWidget(direction, nextWidget); //handling the disabled widget, there is no actual focus lose or get, so we don't need any envet - }else { - if (this._loopFocus){ + } else { + if (this._loopFocus) { if (this._checkFocusEnabledChild()) { - previousWidgetPos = locChildren.length -1; + previousWidgetPos = locChildren.length - 1; nextWidget = this._getChildWidgetByIndex(previousWidgetPos); - if (nextWidget.isFocusEnabled()){ - if (nextWidget instanceof ccui.Layout){ + if (nextWidget.isFocusEnabled()) { + if (nextWidget instanceof ccui.Layout) { nextWidget._isFocusPassing = true; return nextWidget.findNextFocusedWidget(direction, nextWidget); } else { @@ -1286,7 +1299,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {Boolean} * @private */ - _isLastWidgetInContainer:function(widget, direction){ + _isLastWidgetInContainer: function (widget, direction) { var parent = widget.getParent(); if (parent == null || !(parent instanceof ccui.Layout)) return true; @@ -1311,8 +1324,8 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ if (direction === ccui.Widget.UP) return this._isLastWidgetInContainer(parent, direction); - } else if(parent.getLayoutType() === ccui.Layout.LINEAR_VERTICAL){ - if (direction === ccui.Widget.UP){ + } else if (parent.getLayoutType() === ccui.Layout.LINEAR_VERTICAL) { + if (direction === ccui.Widget.UP) { if (index === 0) return this._isLastWidgetInContainer(parent, direction); else @@ -1342,7 +1355,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {Boolean} * @private */ - _isWidgetAncestorSupportLoopFocus: function(widget, direction){ + _isWidgetAncestorSupportLoopFocus: function (widget, direction) { var parent = widget.getParent(); if (parent == null || !(parent instanceof ccui.Layout)) return false; @@ -1354,12 +1367,12 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ else return this._isWidgetAncestorSupportLoopFocus(parent, direction); } - if (layoutType === ccui.Layout.LINEAR_VERTICAL){ + if (layoutType === ccui.Layout.LINEAR_VERTICAL) { if (direction === ccui.Widget.DOWN || direction === ccui.Widget.UP) return true; else return this._isWidgetAncestorSupportLoopFocus(parent, direction); - } else{ + } else { cc.assert(0, "invalid layout type"); return false; } @@ -1374,7 +1387,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {ccui.Widget} * @private */ - _passFocusToChild: function(direction, current){ + _passFocusToChild: function (direction, current) { if (this._checkFocusEnabledChild()) { var previousWidget = ccui.Widget.getCurrentFocusedWidget(); this._findProperSearchingFunctor(direction, previousWidget); @@ -1388,7 +1401,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ this.dispatchFocusEvent(current, widget); return widget; } - }else + } else return this; }, @@ -1397,9 +1410,9 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ * @returns {boolean} * @private */ - _checkFocusEnabledChild: function(){ + _checkFocusEnabledChild: function () { var locChildren = this._children; - for(var i = 0, len = locChildren.length; i < len; i++){ + for (var i = 0, len = locChildren.length; i < len; i++) { var widget = locChildren[i]; if (widget && widget instanceof ccui.Widget && widget.isFocusEnabled()) return true; @@ -1424,7 +1437,7 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ }, _copySpecialProperties: function (layout) { - if(!(layout instanceof ccui.Layout)) + if (!(layout instanceof ccui.Layout)) return; this.setBackGroundImageScale9Enabled(layout._backGroundScale9Enabled); this.setBackGroundImage(layout._backGroundImageFileName, layout._bgImageTexType); @@ -1445,13 +1458,13 @@ ccui.Layout = ccui.Widget.extend(/** @lends ccui.Layout# */{ /** * force refresh widget layout */ - forceDoLayout: function(){ + forceDoLayout: function () { this.requestDoLayout(); this._doLayout(); }, - _createRenderCmd: function(){ - if(cc._renderType === cc._RENDER_TYPE_WEBGL) + _createRenderCmd: function () { + if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) return new ccui.Layout.WebGLRenderCmd(this); else return new ccui.Layout.CanvasRenderCmd(this); @@ -1555,4 +1568,4 @@ ccui.Layout.BACKGROUND_IMAGE_ZORDER = -1; * @type {number} * @constant */ -ccui.Layout.BACKGROUND_RENDERER_ZORDER = -2; \ No newline at end of file +ccui.Layout.BACKGROUND_RENDERER_ZORDER = -2; diff --git a/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js b/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js index ed7f9950f9..7d847ccedd 100644 --- a/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js +++ b/extensions/ccui/layouts/UILayoutCanvasRenderCmd.js @@ -23,157 +23,81 @@ THE SOFTWARE. ****************************************************************************/ -(function(){ - ccui.Layout.CanvasRenderCmd = function(renderable){ - ccui.ProtectedNode.CanvasRenderCmd.call(this, renderable); +(function () { + ccui.Layout.CanvasRenderCmd = function (renderable) { + this._pNodeCmdCtor(renderable); this._needDraw = false; - this._clipElemType = false; - this._locCache = null; - this._rendererSaveCmd = new cc.CustomRenderCmd(this, this._onRenderSaveCmd); - this._rendererSaveCmdSprite = new cc.CustomRenderCmd(this, this._onRenderSaveSpriteCmd); - this._rendererClipCmd = new cc.CustomRenderCmd(this, this._onRenderClipCmd); - this._rendererRestoreCmd = new cc.CustomRenderCmd(this, this._onRenderRestoreCmd); + this._rendererSaveCmd = null; + this._rendererClipCmd = null; + this._rendererRestoreCmd = null; }; var proto = ccui.Layout.CanvasRenderCmd.prototype = Object.create(ccui.ProtectedNode.CanvasRenderCmd.prototype); proto.constructor = ccui.Layout.CanvasRenderCmd; + proto._layoutCmdCtor = ccui.Layout.CanvasRenderCmd; - proto.visit = function(parentCmd){ - var node = this._node; - if (!node._visible) - return; - node._adaptRenderers(); - node._doLayout(); - - if (node._clippingEnabled) { - switch (node._clippingType) { - case ccui.Layout.CLIPPING_STENCIL: - this.stencilClippingVisit(parentCmd); - break; - case ccui.Layout.CLIPPING_SCISSOR: - this.scissorClippingVisit(parentCmd); - break; - default: - break; - } - } else - ccui.Widget.CanvasRenderCmd.prototype.visit.call(this, parentCmd); - }; - - proto._onRenderSaveCmd = function(ctx, scaleX, scaleY){ + proto._onRenderSaveCmd = function (ctx, scaleX, scaleY) { var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - if (this._clipElemType) { - var canvas = context.canvas; - this._locCache = ccui.Layout.CanvasRenderCmd._getSharedCache(); - this._locCache.width = canvas.width; - this._locCache.height = canvas.height; - var locCacheCtx = this._locCache.getContext("2d"); - locCacheCtx.drawImage(canvas, 0, 0); - } else { - wrapper.save(); - wrapper.save(); - wrapper.setTransform(this._worldTransform, scaleX, scaleY); - } - }; + wrapper.save(); + wrapper.save(); + wrapper.setTransform(this._worldTransform, scaleX, scaleY); + var buffer = this._node._clippingStencil._renderCmd._buffer; - proto._onRenderSaveSpriteCmd = function(ctx){ - var wrapper = ctx || cc._renderContext; - //var node = this._node; - if (this._clipElemType) { - wrapper.setCompositeOperation("destination-in"); + for (var i = 0, bufLen = buffer.length; i < bufLen; i++) { + var element = buffer[i], vertices = element.verts; + var firstPoint = vertices[0]; + context.beginPath(); + context.moveTo(firstPoint.x, -firstPoint.y); + for (var j = 1, len = vertices.length; j < len; j++) + context.lineTo(vertices[j].x, -vertices[j].y); + context.closePath(); } }; - proto._onRenderClipCmd = function(ctx){ + proto._onRenderClipCmd = function (ctx) { var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - if (!this._clipElemType) { - wrapper.restore(); - context.clip(); - } + wrapper.restore(); + context.clip(); }; - proto._onRenderRestoreCmd = function(ctx){ + proto._onRenderRestoreCmd = function (ctx) { var wrapper = ctx || cc._renderContext, context = wrapper.getContext(); - if (this._clipElemType) { - // Redraw the cached canvas, so that the cliped area shows the background etc. - context.save(); - context.setTransform(1, 0, 0, 1, 0, 0); - context.globalCompositeOperation = "destination-over"; - context.drawImage(this._locCache, 0, 0); - context.restore(); - }else{ - wrapper.restore(); //use for restore clip operation - } + wrapper.restore(); }; - proto.rebindStencilRendering = function(stencil){ + proto.rebindStencilRendering = function (stencil) { stencil._renderCmd.rendering = this.__stencilDraw; + stencil._renderCmd._canUseDirtyRegion = true; }; - proto.__stencilDraw = function(ctx,scaleX, scaleY){ //Only for Canvas - var wrapper = ctx || cc._renderContext, locContext = wrapper.getContext(), buffer = this._buffer; - - for (var i = 0, bufLen = buffer.length; i < bufLen; i++) { - var element = buffer[i], vertices = element.verts; - var firstPoint = vertices[0]; - locContext.beginPath(); - locContext.moveTo(firstPoint.x * scaleX, -firstPoint.y * scaleY); - for (var j = 1, len = vertices.length; j < len; j++) - locContext.lineTo(vertices[j].x * scaleX, -vertices[j].y * scaleY); - locContext.closePath(); - } + proto.__stencilDraw = function (ctx, scaleX, scaleY) { //Only for Canvas + //do nothing, rendering in layout }; - proto.stencilClippingVisit = proto.scissorClippingVisit = function(parentCmd){ + proto.stencilClippingVisit = proto.scissorClippingVisit = function (parentCmd) { var node = this._node; if (!node._clippingStencil || !node._clippingStencil.isVisible()) return; - this._clipElemType = node._stencil instanceof cc.Sprite; - this._syncStatus(parentCmd); + if (!this._rendererSaveCmd) { + this._rendererSaveCmd = new cc.CustomRenderCmd(this, this._onRenderSaveCmd); + this._rendererClipCmd = new cc.CustomRenderCmd(this, this._onRenderClipCmd); + this._rendererRestoreCmd = new cc.CustomRenderCmd(this, this._onRenderRestoreCmd); + } cc.renderer.pushRenderCommand(this._rendererSaveCmd); - if (this._clipElemType) { - cc.ProtectedNode.prototype.visit.call(node, parentCmd); - cc.renderer.pushRenderCommand(this._rendererSaveCmdSprite); - } node._clippingStencil.visit(this); cc.renderer.pushRenderCommand(this._rendererClipCmd); - if (!this._clipElemType) { - node.sortAllChildren(); - node.sortAllProtectedChildren(); - - var children = node._children; - var j=0, locProtectChildren = node._protectedChildren, i = 0, locChild; - var iLen = children.length, jLen = locProtectChildren.length; - - for( ; i < iLen; i++ ){ - locChild = children[i]; - if ( locChild && locChild.getLocalZOrder() < 0 ) - locChild.visit(this); - else - break; - } - for( ; j < jLen; j++ ) { - locChild = locProtectChildren[j]; - if ( locChild && locChild.getLocalZOrder() < 0 ) - locChild.visit(this); - else - break; - } - for (; i < iLen; i++) - children[i].visit(this); - for (; j < jLen; j++) - locProtectChildren[j].visit(this); - cc.renderer.pushRenderCommand(this._rendererRestoreCmd); - } - this._dirtyFlag = 0; + }; + + proto.postStencilVisit = proto.postScissorVisit = function () { + cc.renderer.pushRenderCommand(this._rendererRestoreCmd); }; ccui.Layout.CanvasRenderCmd._getSharedCache = function () { - return (cc.ClippingNode._sharedCache) || (cc.ClippingNode._sharedCache = cc.newElement("canvas")); + return (cc.ClippingNode._sharedCache) || (cc.ClippingNode._sharedCache = document.createElement("canvas")); }; -})(); \ No newline at end of file +})(); diff --git a/extensions/ccui/layouts/UILayoutComponent.js b/extensions/ccui/layouts/UILayoutComponent.js index 96a9dbf3fa..3a910f690a 100644 --- a/extensions/ccui/layouts/UILayoutComponent.js +++ b/extensions/ccui/layouts/UILayoutComponent.js @@ -537,7 +537,16 @@ ccui.LayoutComponent = cc.Component.extend({ locOwner.setPosition(ownerPosition); locOwner.setContentSize(ownerSize); - ccui.helper.doLayout(locOwner); + if(locOwner instanceof ccui.PageView){ + locOwner.forceDoLayout(); + + var layoutVector = locOwner.getPages(); + for(var i=0; icc.EditBox is a brief Class for edit box.
* You can use this widget to gather small amounts of text from the user.
* Sets the maximum input length of the edit box.
* Setting this value enables multiline input mode by default.
- *
- * Returns the flag which indicates whether the widget is flipped horizontally or not.
- *
- * It only flips the texture of the widget, and not the texture of the widget's children.
- * Also, flipping the texture doesn't alter the anchorPoint.
- * If you want to flip the anchorPoint too, and/or to flip the children too use:
- * widget->setScaleX(sprite->getScaleX() * -1);
- *
- * Return the flag which indicates whether the widget is flipped vertically or not.
- *
- * It only flips the texture of the widget, and not the texture of the widget's children.
- * Also, flipping the texture doesn't alter the anchorPoint.
- * If you want to flip the anchorPoint too, and/or to flip the children too use:
- * widget->setScaleY(widget->getScaleY() * -1);
- *
idx property.
*/
- reset:function () {
+ reset: function () {
this._idx = cc.INVALID_INDEX;
},
- setObjectID:function (idx) {
+ setObjectID: function (idx) {
this._idx = idx;
},
- getObjectID:function () {
+ getObjectID: function () {
return this._idx;
}
});
@@ -94,7 +94,7 @@ cc.TableViewDelegate = cc.ScrollViewDelegate.extend(/** @lends cc.TableViewDeleg
* @param {cc.TableView} table table contains the given cell
* @param {cc.TableViewCell} cell cell that is touched
*/
- tableCellTouched:function (table, cell) {
+ tableCellTouched: function (table, cell) {
},
/**
@@ -103,7 +103,7 @@ cc.TableViewDelegate = cc.ScrollViewDelegate.extend(/** @lends cc.TableViewDeleg
* @param {cc.TableView} table table contains the given cell
* @param {cc.TableViewCell} cell cell that is pressed
*/
- tableCellHighlight:function(table, cell){
+ tableCellHighlight: function (table, cell) {
},
/**
@@ -112,7 +112,7 @@ cc.TableViewDelegate = cc.ScrollViewDelegate.extend(/** @lends cc.TableViewDeleg
* @param {cc.TableView} table table contains the given cell
* @param {cc.TableViewCell} cell cell that is pressed
*/
- tableCellUnhighlight:function(table, cell){
+ tableCellUnhighlight: function (table, cell) {
},
@@ -125,7 +125,7 @@ cc.TableViewDelegate = cc.ScrollViewDelegate.extend(/** @lends cc.TableViewDeleg
* @param table table contains the given cell
* @param cell cell that is pressed
*/
- tableCellWillRecycle:function(table, cell){
+ tableCellWillRecycle: function (table, cell) {
}
});
@@ -140,7 +140,7 @@ cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
* @param {Number} idx the index of a cell to get a size
* @return {cc.Size} size of a cell at given index
*/
- tableCellSizeForIndex:function(table, idx){
+ tableCellSizeForIndex: function (table, idx) {
return this.cellSizeForTable(table);
},
/**
@@ -149,8 +149,8 @@ cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
* @param {cc.TableView} table table to hold the instances of Class
* @return {cc.Size} cell size
*/
- cellSizeForTable:function (table) {
- return cc.size(0,0);
+ cellSizeForTable: function (table) {
+ return cc.size(0, 0);
},
/**
@@ -159,7 +159,7 @@ cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
* @param idx index to search for a cell
* @return {cc.TableView} cell found at idx
*/
- tableCellAtIndex:function (table, idx) {
+ tableCellAtIndex: function (table, idx) {
return null;
},
@@ -168,7 +168,7 @@ cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
* @param {cc.TableView} table table to hold the instances of Class
* @return {Number} number of cells
*/
- numberOfCellsInTableView:function (table) {
+ numberOfCellsInTableView: function (table) {
return 0;
}
});
@@ -186,14 +186,14 @@ cc.TableViewDataSource = cc.Class.extend(/** @lends cc.TableViewDataSource# */{
*
*/
cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
- _vOrdering:null,
- _indices:null,
- _cellsFreed:null,
- _dataSource:null,
- _tableViewDelegate:null,
- _oldDirection:null,
- _cellsPositions:null, //vector with all cell positions
- _touchedCell:null,
+ _vOrdering: null,
+ _indices: null,
+ _cellsFreed: null,
+ _dataSource: null,
+ _tableViewDelegate: null,
+ _oldDirection: null,
+ _cellsPositions: null, //vector with all cell positions
+ _touchedCell: null,
/**
* The
@@ -201,7 +201,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
* @param size
* @param container
*/
- ctor:function (dataSource, size, container) {
+ ctor: function (dataSource, size, container) {
cc.ScrollView.prototype.ctor.call(this);
this._oldDirection = cc.SCROLLVIEW_DIRECTION_NONE;
this._cellsPositions = [];
@@ -212,7 +212,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
this._updateContentSize();
},
- __indexFromOffset:function (offset) {
+ __indexFromOffset: function (offset) {
var low = 0;
var high = this._dataSource.numberOfCellsInTableView(this) - 1;
var search;
@@ -226,16 +226,16 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
var locCellsPositions = this._cellsPositions;
- while (high >= low){
- var index = 0|(low + (high - low) / 2);
+ while (high >= low) {
+ var index = 0 | (low + (high - low) / 2);
var cellStart = locCellsPositions[index];
var cellEnd = locCellsPositions[index + 1];
- if (search >= cellStart && search <= cellEnd){
+ if (search >= cellStart && search <= cellEnd) {
return index;
- } else if (search < cellStart){
+ } else if (search < cellStart) {
high = index - 1;
- }else {
+ } else {
low = index + 1;
}
}
@@ -245,7 +245,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
return -1;
},
- _indexFromOffset:function (offset) {
+ _indexFromOffset: function (offset) {
var locOffset = {x: offset.x, y: offset.y};
var locDataSource = this._dataSource;
var maxIdx = locDataSource.numberOfCellsInTableView(this) - 1;
@@ -262,7 +262,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
return index;
},
- __offsetFromIndex:function (index) {
+ __offsetFromIndex: function (index) {
var offset;
switch (this.getDirection()) {
case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
@@ -276,7 +276,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
return offset;
},
- _offsetFromIndex:function (index) {
+ _offsetFromIndex: function (index) {
var offset = this.__offsetFromIndex(index);
var cellSize = this._dataSource.tableCellSizeForIndex(this, index);
@@ -286,14 +286,14 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
return offset;
},
- _updateCellPositions:function(){
+ _updateCellPositions: function () {
var cellsCount = this._dataSource.numberOfCellsInTableView(this);
var locCellsPositions = this._cellsPositions;
- if (cellsCount > 0){
+ if (cellsCount > 0) {
var currentPos = 0;
var cellSize, locDataSource = this._dataSource;
- for (var i=0; i < cellsCount; i++) {
+ for (var i = 0; i < cellsCount; i++) {
locCellsPositions[i] = currentPos;
cellSize = locDataSource.tableCellSizeForIndex(this, i);
switch (this.getDirection()) {
@@ -309,12 +309,12 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
},
- _updateContentSize:function () {
+ _updateContentSize: function () {
var size = cc.size(0, 0);
var cellsCount = this._dataSource.numberOfCellsInTableView(this);
- if(cellsCount > 0){
+ if (cellsCount > 0) {
var maxPosition = this._cellsPositions[cellsCount];
switch (this.getDirection()) {
case cc.SCROLLVIEW_DIRECTION_HORIZONTAL:
@@ -338,8 +338,8 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
},
- _moveCellOutOfSight:function (cell) {
- if(this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
+ _moveCellOutOfSight: function (cell) {
+ if (this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
this._tableViewDelegate.tableCellWillRecycle(this, cell);
this._cellsFreed.addObject(cell);
@@ -352,50 +352,52 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
},
- _setIndexForCell:function (index, cell) {
+ _setIndexForCell: function (index, cell) {
cell.setAnchorPoint(0, 0);
cell.setPosition(this._offsetFromIndex(index));
cell.setIdx(index);
},
- _addCellIfNecessary:function (cell) {
+ _addCellIfNecessary: function (cell) {
if (cell.getParent() !== this.getContainer()) {
this.getContainer().addChild(cell);
}
this._cellsUsed.insertSortedObject(cell);
var locIndices = this._indices, addIdx = cell.getIdx();
- if(locIndices.indexOf(addIdx) === -1){
+ if (locIndices.indexOf(addIdx) === -1) {
locIndices.push(addIdx);
//sort
- locIndices.sort(function(a,b){return a-b;});
+ locIndices.sort(function (a, b) {
+ return a - b;
+ });
}
},
/**
* data source
*/
- getDataSource:function () {
+ getDataSource: function () {
return this._dataSource;
},
- setDataSource:function (source) {
+ setDataSource: function (source) {
this._dataSource = source;
},
/**
* delegate
*/
- getDelegate:function () {
+ getDelegate: function () {
return this._tableViewDelegate;
},
- setDelegate:function (delegate) {
+ setDelegate: function (delegate) {
this._tableViewDelegate = delegate;
},
/**
* determines how cell is ordered and filled in the view.
*/
- setVerticalFillOrder:function (fillOrder) {
+ setVerticalFillOrder: function (fillOrder) {
if (this._vOrdering !== fillOrder) {
this._vOrdering = fillOrder;
if (this._cellsUsed.count() > 0) {
@@ -403,11 +405,11 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
}
},
- getVerticalFillOrder:function () {
+ getVerticalFillOrder: function () {
return this._vOrdering;
},
- initWithViewSize:function (size, container) {
+ initWithViewSize: function (size, container) {
if (cc.ScrollView.prototype.initWithViewSize.call(this, size, container)) {
this._cellsUsed = new cc.ArrayForObjectSorting();
this._cellsFreed = new cc.ArrayForObjectSorting();
@@ -427,7 +429,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
*
* @param idx index to find a cell
*/
- updateCellAtIndex:function (idx) {
+ updateCellAtIndex: function (idx) {
if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
return;
@@ -445,7 +447,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
*
* @param idx location to insert
*/
- insertCellAtIndex:function (idx) {
+ insertCellAtIndex: function (idx) {
if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
return;
@@ -473,7 +475,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
*
* @param idx index to find a cell
*/
- removeCellAtIndex:function (idx) {
+ removeCellAtIndex: function (idx) {
if (idx === cc.INVALID_INDEX || idx > this._dataSource.numberOfCellsInTableView(this) - 1)
return;
@@ -498,13 +500,13 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
/**
* reloads data from data source. the view will be refreshed.
*/
- reloadData:function () {
+ reloadData: function () {
this._oldDirection = cc.SCROLLVIEW_DIRECTION_NONE;
var locCellsUsed = this._cellsUsed, locCellsFreed = this._cellsFreed, locContainer = this.getContainer();
for (var i = 0, len = locCellsUsed.count(); i < len; i++) {
var cell = locCellsUsed.objectAtIndex(i);
- if(this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
+ if (this._tableViewDelegate && this._tableViewDelegate.tableCellWillRecycle)
this._tableViewDelegate.tableCellWillRecycle(this, cell);
locCellsFreed.addObject(cell);
@@ -520,6 +522,8 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
this._updateContentSize();
if (this._dataSource.numberOfCellsInTableView(this) > 0)
this.scrollViewDidScroll(this);
+
+ this.setNodeDirty();
},
/**
@@ -527,7 +531,7 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
*
* @return {TableViewCell} free cell
*/
- dequeueCell:function () {
+ dequeueCell: function () {
if (this._cellsFreed.count() === 0) {
return null;
} else {
@@ -543,14 +547,14 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
* @param idx index
* @return {cc.TableViewCell} a cell at a given index
*/
- cellAtIndex:function (idx) {
+ cellAtIndex: function (idx) {
var i = this._indices.indexOf(idx);
if (i === -1)
return null;
return this._cellsUsed.objectWithObjectID(idx);
},
- scrollViewDidScroll:function (view) {
+ scrollViewDidScroll: function (view) {
var locDataSource = this._dataSource;
var countOfItems = locDataSource.numberOfCellsInTableView(this);
if (0 === countOfItems)
@@ -559,24 +563,24 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
if (this._tableViewDelegate !== null && this._tableViewDelegate.scrollViewDidScroll)
this._tableViewDelegate.scrollViewDidScroll(this);
- var idx = 0, locViewSize = this._viewSize, locContainer = this.getContainer();
+ var idx = 0, locViewSize = this._viewSize, locContainer = this.getContainer();
var offset = this.getContentOffset();
offset.x *= -1;
offset.y *= -1;
- var maxIdx = Math.max(countOfItems-1, 0);
+ var maxIdx = Math.max(countOfItems - 1, 0);
if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
- offset.y = offset.y + locViewSize.height/locContainer.getScaleY();
+ offset.y = offset.y + locViewSize.height / locContainer.getScaleY();
var startIdx = this._indexFromOffset(offset);
if (startIdx === cc.INVALID_INDEX)
startIdx = countOfItems - 1;
if (this._vOrdering === cc.TABLEVIEW_FILL_TOPDOWN)
- offset.y -= locViewSize.height/locContainer.getScaleY();
+ offset.y -= locViewSize.height / locContainer.getScaleY();
else
- offset.y += locViewSize.height/locContainer.getScaleY();
- offset.x += locViewSize.width/locContainer.getScaleX();
+ offset.y += locViewSize.height / locContainer.getScaleY();
+ offset.x += locViewSize.width / locContainer.getScaleX();
var endIdx = this._indexFromOffset(offset);
if (endIdx === cc.INVALID_INDEX)
@@ -617,24 +621,24 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
}
},
- scrollViewDidZoom:function (view) {
+ scrollViewDidZoom: function (view) {
},
- onTouchEnded:function (touch, event) {
+ onTouchEnded: function (touch, event) {
if (!this.isVisible())
return;
- if (this._touchedCell){
+ if (this._touchedCell) {
var bb = this.getBoundingBox();
var tmpOrigin = cc.p(bb.x, bb.y);
tmpOrigin = this._parent.convertToWorldSpace(tmpOrigin);
bb.x = tmpOrigin.x;
bb.y = tmpOrigin.y;
var locTableViewDelegate = this._tableViewDelegate;
- if (cc.rectContainsPoint(bb, touch.getLocation()) && locTableViewDelegate !== null){
- if(locTableViewDelegate.tableCellUnhighlight)
+ if (cc.rectContainsPoint(bb, touch.getLocation()) && locTableViewDelegate !== null) {
+ if (locTableViewDelegate.tableCellUnhighlight)
locTableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
- if(locTableViewDelegate.tableCellTouched)
+ if (locTableViewDelegate.tableCellTouched)
locTableViewDelegate.tableCellTouched(this, this._touchedCell);
}
this._touchedCell = null;
@@ -642,13 +646,15 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
cc.ScrollView.prototype.onTouchEnded.call(this, touch, event);
},
- onTouchBegan:function(touch, event){
- if (!this.isVisible())
- return false;
+ onTouchBegan: function (touch, event) {
+ for (var c = this; c != null; c = c.parent) {
+ if (!c.isVisible())
+ return false;
+ }
var touchResult = cc.ScrollView.prototype.onTouchBegan.call(this, touch, event);
- if(this._touches.length === 1) {
+ if (this._touches.length === 1) {
var index, point;
point = this.getContainer().convertTouchToNodeSpace(touch);
@@ -657,12 +663,12 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
if (index === cc.INVALID_INDEX)
this._touchedCell = null;
else
- this._touchedCell = this.cellAtIndex(index);
+ this._touchedCell = this.cellAtIndex(index);
if (this._touchedCell && this._tableViewDelegate !== null && this._tableViewDelegate.tableCellHighlight)
this._tableViewDelegate.tableCellHighlight(this, this._touchedCell);
- } else if(this._touchedCell) {
- if(this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ } else if (this._touchedCell) {
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
this._touchedCell = null;
}
@@ -670,21 +676,21 @@ cc.TableView = cc.ScrollView.extend(/** @lends cc.TableView# */{
return touchResult;
},
- onTouchMoved: function(touch, event){
+ onTouchMoved: function (touch, event) {
cc.ScrollView.prototype.onTouchMoved.call(this, touch, event);
if (this._touchedCell && this.isTouchMoved()) {
- if(this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
this._touchedCell = null;
}
},
- onTouchCancelled: function(touch, event){
+ onTouchCancelled: function (touch, event) {
cc.ScrollView.prototype.onTouchCancelled.call(this, touch, event);
if (this._touchedCell) {
- if(this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
+ if (this._tableViewDelegate !== null && this._tableViewDelegate.tableCellUnhighlight)
this._tableViewDelegate.tableCellUnhighlight(this, this._touchedCell);
this._touchedCell = null;
}
diff --git a/extensions/runtime/CCLoaderLayer.js b/extensions/runtime/CCLoaderLayer.js
new file mode 100644
index 0000000000..5877918da5
--- /dev/null
+++ b/extensions/runtime/CCLoaderLayer.js
@@ -0,0 +1,988 @@
+/****************************************************************************
+ Copyright (c) 2014-2015 Chukong Technologies Inc.
+
+ http://www.cocos2d-x.org
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ ****************************************************************************/
+(function () {
+
+var INT_MAX = Number.MAX_VALUE;
+var GROUP_JSON_PATH = "group.json";
+
+cc.LoaderLayer = cc.Layer.extend({
+ _backgroundSprite: null,
+ _progressBackgroundSprite: null,
+ _progressBarSprite: null,
+ _logoSprite: null,
+ _titleSprite: null,
+ _groupname: null,
+ _callback: null,
+ _selector: null,
+ _preloadCount: 0,
+ _isPreloadFromFailed: false,
+ _progressOriginalWidth: 0,
+ _isLandScape: false,
+ _scaleFactor: null,
+
+ ctor: function (config) {
+ this._super();
+ if (config) {
+ cc.LoaderLayer.setConfig(config);
+ }
+ },
+ onEnter: function () {
+ this._super();
+ this.initView();
+ var config = cc.LoaderLayer._finalConfig;
+ if (config.onEnter) {
+ config.onEnter(this);
+ }
+ },
+ onExit: function () {
+ this._super();
+ var config = cc.LoaderLayer._finalConfig;
+ if (config.logo.action) {
+ config.logo.action.release();
+ }
+ if(config.title.action){
+ config.title.action.release();
+ }
+ if (config.onExit) {
+ config.onExit(this);
+ }
+ },
+ initView: function () {
+ var config = cc.LoaderLayer._finalConfig;
+ this._contentLayer = new cc.Layer();
+ this._isLandScape = cc.winSize.width > cc.winSize.height;
+ this._scaleFactor = !cc.LoaderLayer._useDefaultSource ? 1 : cc.winSize.width > cc.winSize.height ? cc.winSize.width / 720 : cc.winSize.width / 480;
+
+ //background
+ this.backgroundSprite = new cc.Sprite(config.background.res);
+ this.addChild(this.backgroundSprite);
+ this.backgroundSprite.x = 0, this.backgroundSprite.y = 0, this.backgroundSprite.anchorX = 0, this.backgroundSprite.anchorY = 0;
+ if (cc.LoaderLayer._useDefaultSource) {
+ this.backgroundSprite.scaleX = cc.winSize.width / this.backgroundSprite.width;
+ this.backgroundSprite.scaleY = cc.winSize.height / this.backgroundSprite.height;
+ }
+
+ //title
+ if (config.title.show) {
+ this.titleSprite = new cc.Sprite(config.title.res);
+ var defaultTitlePosition = cc.pAdd(cc.visibleRect.center, cc.p(0, this._scaleFactor < 1 ? 0 : this._isLandScape ? -80 : 30));
+ this.titleSprite.setPosition(config.title.position ? config.title.position : defaultTitlePosition);
+ this._contentLayer.addChild(this.titleSprite);
+ if (config.title.action) {
+ this.titleSprite.runAction(config.title.action);
+ }
+ }
+
+ //logo
+ if (config.logo.show) {
+ this.logoSprite = new cc.Sprite(config.logo.res);
+ var defaultLogoPosition = cc.pAdd(cc.visibleRect.top, cc.p(0, this._scaleFactor < 1 ? 0 : -this.logoSprite.height / 2 - (this._isLandScape ? 56 : 76)));
+ this.logoSprite.setPosition(config.logo.position ? config.logo.position : defaultLogoPosition);
+ this._contentLayer.addChild(this.logoSprite);
+ if (config.logo.action) {
+ this.logoSprite.runAction(config.logo.action);
+ }
+ }
+
+ //progressbar
+ if (config.progressBar.show) {
+ this.progressBarSprite = new cc.Sprite(config.progressBar.res);
+ this._progressOriginalWidth = this.progressBarSprite.width;
+ this.progressBackgroundSprite = new cc.Sprite(config.progressBar.barBackgroundRes);
+ this.progressBarSprite.anchorX = 0;
+ this.progressBarSprite.anchorY = 0;
+ if (cc.LoaderLayer._isDefaultProgress) {
+ this._barPoint = new cc.Sprite(config.progressBar.barPoint);
+ this.progressBarSprite.addChild(this._barPoint);
+ }
+ if (config.progressBar.barBackgroundRes == null) {
+ this.progressBackgroundSprite.setTextureRect(cc.rect(0, 0, this.progressBarSprite.width, this.progressBarSprite.height));
+ }
+ if (config.progressBar.offset == null) {
+ var deltaProgressWithX = (this.progressBackgroundSprite.width - this.progressBarSprite.width) / 2;
+ var deltaProgressWithY = (this.progressBackgroundSprite.height - this.progressBarSprite.height) / 2;
+ config.progressBar.offset = cc.p(deltaProgressWithX, deltaProgressWithY);
+ }
+ this.progressBarSprite.setPosition(config.progressBar.offset);
+ this.progressBackgroundSprite.addChild(this.progressBarSprite);
+ var defaultProgressPosition = cc.pAdd(cc.visibleRect.bottom, cc.p(0, this.progressBarSprite.height / 2 + this._isLandScape ? 60 : 80));
+ this.progressBackgroundSprite.setPosition(config.progressBar.position ? config.progressBar.position : defaultProgressPosition);
+ this._contentLayer.addChild(this.progressBackgroundSprite);
+ this._setProgress(0);
+ }
+
+ //tips
+ if (config.tips.show) {
+ this.tipsLabel = new cc.LabelTTF("100%", "Arial", config.tips.fontSize);
+ this.tipsLabel.setColor(config.tips.color ? config.tips.color : cc.color(255, 255, 255));
+ this.tipsLabel.setPosition(config.tips.position ? config.tips.position : this.progressBackgroundSprite ? cc.p(this.progressBackgroundSprite.x, this.progressBackgroundSprite.y + this.progressBackgroundSprite.height / 2 + 20) : cc.pAdd(cc.visibleRect.bottom, cc.p(0, 100)));
+ this._contentLayer.addChild(this.tipsLabel);
+ }
+ this.addChild(this._contentLayer);
+ if (this._scaleFactor < 1) {
+ this._contentLayer.setScale(this._scaleFactor);
+ this._contentLayer.setPosition(cc.pAdd(this._contentLayer.getPosition(), cc.p(0, -50)));
+ }
+
+ },
+ _setProgress: function (percent) {
+ if (this.progressBarSprite) {
+ percent < 1 ? percent : 1;
+ var width = percent * this._progressOriginalWidth;
+ this.progressBarSprite.setTextureRect(cc.rect(0, 0, width, this.progressBarSprite.height));
+ if (cc.LoaderLayer._isDefaultProgress) {
+ this._barPoint.setPosition(cc.p(this.progressBarSprite.width, this.progressBarSprite.height / 2));
+ }
+ }
+ },
+ setTipsString: function (str) {
+ if (this.tipsLabel != null) {
+ this.tipsLabel.setString(str);
+ }
+ },
+ getProgressBar: function () {
+ return this.progressBarSprite;
+ },
+ getTipsLabel: function () {
+ return this.tipsLabel;
+ },
+ getLogoSprite: function () {
+ return this.logoSprite;
+ },
+ getTitleSprite: function () {
+ return this.titleSprite;
+ },
+ updateGroup: function (groupname, callback, target) {
+ this._groupname = groupname;
+ this._callback = callback;
+ this._selector = target;
+ },
+ _resetLoadingLabel: function () {
+ this.setTipsString("");
+ this._setProgress(0);
+ },
+ _preloadSource: function () {
+ cc.log("cc.LoaderLayer is preloading resource group: " + this._groupname);
+ this._resetLoadingLabel();
+ if (cc.sys.isNative) {
+ cc.Loader.preload(this._groupname, this._preload_native, this);
+ } else {
+ this._preload_html5();
+ }
+ },
+ _preload_html5: function () {
+ var res = "";
+ var groupIndex = [];
+ var config = cc.LoaderLayer._finalConfig;
+ var groups = cc.LoaderLayer.groups;
+ if (cc.isString(this._groupname)) {
+ if (this._groupname.indexOf(".") != -1) {
+ res = [this._groupname];
+ } else {
+ res = groups[this._groupname];
+ }
+ } else if (cc.isArray(this._groupname)) {
+ res = [];
+ for (var i = 0; i < this._groupname.length; i++) {
+ var group = groups[this._groupname[i]];
+ var files = group && group.files;
+ var preCount = i > 0 ? groupIndex[i - 1] : 0;
+ groupIndex.push(preCount + files ? files.length : 0);
+ res = res.concat(files);
+ }
+ }
+ var self = this;
+ //var progressFunction = self.config.progressCallback ? self.config.progressCallback : null;
+ cc.loader.load(res, function (result, count, loadedCount) {
+ var checkGroupName = function (loadedCount) {
+ for (var i = 0; i < groupIndex.length; i++) {
+ if (groupIndex[i] >= loadedCount) {
+ return self._groupname[i];
+ }
+ }
+ };
+ var groupName = checkGroupName(loadedCount);
+ var status = {
+ groupName: groupName,
+ isCompleted: false,
+ percent: (loadedCount / count * 100) | 0,//(float),
+ stage: 1, //(1 download,2 unzip)
+ isFailed: false
+ }
+ if (status.percent != 0) {
+ self._setProgress(status.percent / 100);
+ }
+ config.tips.tipsProgress(status, self);
+ }, function () {
+ self.removeFromParent();
+ self._preloadCount--;
+ if (self._callback) {
+ if (self._selector) {
+ self._callback(self._selector, true);
+ } else {
+ self._callback(true);
+ }
+ }
+ });
+ },
+ _preload_native: function (status) {
+ cc.log(JSON.stringify(status));
+ var config = cc.LoaderLayer._finalConfig;
+ if (status.percent) {
+ this._setProgress(status.percent / 100);
+ }
+ if (config.tips.tipsProgress) {
+ config.tips.tipsProgress(status, this);
+ }
+ if (status.isCompleted || status.isFailed) {
+ this._preloadCount--;
+
+ if (status.isCompleted) {
+ cc.log("preload finish!");
+ this._isPreloadFromFailed = false;
+ }
+ if (status.isFailed) {
+ cc.log("preload failed!");
+ this._isPreloadFromFailed = true;
+ }
+
+ // Remove loading layer from scene after loading was done.
+ if (this._preloadCount == 0 && !this._isPreloadFromFailed) {
+ this.removeFromParent();
+ if (cc.LoaderLayer._useDefaultSource) {
+ var _config = cc.runtime.config.design_resolution || {width: 480, height: 720, policy: "SHOW_ALL"};
+ cc.view.setDesignResolutionSize(_config.width, _config.height, cc.ResolutionPolicy[_config.policy]);
+ }
+ }
+
+ // Callback must be invoked after removeFromParent.
+ this._callback.call(this._target, status);
+ }
+ },
+ _addToScene: function () {
+ if (this._preloadCount == 0 && !this._isPreloadFromFailed) {
+ if (cc.sys.isNative && cc.LoaderLayer._useDefaultSource) {
+ var config = cc.runtime.config.design_resolution;
+ var isLandscape = false;
+ var isLargeThanResource = false;
+ if (config) {
+ var orientation = cc.runtime.config.orientation;
+ cc.log("_addToScene orientation is " + orientation);
+ if (orientation == "landscape") {
+ isLandscape = true;
+ isLargeThanResource = config.width > 720 || config.height > 480;
+ } else {
+ isLargeThanResource = config.width > 480 || config.height > 720;
+ }
+ }
+ cc.log("isLargeThanResource is " + isLargeThanResource);
+ cc.view.setDesignResolutionSize(isLargeThanResource ? config.width : isLandscape ? 720 : 480, isLargeThanResource ? config.height : isLandscape ? 480 : 720, cc.ResolutionPolicy["FIXED_HEIGHT"]);
+ }
+ cc.director.getRunningScene().addChild(this, INT_MAX - 1);
+ }
+ this._preloadCount++;
+ }
+});
+cc.LoaderLayer._config = {//default setting for loaderlayer
+ background: {
+ res: "res_engine/preload_bg.jpg"
+ },
+ title: {
+ show: true,
+ res: "res_engine/preload_title.png",
+ position: null,
+ action: null
+ },
+ logo: {
+ res: "res_engine/preload_logo.png",
+ show: true,
+ position: null
+ },
+ progressBar: {
+ show: true,
+ res: "res_engine/progress_bar.png",
+ offset: null,
+ position: null,
+ barBackgroundRes: "res_engine/progress_bg.png",
+ barPoint: "res_engine/progress_light.png",
+ barShadow: "res_engine/shadow.png"
+ },
+ tips: {
+ show: true,
+ fontSize: 22,
+ position: null,
+ color: null,
+ tipsProgress: function (status, loaderlayer) {
+ if(loaderlayer.getTipsLabel()){
+ var statusStr = "æ£åœ¨";
+ if (status.stage == cc.network.preloadstatus.DOWNLOAD) {
+ statusStr += "下载";
+ } else if (status.stage == cc.network.preloadstatus.UNZIP) {
+ statusStr += "解压";
+ }
+ if (status.groupName) {
+ statusStr += status.groupName;
+ }
+ statusStr += "进度:" + status.percent.toFixed(2) + "%";
+ loaderlayer.getTipsLabel().setString(statusStr);
+ }
+ }
+ },
+ progressCallback: function (progress) {
+
+ },
+ onEnter: function (layer) {
+ cc.log("LoaderLayer onEnter");
+ },
+ onExit: function (layer) {
+ cc.log("LoaderLayer onExit");
+ }
+}
+
+var res_engine_loaded = false;
+
+cc.LoaderLayer.preload = function (groupname, callback, target) {
+ var loaderLayer = new cc.LoaderLayer();
+ var preloadCb = function (status) {
+ if (status.isFailed) {
+ var tips, conirmfunc, cancelfunc;
+ switch (status.errorCode) {
+ case "err_no_space":
+ {
+ tips = "空间ä¸è¶³ï¼Œè¯·æ¸…ç†ç£ç›˜ç©ºé—´";
+ conirmfunc = function () {
+ callPreload();
+ };
+ cancelfunc = function () {
+ cc.director.end();
+ };
+ break;
+ }
+ case "err_verify":
+ {
+ tips = "æ ¡éªŒå¤±è´¥ï¼Œæ˜¯å¦é‡æ–°ä¸‹è½½ï¼Ÿ";
+ conirmfunc = function () {
+ callPreload();
+ }
+ cancelfunc = function () {
+ cc.director.end();
+ }
+ break;
+ }
+ case "err_network":
+ {
+ tips = "网络异常是å¦é‡æ–°ä¸‹è½½";
+ conirmfunc = function () {
+ callPreload();
+ }
+ cancelfunc = function () {
+ cc.director.end();
+ }
+ break;
+ }
+ default :
+ {
+ conirmfunc = cancelfunc = function () {
+
+ }
+ }
+ }
+ cc._NetworkErrorDialog._show(status.errorCode, tips, conirmfunc, cancelfunc);
+ } else {
+ if (callback) {
+ if (target) {
+ callback.call(target, !status.isFailed);
+ } else {
+ callback(!status.isFailed)
+ }
+ }
+ }
+ }
+ var callPreload = function () {
+ loaderLayer.updateGroup(groupname, preloadCb, target);
+ loaderLayer._addToScene();
+ loaderLayer._preloadSource();
+ };
+
+ if (res_engine_loaded) {
+ callPreload();
+ return;
+ }
+
+ if (!cc.director.getRunningScene()) {
+ cc.director.runScene(new cc.Scene());
+ }
+
+ // Res engine not loaded, load them
+ cc.loader.load([
+ GROUP_JSON_PATH,
+ cc.LoaderLayer._finalConfig.background.res,
+ cc.LoaderLayer._finalConfig.title.res,
+ cc.LoaderLayer._finalConfig.logo.res,
+ cc.LoaderLayer._finalConfig.progressBar.res,
+ cc.LoaderLayer._finalConfig.progressBar.barBackgroundRes,
+ cc.LoaderLayer._finalConfig.progressBar.barPoint,
+ cc.LoaderLayer._finalConfig.progressBar.barShadow,
+ cc.Dialog._finalConfig.background.res,
+ cc.Dialog._finalConfig.confirmBtn.normalRes,
+ cc.Dialog._finalConfig.confirmBtn.pressRes,
+ cc.Dialog._finalConfig.cancelBtn.normalRes,
+ cc.Dialog._finalConfig.cancelBtn.pressRes
+ ],
+ function (result, count, loadedCount) {
+ var percent = (loadedCount / count * 100) | 0;
+ percent = Math.min(percent, 100);
+ cc.log("Preloading engine resources... " + percent + "%");
+ }, function () {
+ var groups = cc.loader.getRes(GROUP_JSON_PATH);
+ if (groups) {
+ cc.LoaderLayer.groups = groups;
+ }
+ else {
+ cc.warn("Group versions haven't been loaded, you can also set group data with 'cc.LoaderLayer.groups'");
+ }
+ res_engine_loaded = true;
+ callPreload();
+ });
+};
+
+cc.LoaderLayer._useDefaultSource = true;
+cc.LoaderLayer._isDefaultProgress = true;
+cc.LoaderLayer._finalConfig = cc.LoaderLayer._config;
+cc.LoaderLayer.groups = {};
+cc.LoaderLayer.setUseDefaultSource = function (status) {
+ cc.LoaderLayer._useDefaultSource = status;
+};
+cc.LoaderLayer.setConfig = function (config) {
+ if(config.title && config.title.action){
+ config.title.action.retain();
+ }
+ if(config.logo && config.logo.action){
+ config.logo.action.retain();
+ }
+ this._initData(config);
+};
+cc.LoaderLayer._initData = function (uConfig) {
+ this._finalConfig = cc.clone(this._config);
+ var config = this._finalConfig;
+ if (uConfig != null) {
+ if (uConfig.background && uConfig.background.res) {
+ config.background.res = uConfig.background.res;
+ }
+ if (uConfig.title) {
+ var uTitle = uConfig.title;
+ var title = config.title;
+ title.show = typeof uTitle.show != "undefined" ? uTitle.show : title.show;
+ title.res = uTitle.res ? uTitle.res : title.res;
+ title.position = uTitle.position ? uTitle.position : title.position;
+ title.action = uTitle.action ? uTitle.action : title.action;
+ if (title.action) {
+ title.action = uTitle.action;
+ title.action.retain();
+ }
+ }
+ if (uConfig.logo) {
+ var uLogo = uConfig.logo;
+ var logo = config.logo;
+ logo.show = typeof uLogo.show != "undefined" ? uLogo.show : logo.show;
+ logo.res = uLogo.res ? uLogo.res : logo.res;
+ logo.position = uLogo.position ? uLogo.position : logo.position;
+ if (typeof uLogo.action != "undefined") {
+ logo.action = uLogo.action;
+ if (logo.action) {
+ logo.action.retain();
+ }
+ }
+ }
+ if (uConfig.progressBar) {
+ var uProgress = uConfig.progressBar;
+ var progress = config.progressBar;
+ progress.show = typeof uProgress.show != "undefined" ? uProgress.show : progress.show;
+ if (uProgress.res) {
+ progress.res = uProgress.res;
+ this._isDefaultProgress = false;
+ }
+ progress.offset = uProgress.offset ? uProgress.offset : progress.offset;
+ progress.position = uProgress.position ? uProgress.position : progress.position;
+ progress.barBackgroundRes = uProgress.barBackgroundRes ? uProgress.barBackgroundRes : progress.barBackgroundRes;
+ }
+ if (uConfig.tips) {
+ var uTips = uConfig.tips;
+ var tips = config.tips;
+ tips.show = typeof uTips.show != "undefined" ? uTips.show : tips.show;
+ tips.res = uTips.res ? uTips.res : tips.res;
+ tips.offset = uTips.offset ? uTips.offset : tips.offset;
+ tips.fontSize = uTips.fontSize ? uTips.fontSize : tips.fontSize;
+ tips.position = uTips.position ? uTips.position : tips.position;
+ tips.color = uTips.color ? uTips.color : tips.color;
+ if (uConfig.tips.tipsProgress && typeof uConfig.tips.tipsProgress == "function") {
+ tips.tipsProgress = uConfig.tips.tipsProgress;
+ }
+ }
+ if (typeof uConfig.onEnter == "function") {
+ config.onEnter = uConfig.onEnter;
+ }
+ if (typeof uConfig.onExit == "function") {
+ config.onExit = uConfig.onExit;
+ }
+ }
+
+ if (typeof config.logo.action == "undefined" && this._useDefaultSource) {
+ config.logo.action = cc.sequence(
+ cc.spawn(cc.moveBy(0.4, cc.p(0, 40)).easing(cc.easeIn(0.5)), cc.scaleTo(0.4, 0.95, 1.05).easing(cc.easeIn(0.5))),
+ cc.delayTime(0.08),
+ cc.spawn(cc.moveBy(0.4, cc.p(0, -40)).easing(cc.easeOut(0.5)), cc.scaleTo(0.4, 1.05, 0.95).easing(cc.easeOut(0.5)))
+ ).repeatForever();
+ config.logo.action.retain();
+ }
+ if (!config.tips.color) {
+ config.tips.color = cc.color(255, 255, 255);
+ }
+};
+
+cc.Dialog = cc.Layer.extend({
+ _defaultConfig: null,
+ backgroundSprite: null,
+ _menuItemConfirm: null,
+ _menuItemCancel: null,
+ _messageLabel: null,
+ _eventListener: null,
+ _scaleFactor: null,
+
+ ctor: function (config) {
+ this._super();
+ this.setConfig(config);
+ },
+ setConfig: function (config) {
+ this.removeAllChildren();
+ if (config) {
+ cc.Dialog.setConfig(config);
+ }
+ },
+ initView: function () {
+ var useDefaultSource = cc.Dialog._useDefaultSource;
+ var winSize = cc.director.getWinSize();
+ this._scaleFactor = !useDefaultSource ? 1 : winSize.width > winSize.height ? winSize.width / 720 : winSize.width / 480;
+ var config = cc.Dialog._finalConfig;
+
+ //bg
+ this.backgroundSprite = new cc.Scale9Sprite(config.background.res);
+ this._setScale(this.backgroundSprite);
+ if (this._scaleFactor < 1) {
+ this.backgroundSprite.setScale(this._scaleFactor);
+ }
+ this.backgroundSprite.setPosition(config.position ? config.position : cc.p(winSize.width / 2, winSize.height / 2));
+
+ //menu
+ this.menuItemConfirm = this._createMenuItemSprite(config.confirmBtn, this._confirmCallback);
+ this.menuItemCancel = this._createMenuItemSprite(config.cancelBtn, this._cancelCallback);
+ this.menuItemCancel.setPosition(config.cancelBtn.position ? config.cancelBtn.position : cc.p(this.backgroundSprite.width / 2 - this.menuItemCancel.width / 2 - 20, this.menuItemCancel.height + 20));
+ this.menuItemConfirm.setPosition(config.confirmBtn.position ? config.confirmBtn.position : cc.p(this.backgroundSprite.width / 2 + this.menuItemConfirm.width / 2 + 20, this.menuItemConfirm.height + 20));
+ var menu = new cc.Menu(this.menuItemConfirm, this.menuItemCancel);
+ menu.setPosition(cc.p(0, 0));
+ this.backgroundSprite.addChild(menu);
+
+ //message
+ var fontSize = config.messageLabel.fontSize ? config.messageLabel.fontSize : this._scaleFactor > 1 ? 16 * this._scaleFactor : 16;
+ this.messageLabel = new cc.LabelTTF(config.messageLabel.text, "Arial", fontSize);
+ this.messageLabel.setDimensions(config.messageLabel.dimensions ? config.messageLabel.dimensions : cc.size(this.backgroundSprite.width - 30, this.backgroundSprite.height - this.menuItemConfirm.y - 10));
+ this.messageLabel.setColor(config.messageLabel.color ? config.messageLabel.color : cc.color(255, 255, 255));
+ this.messageLabel.setPosition(config.messageLabel.position ? config.messageLabel.position : cc.p(this.backgroundSprite.width / 2, this.backgroundSprite.height - this.messageLabel.height / 2 - 20));
+ this.backgroundSprite.addChild(this.messageLabel);
+ if (!config.action) {
+ var action = cc.sequence(cc.EaseIn.create(cc.scaleTo(0.1, this.backgroundSprite.scale + 0.02), 0.4), cc.EaseOut.create(cc.scaleTo(0.1, this.backgroundSprite.scale), 0.3));
+ this.backgroundSprite.runAction(action);
+ } else {
+ this.backgroundSprite.runAction(config.action);
+ }
+ this.addChild(this.backgroundSprite);
+
+ },
+ _createMenuItemSprite: function (res, callback) {
+ var spriteNormal = new cc.Scale9Sprite(res.normalRes);
+ var spritePress = new cc.Scale9Sprite(res.pressRes);
+ this._setScale(spriteNormal);
+ this._setScale(spritePress);
+ var fontSize = res.fontSize ? res.fontSize : this._scaleFactor > 1 ? 16 * this._scaleFactor : 16;
+ var menuLabel = new cc.LabelTTF(res.text, "Arial", fontSize);
+ menuLabel.setColor(res.textColor);
+ var menuItem = new cc.MenuItemSprite(spriteNormal, spritePress, callback, this);
+ menuLabel.setPosition(cc.p(menuItem.width / 2, menuItem.height / 2));
+ menuItem.addChild(menuLabel);
+ return menuItem;
+ },
+ _setScale: function (s9Sprite) {
+ if (this._scaleFactor > 1) {
+ s9Sprite.setContentSize(cc.size(this._scaleFactor * s9Sprite.width, this._scaleFactor * s9Sprite.height));
+ }
+ },
+ _confirmCallback: function () {
+ var config = cc.Dialog._finalConfig;
+ if (config.confirmBtn.callback) {
+ if (config.target) {
+ config.confirmBtn.callback.call(config.target, this);
+ } else {
+ config.confirmBtn.callback(this);
+ }
+ }
+ this.removeFromParent();
+ },
+ _cancelCallback: function () {
+ var config = cc.Dialog._finalConfig;
+ if (config.cancelBtn.callback) {
+ if (config.target) {
+ config.cancelBtn.callback.call(config.target, this);
+ } else {
+ config.cancelBtn.callback(this);
+ }
+ }
+ this.removeFromParent();
+ },
+ onEnter: function () {
+ this._super();
+ var config = cc.Dialog._finalConfig;
+ this.initView();
+ config.onEnter(this);
+ var self = this;
+ self._eventListener = cc.EventListener.create({
+ event: cc.EventListener.TOUCH_ONE_BY_ONE,
+ swallowTouches: true,
+ onTouchBegan: function (touch, event) {
+ return true;
+ }
+ });
+ cc.eventManager.addListener(self._eventListener, self);
+ },
+ onExit: function () {
+ this._super();
+ var config = cc.Dialog._finalConfig;
+ config.onExit(this);
+ this.removeAllChildren();
+ cc.Dialog._dialog = null;
+ cc.eventManager.removeListener(this._eventListener);
+ }
+});
+
+cc.Dialog._dialog = null;
+cc.Dialog._clearDialog = function () {
+ if (cc.Dialog._dialog != null) {
+ cc.Dialog._dialog.removeFromParent();
+ cc.Dialog._dialog = null;
+ }
+}
+
+cc.Dialog.show = function (tips, confirmCb, cancelCb) {
+ if (cc.Dialog._dialog != null) {
+ cc.log("other dialog is on the screen,this dialog can't show now");
+ return;
+ }
+
+ var conf;
+ if (typeof tips == "string") {
+ conf = {
+ messageLabel: {
+ text: tips
+ },
+ confirmBtn: {
+ callback: confirmCb
+ },
+ cancelBtn: {
+ callback: cancelCb
+ }
+ }
+ } else if (typeof tips == "object") {
+ conf = tips;
+ } else {
+ cc.log("tips is invalid");
+ return;
+ }
+
+ cc.Dialog._dialog = new cc.Dialog(conf);
+ if (cc.director.getRunningScene()) {
+ cc.director.getRunningScene().addChild(cc.Dialog._dialog, INT_MAX);
+ } else {
+ cc.log("Current scene is null we can't show dialog");
+ }
+};
+cc.Dialog._useDefaultSource = true;
+cc.Dialog.setUseDefaultSource = function (status) {
+ cc.Dialog._useDefaultSource = status;
+}
+cc.Dialog._defaultConfig = {
+ position: null,
+ target: null,
+ action: null,
+ background: {
+ res: "res_engine/dialog_bg.png"
+ },
+ confirmBtn: {
+ normalRes: "res_engine/dialog_confirm_normal.png",
+ pressRes: "res_engine/dialog_confirm_press.png",
+ text: "确定",
+ textColor: null,
+ fontSize: null,
+ position: null,
+ callback: function () {
+ cc.log("this is confirm callback");
+ }
+ },
+ cancelBtn: {
+ normalRes: "res_engine/dialog_cancel_normal.png",
+ pressRes: "res_engine/dialog_cancel_press.png",
+ text: "å–æ¶ˆ",
+ textColor: null,
+ position: null,
+ fontSize: null,
+ callback: function () {
+ cc.log("this is cancel callback");
+ }
+ },
+ messageLabel: {
+ text: "",
+ color: null,
+ dimensions: null,
+ fontSize: null,
+ position: null
+ },
+ onEnter: function (dialog) {
+ cc.log("dialog call onEnter");
+ },
+ onExit: function (dialog) {
+ cc.log("dialog call onExit");
+ }
+};
+cc.Dialog._finalConfig = cc.Dialog._defaultConfig;
+cc.Dialog.setConfig = function (config) {
+ this._initData(config);
+};
+cc.Dialog._initData = function (uConfig) {
+ this._finalConfig = cc.clone(this._defaultConfig);
+ var config = this._finalConfig;
+ if (uConfig != null) {
+ if (uConfig.position) {
+ config.position = uConfig.position;
+ }
+ if (uConfig.action) {
+ config.action = uConfig.action;
+ }
+ if (uConfig.background && uConfig.background.res) {
+ config.background = uConfig.background;
+ }
+ if (uConfig.confirmBtn) {
+ var uConfirmBtn = uConfig.confirmBtn;
+ var confirmBtn = config.confirmBtn;
+ confirmBtn.normalRes = uConfirmBtn.normalRes ? uConfirmBtn.normalRes : confirmBtn.normalRes;
+ confirmBtn.pressRes = uConfirmBtn.pressRes ? uConfirmBtn.pressRes : confirmBtn.pressRes;
+ confirmBtn.text = typeof uConfirmBtn.text != "undefined" ? uConfirmBtn.text : confirmBtn.text;
+ confirmBtn.textColor = uConfirmBtn.textColor ? uConfirmBtn.textColor : confirmBtn.textColor;
+ confirmBtn.fontSize = uConfirmBtn.fontSize ? uConfirmBtn.fontSize : confirmBtn.fontSize;
+ confirmBtn.position = uConfirmBtn.position ? uConfirmBtn.position : confirmBtn.position;
+ confirmBtn.callback = uConfirmBtn.callback ? uConfirmBtn.callback : confirmBtn.callback;
+ }
+ if (uConfig.cancelBtn) {
+ var uCancelBtn = uConfig.cancelBtn;
+ var cancelBtn = config.cancelBtn;
+ cancelBtn.normalRes = uCancelBtn.normalRes ? uCancelBtn.normalRes : cancelBtn.normalRes;
+ cancelBtn.pressRes = uCancelBtn.pressRes ? uCancelBtn.pressRes : cancelBtn.pressRes;
+ cancelBtn.text = typeof uCancelBtn.text != "undefined" ? uCancelBtn.text : cancelBtn.text;
+ cancelBtn.textColor = uCancelBtn.textColor ? uCancelBtn.textColor : cancelBtn.textColor;
+ cancelBtn.fontSize = uCancelBtn.fontSize ? uCancelBtn.fontSize : cancelBtn.fontSize;
+ cancelBtn.position = uCancelBtn.position ? uCancelBtn.position : cancelBtn.position;
+ cancelBtn.callback = uCancelBtn.callback ? uCancelBtn.callback : cancelBtn.callback;
+ }
+ if (uConfig.messageLabel) {
+ var uMessageLabel = uConfig.messageLabel;
+ var messageLabel = config.messageLabel;
+ messageLabel.text = typeof uMessageLabel.text != "undefined" ? uMessageLabel.text : messageLabel.text;
+ messageLabel.color = uMessageLabel.color ? uMessageLabel.color : messageLabel.color;
+ messageLabel.fontSize = uMessageLabel.fontSize ? uMessageLabel.fontSize : messageLabel.fontSize;
+ messageLabel.position = uMessageLabel.position ? uMessageLabel.position : messageLabel.position;
+ messageLabel.dimensions = uMessageLabel.dimensions ? uMessageLabel.dimensions : messageLabel.dimensions;
+ }
+ if (uConfig.target) {
+ config.target = uConfig.target;
+ }
+ if (typeof uConfig.onEnter == "function") {
+ config.onEnter = uConfig.onEnter;
+ }
+ if (typeof uConfig.onExit == "function") {
+ config.onExit = uConfig.onExit;
+ }
+ }
+
+ if (!config.cancelBtn.textColor) {
+ config.cancelBtn.textColor = cc.color(255, 255, 255);
+ }
+ if (!config.confirmBtn.textColor) {
+ config.confirmBtn.textColor = cc.color(255, 255, 255);
+ }
+};
+
+cc._NetworkErrorDialog = function () {
+ cc.Dialog._clearDialog();
+ cc.Dialog._dialog = new cc.Dialog(cc._NetworkErrorDialog._config);
+ return cc.Dialog._dialog;
+}
+cc._NetworkErrorDialog._config = {
+ networkError: {},
+ spaceError: {},
+ verifyError: {}
+};
+cc._NetworkErrorDialog._show = function (type, tips, confirmCb, cancelCb) {
+ var networkDialog = cc._NetworkErrorDialog();
+ var config;
+ switch (type) {
+ case "err_network":
+ {
+ config = cc._NetworkErrorDialog._config.networkError;
+ break;
+ }
+ case "err_no_space":
+ {
+ config = cc._NetworkErrorDialog._config.spaceError;
+ break;
+ }
+ case "err_verify":
+ {
+ config = cc._NetworkErrorDialog._config.verifyError;
+ break;
+ }
+ default:
+ {
+ cc.log("type is not found");
+ return;
+ }
+ }
+ if (!networkDialog.getParent()) {
+
+ config.confirmBtn = config.confirmBtn || {};
+ config.confirmBtn.callback = function () {
+ if (confirmCb)
+ confirmCb();
+ }
+
+ config.cancelBtn = config.cancelBtn || {};
+ config.cancelBtn.callback = function () {
+ if (cancelCb)
+ cancelCb();
+ }
+
+ config.messageLabel = config.messageLabel || {};
+ if (typeof config.messageLabel.text == "undefined") {
+ config.messageLabel.text = tips;
+ }
+
+ networkDialog.setConfig(config);
+ if (cc.director.getRunningScene()) {
+ cc.director.getRunningScene().addChild(networkDialog, INT_MAX);
+ } else {
+ cc.log("Current scene is null we can't show dialog");
+ }
+ }
+}
+
+cc._NetworkErrorDialog._setConfig = function (key, config) {
+ if (key && config) {
+ switch (key) {
+ case "err_network":
+ {
+ cc._NetworkErrorDialog._config.networkError = config;
+ break;
+ }
+ case "err_no_space":
+ {
+ cc._NetworkErrorDialog._config.spaceError = config;
+ break;
+ }
+ case "err_verify":
+ {
+ cc._NetworkErrorDialog._config.verifyError = config;
+ break;
+ }
+ }
+ }
+}
+
+cc.runtime = cc.runtime || {};
+
+cc.runtime.setOption = function (promptype, config) {
+ if (config) {
+ switch (promptype) {
+ case "network_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_network", config);
+ break;
+ }
+ case "no_space_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_no_space", config);
+ break;
+ }
+ case "verify_error_dialog":
+ {
+ cc._NetworkErrorDialog._setConfig("err_verify", config);
+ break;
+ }
+ default :
+ {
+ cc.log("promptype not found please check your promptype");
+ }
+ }
+ } else {
+ cc.log("config is null please check your config");
+ }
+}
+
+/**
+ * only use in JSB get network type
+ * @type {{}|*|cc.network}
+ */
+cc.network = cc.network || {};
+cc.network.type = {
+ NO_NETWORK: -1,
+ MOBILE: 0,
+ WIFI: 1
+}
+cc.network.preloadstatus = {
+ DOWNLOAD: 1,
+ UNZIP: 2
+}
+cc.runtime.network = cc.network;
+
+})();
+
+cc.LoaderScene._preload = cc.LoaderScene.preload;
+cc.LoaderScene.preload = function (arr, cb, target) {
+ // No extension
+ var isGroups = (arr[0] && arr[0].indexOf('.') === -1);
+ if (isGroups) {
+ if (arr.indexOf('boot') === -1) {
+ arr.splice(0, 0, 'boot');
+ }
+ cc.LoaderLayer.preload(arr, cb, target);
+ }
+ else {
+ cc.LoaderScene._preload(arr, cb, target);
+ }
+}
diff --git a/extensions/spine/CCSkeleton.js b/extensions/spine/CCSkeleton.js
index 27e1ac1763..97a99f4edb 100644
--- a/extensions/spine/CCSkeleton.js
+++ b/extensions/spine/CCSkeleton.js
@@ -31,33 +31,7 @@
*/
var sp = sp || {};
-/**
- * The vertex index of spine.
- * @constant
- * @type {{X1: number, Y1: number, X2: number, Y2: number, X3: number, Y3: number, X4: number, Y4: number}}
- */
-sp.VERTEX_INDEX = {
- X1: 0,
- Y1: 1,
- X2: 2,
- Y2: 3,
- X3: 4,
- Y3: 5,
- X4: 6,
- Y4: 7
-};
-
-/**
- * The attachment type of spine. It contains three type: REGION(0), BOUNDING_BOX(1), MESH(2) and SKINNED_MESH.
- * @constant
- * @type {{REGION: number, BOUNDING_BOX: number, REGION_SEQUENCE: number, MESH: number}}
- */
-sp.ATTACHMENT_TYPE = {
- REGION: 0,
- BOUNDING_BOX: 1,
- MESH: 2,
- SKINNED_MESH:3
-};
+var spine = sp.spine;
/**
*
@@ -78,14 +52,12 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
_premultipliedAlpha: false,
_ownsSkeletonData: null,
_atlas: null,
- _blendFunc: null,
/**
* The constructor of sp.Skeleton. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
*/
ctor:function(skeletonDataFile, atlasFile, scale){
cc.Node.prototype.ctor.call(this);
- this._blendFunc = {src: cc.BLEND_SRC, dst: cc.BLEND_DST};
if(arguments.length === 0)
this.init();
@@ -94,7 +66,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
},
_createRenderCmd:function () {
- if(cc._renderType === cc._RENDER_TYPE_CANVAS)
+ if(cc._renderType === cc.game.RENDER_TYPE_CANVAS)
return new sp.Skeleton.CanvasRenderCmd(this);
else
return new sp.Skeleton.WebGLRenderCmd(this);
@@ -105,12 +77,19 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
*/
init: function () {
cc.Node.prototype.init.call(this);
- //this.setOpacityModifyRGB(true);
- this._blendFunc.src = cc.ONE;
- this._blendFunc.dst = cc.ONE_MINUS_SRC_ALPHA;
+ this._premultipliedAlpha = (cc._renderType === cc.game.RENDER_TYPE_WEBGL && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA);
+ },
+
+ onEnter: function () {
+ cc.Node.prototype.onEnter.call(this);
this.scheduleUpdate();
},
+ onExit: function () {
+ this.unscheduleUpdate();
+ cc.Node.prototype.onExit.call(this);
+ },
+
/**
* Sets whether open debug slots.
* @param {boolean} enable true to open, false to close.
@@ -173,7 +152,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Initializes sp.Skeleton with Data.
- * @param {spine.SkeletonData|String} skeletonDataFile
+ * @param {sp.spine.SkeletonData|String} skeletonDataFile
* @param {String|spine.Atlas|spine.SkeletonData} atlasFile atlas filename or atlas data or owns SkeletonData
* @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
*/
@@ -185,7 +164,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
if (cc.isString(argAtlasFile)) {
var data = cc.loader.getRes(argAtlasFile);
sp._atlasLoader.setAtlasFile(argAtlasFile);
- atlas = new spine.Atlas(data, sp._atlasLoader);
+ atlas = new spine.TextureAtlas(data, sp._atlasLoader.load.bind(sp._atlasLoader));
} else {
atlas = atlasFile;
}
@@ -213,38 +192,25 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
*/
getBoundingBox: function () {
var minX = cc.FLT_MAX, minY = cc.FLT_MAX, maxX = cc.FLT_MIN, maxY = cc.FLT_MIN;
- var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices = [],
- slots = this._skeleton.slots, VERTEX = sp.VERTEX_INDEX;
+ var scaleX = this.getScaleX(), scaleY = this.getScaleY(), vertices,
+ slots = this._skeleton.slots, VERTEX = spine.RegionAttachment;
for (var i = 0, slotCount = slots.length; i < slotCount; ++i) {
var slot = slots[i];
- if (!slot.attachment || slot.attachment.type != sp.ATTACHMENT_TYPE.REGION)
- continue;
var attachment = slot.attachment;
- this._computeRegionAttachmentWorldVertices(attachment, slot.bone.skeleton.x, slot.bone.skeleton.y, slot.bone, vertices);
- minX = Math.min(minX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- minY = Math.min(minY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
- maxX = Math.max(maxX, vertices[VERTEX.X1] * scaleX, vertices[VERTEX.X4] * scaleX, vertices[VERTEX.X2] * scaleX, vertices[VERTEX.X3] * scaleX);
- maxY = Math.max(maxY, vertices[VERTEX.Y1] * scaleY, vertices[VERTEX.Y4] * scaleY, vertices[VERTEX.Y2] * scaleY, vertices[VERTEX.Y3] * scaleY);
+ if (!attachment || !(attachment instanceof spine.RegionAttachment))
+ continue;
+ vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ minX = Math.min(minX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ minY = Math.min(minY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
+ maxX = Math.max(maxX, vertices[VERTEX.OX1] * scaleX, vertices[VERTEX.OX4] * scaleX, vertices[VERTEX.OX2] * scaleX, vertices[VERTEX.OX3] * scaleX);
+ maxY = Math.max(maxY, vertices[VERTEX.OY1] * scaleY, vertices[VERTEX.OY4] * scaleY, vertices[VERTEX.OY2] * scaleY, vertices[VERTEX.OY3] * scaleY);
}
var position = this.getPosition();
return cc.rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
},
- _computeRegionAttachmentWorldVertices : function(self, x, y, bone, vertices){
- var offset = self.offset, vertexIndex = sp.VERTEX_INDEX;
- x += bone.worldX;
- y += bone.worldY;
- vertices[vertexIndex.X1] = offset[vertexIndex.X1] * bone.m00 + offset[vertexIndex.Y1] * bone.m01 + x;
- vertices[vertexIndex.Y1] = offset[vertexIndex.X1] * bone.m10 + offset[vertexIndex.Y1] * bone.m11 + y;
- vertices[vertexIndex.X2] = offset[vertexIndex.X2] * bone.m00 + offset[vertexIndex.Y2] * bone.m01 + x;
- vertices[vertexIndex.Y2] = offset[vertexIndex.X2] * bone.m10 + offset[vertexIndex.Y2] * bone.m11 + y;
- vertices[vertexIndex.X3] = offset[vertexIndex.X3] * bone.m00 + offset[vertexIndex.Y3] * bone.m01 + x;
- vertices[vertexIndex.Y3] = offset[vertexIndex.X3] * bone.m10 + offset[vertexIndex.Y3] * bone.m11 + y;
- vertices[vertexIndex.X4] = offset[vertexIndex.X4] * bone.m00 + offset[vertexIndex.Y4] * bone.m01 + x;
- vertices[vertexIndex.Y4] = offset[vertexIndex.X4] * bone.m10 + offset[vertexIndex.Y4] * bone.m11 + y;
- },
-
/**
* Computes the world SRT from the local SRT for each bone.
*/
@@ -276,7 +242,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a bone by name. This does a string comparison for every bone.
* @param {String} boneName
- * @returns {spine.Bone}
+ * @returns {sp.spine.Bone}
*/
findBone: function (boneName) {
return this._skeleton.findBone(boneName);
@@ -285,7 +251,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a slot by name. This does a string comparison for every slot.
* @param {String} slotName
- * @returns {spine.Slot}
+ * @returns {sp.spine.Slot}
*/
findSlot: function (slotName) {
return this._skeleton.findSlot(slotName);
@@ -294,7 +260,7 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Finds a skin by name and makes it the active skin. This does a string comparison for every skin. Note that setting the skin does not change which attachments are visible.
* @param {string} skinName
- * @returns {spine.Skin}
+ * @returns {sp.spine.Skin}
*/
setSkin: function (skinName) {
return this._skeleton.setSkinByName(skinName);
@@ -304,10 +270,10 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* Returns the attachment for the slot and attachment name. The skeleton looks first in its skin, then in the skeleton data’s default skin.
* @param {String} slotName
* @param {String} attachmentName
- * @returns {spine.RegionAttachment|spine.BoundingBoxAttachment}
+ * @returns {sp.spine.Attachment}
*/
getAttachment: function (slotName, attachmentName) {
- return this._skeleton.getAttachmentBySlotName(slotName, attachmentName);
+ return this._skeleton.getAttachmentByName(slotName, attachmentName);
},
/**
@@ -323,22 +289,22 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* Sets the premultiplied alpha value to sp.Skeleton.
* @param {Number} alpha
*/
- setOpacityModifyRGB: function (alpha) {
- this._premultipliedAlpha = alpha;
+ setPremultipliedAlpha: function (premultiplied) {
+ this._premultipliedAlpha = premultiplied;
},
/**
* Returns whether to enable premultiplied alpha.
* @returns {boolean}
*/
- isOpacityModifyRGB: function () {
+ isPremultipliedAlpha: function () {
return this._premultipliedAlpha;
},
/**
* Sets skeleton data to sp.Skeleton.
- * @param {spine.SkeletonData} skeletonData
- * @param {spine.SkeletonData} ownsSkeletonData
+ * @param {sp.spine.SkeletonData} skeletonData
+ * @param {sp.spine.SkeletonData} ownsSkeletonData
*/
setSkeletonData: function (skeletonData, ownsSkeletonData) {
if(skeletonData.width != null && skeletonData.height != null)
@@ -354,11 +320,11 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
/**
* Return the renderer of attachment.
- * @param {spine.RegionAttachment|spine.BoundingBoxAttachment} regionAttachment
- * @returns {cc.Node}
+ * @param {sp.spine.RegionAttachment|sp.spine.BoundingBoxAttachment} regionAttachment
+ * @returns {sp.spine.TextureAtlasRegion}
*/
getTextureAtlas: function (regionAttachment) {
- return regionAttachment.rendererObject.page.rendererObject;
+ return regionAttachment.region;
},
/**
@@ -366,23 +332,23 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
* @returns {cc.BlendFunc}
*/
getBlendFunc: function () {
- return this._blendFunc;
+ var slot = this._skeleton.drawOrder[0];
+ if (slot) {
+ var blend = this._renderCmd._getBlendFunc(slot.data.blendMode, this._premultipliedAlpha);
+ return blend;
+ }
+ else {
+ return {};
+ }
},
/**
- * Sets the blendFunc of sp.Skeleton.
+ * Sets the blendFunc of sp.Skeleton, it won't have any effect for skeleton, skeleton is using slot's data to determine the blend function.
* @param {cc.BlendFunc|Number} src
* @param {Number} [dst]
*/
setBlendFunc: function (src, dst) {
- var locBlendFunc = this._blendFunc;
- if (dst === undefined) {
- locBlendFunc.src = src.src;
- locBlendFunc.dst = src.dst;
- } else {
- locBlendFunc.src = src;
- locBlendFunc.dst = dst;
- }
+ return;
},
/**
@@ -394,6 +360,14 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
}
});
+cc.defineGetterSetter(sp.Skeleton.prototype, "opacityModifyRGB", sp.Skeleton.prototype.isOpacityModifyRGB);
+
+// For renderer webgl to identify skeleton's default texture and blend function
+cc.defineGetterSetter(sp.Skeleton.prototype, "_blendFunc", sp.Skeleton.prototype.getBlendFunc);
+cc.defineGetterSetter(sp.Skeleton.prototype, '_texture', function () {
+ return this._renderCmd._currTexture;
+});
+
/**
* Creates a skeleton object.
* @deprecated since v3.0, please use new sp.Skeleton(skeletonDataFile, atlasFile, scale) instead.
@@ -404,4 +378,4 @@ sp.Skeleton = cc.Node.extend(/** @lends sp.Skeleton# */{
*/
sp.Skeleton.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
return new sp.Skeleton(skeletonDataFile, atlasFile, scale);
-};
\ No newline at end of file
+};
diff --git a/extensions/spine/CCSkeletonAnimation.js b/extensions/spine/CCSkeletonAnimation.js
index f351d83c80..17f0f25675 100644
--- a/extensions/spine/CCSkeletonAnimation.js
+++ b/extensions/spine/CCSkeletonAnimation.js
@@ -24,35 +24,17 @@
THE SOFTWARE.
****************************************************************************/
-/**
- * @ignore
- */
-sp._atlasPage_createTexture_webGL = function (self, path) {
- var texture = cc.textureCache.addImage(path);
- self.rendererObject = new cc.TextureAtlas(texture, 128);
- self.width = texture.getPixelsWide();
- self.height = texture.getPixelsHigh();
-};
-
-sp._atlasPage_createTexture_canvas = function(self, path) {
- self._texture = cc.textureCache.addImage(path);
-};
-
-sp._atlasPage_disposeTexture = function (self) {
- self.rendererObject.release();
-};
-
sp._atlasLoader = {
spAtlasFile:null,
setAtlasFile:function(spAtlasFile){
this.spAtlasFile = spAtlasFile;
},
- load:function(page, line, spAtlas){
+ load:function(line){
var texturePath = cc.path.join(cc.path.dirname(this.spAtlasFile), line);
- if (cc._renderType === cc._RENDER_TYPE_WEBGL)
- sp._atlasPage_createTexture_webGL(page,texturePath);
- else
- sp._atlasPage_createTexture_canvas(page,texturePath);
+ var texture = cc.textureCache.addImage(texturePath);
+ var tex = new sp.SkeletonTexture({ width: texture.getPixelsWide(), height: texture.getPixelsHigh() });
+ tex.setRealTexture(texture);
+ return tex;
},
unload:function(obj){
}
@@ -65,28 +47,86 @@ sp._atlasLoader = {
*/
sp.ANIMATION_EVENT_TYPE = {
START: 0,
- END: 1,
- COMPLETE: 2,
- EVENT: 3
+ INTERRUPT: 1,
+ END: 2,
+ DISPOSE: 3,
+ COMPLETE: 4,
+ EVENT: 5
};
-sp.TrackEntryListeners = function(startListener, endListener, completeListener, eventListener){
+sp.TrackEntryListeners = function (startListener, endListener, completeListener, eventListener, interruptListener, disposeListener) {
this.startListener = startListener || null;
this.endListener = endListener || null;
this.completeListener = completeListener || null;
this.eventListener = eventListener || null;
+ this.interruptListener = interruptListener || null;
+ this.disposeListener = disposeListener || null;
+ this.callback = null;
+ this.callbackTarget = null;
+ this.skeletonNode = null;
};
-sp.TrackEntryListeners.getListeners = function(entry){
- if(!entry.rendererObject){
- entry.rendererObject = new sp.TrackEntryListeners();
- entry.listener = sp.trackEntryCallback;
+var proto = sp.TrackEntryListeners.prototype;
+proto.start = function(trackEntry) {
+ if (this.startListener) {
+ this.startListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.START, null, 0);
+ }
+};
+
+proto.interrupt = function(trackEntry) {
+ if (this.interruptListener) {
+ this.interruptListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.INTERRUPT, null, 0);
}
- return entry.rendererObject;
};
-sp.trackEntryCallback = function(state, trackIndex, type, event, loopCount) {
- state.rendererObject.onTrackEntryEvent(trackIndex, type, event, loopCount);
+proto.end = function (trackEntry) {
+ if (this.endListener) {
+ this.endListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.END, null, 0);
+ }
+};
+
+proto.dispose = function (trackEntry) {
+ if (this.disposeListener) {
+ this.disposeListener(trackEntry);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.DISPOSE, null, 0);
+ }
+};
+
+proto.complete = function (trackEntry) {
+ var loopCount = Math.floor(trackEntry.trackTime / trackEntry.animationEnd);
+ if (this.completeListener) {
+ this.completeListener(trackEntry, loopCount);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.COMPLETE, null, loopCount);
+ }
+};
+
+proto.event = function (trackEntry, event) {
+ if (this.eventListener) {
+ this.eventListener(trackEntry, event);
+ }
+ if (this.callback) {
+ this.callback.call(this.callbackTarget, this.skeletonNode, trackEntry, sp.ANIMATION_EVENT_TYPE.EVENT, event, 0);
+ }
+};
+
+sp.TrackEntryListeners.getListeners = function(entry){
+ if(!entry.listener){
+ entry.listener = new sp.TrackEntryListeners();
+ }
+ return entry.listener;
};
/**
@@ -99,14 +139,9 @@ sp.trackEntryCallback = function(state, trackIndex, type, event, loopCount) {
*/
sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
_state: null,
- _target: null,
- _callback: null,
_ownsAnimationStateData: false,
- _startListener: null,
- _endListener: null,
- _completeListener: null,
- _eventListener: null,
+ _listener: null,
/**
* Initializes a sp.SkeletonAnimation. please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
@@ -120,15 +155,13 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
/**
* Sets animation state data to sp.SkeletonAnimation.
- * @param {spine.AnimationStateData} stateData
+ * @param {sp.spine.AnimationStateData} stateData
*/
setAnimationStateData: function (stateData) {
var state = new spine.AnimationState(stateData);
+ this._listener = new sp.TrackEntryListeners();
state.rendererObject = this;
- state.onStart = this._onAnimationStateStart.bind(this);
- state.onComplete = this._onAnimationStateComplete.bind(this);
- state.onEnd = this._onAnimationStateEnd.bind(this);
- state.onEvent = this._onAnimationStateEvent.bind(this);
+ state.addListener(this._listener);
this._state = state;
},
@@ -139,7 +172,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Number} duration
*/
setMix: function (fromAnimation, toAnimation, duration) {
- this._state.data.setMixByName(fromAnimation, toAnimation, duration);
+ this._state.data.setMixWith(fromAnimation, toAnimation, duration);
},
/**
@@ -148,8 +181,9 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Function} callback
*/
setAnimationListener: function (target, callback) {
- this._target = target;
- this._callback = callback;
+ this._listener.callbackTarget = target;
+ this._listener.callback = callback;
+ this._listener.skeletonNode = this;
},
/**
@@ -157,7 +191,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Number} trackIndex
* @param {String} name
* @param {Boolean} loop
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
setAnimation: function (trackIndex, name, loop) {
var animation = this._skeleton.data.findAnimation(name);
@@ -165,7 +199,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
cc.log("Spine: Animation not found: " + name);
return null;
}
- return this._state.setAnimation(trackIndex, animation, loop);
+ return this._state.setAnimationWith(trackIndex, animation, loop);
},
/**
@@ -174,7 +208,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {String} name
* @param {Boolean} loop
* @param {Number} [delay=0]
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
addAnimation: function (trackIndex, name, loop, delay) {
delay = delay == null ? 0 : delay;
@@ -183,13 +217,22 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
cc.log("Spine: Animation not found:" + name);
return null;
}
- return this._state.addAnimation(trackIndex, animation, loop, delay);
+ return this._state.addAnimationWith(trackIndex, animation, loop, delay);
+ },
+
+ /**
+ * Find animation with specified name
+ * @param {String} name
+ * @returns {sp.spine.Animation|null}
+ */
+ findAnimation: function (name) {
+ return this._skeleton.data.findAnimation(name);
},
/**
* Returns track entry by trackIndex.
* @param trackIndex
- * @returns {spine.TrackEntry|null}
+ * @returns {sp.spine.TrackEntry|null}
*/
getCurrent: function (trackIndex) {
return this._state.getCurrent(trackIndex);
@@ -219,6 +262,7 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
update: function (dt) {
this._super(dt);
dt *= this._timeScale;
+ this._renderCmd.setDirtyFlag(cc.Node._dirtyFlags.contentDirty);
this._state.update(dt);
this._state.apply(this._skeleton);
this._skeleton.updateWorldTransform();
@@ -230,7 +274,15 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {function} listener
*/
setStartListener: function(listener){
- this._startListener = listener;
+ this._listener.startListener = listener;
+ },
+
+ /**
+ * Set the interrupt listener
+ * @param {function} listener
+ */
+ setInterruptListener: function(listener) {
+ this._listener.interruptListener = listener;
},
/**
@@ -238,25 +290,41 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {function} listener
*/
setEndListener: function(listener) {
- this._endListener = listener;
+ this._listener.endListener = listener;
+ },
+
+ /**
+ * Set the dispose listener
+ * @param {function} listener
+ */
+ setDisposeListener: function(listener) {
+ this._listener.disposeListener = listener;
},
setCompleteListener: function(listener) {
- this._completeListener = listener;
+ this._listener.completeListener = listener;
},
setEventListener: function(listener){
- this._eventListener = listener;
+ this._listener.eventListener = listener;
},
setTrackStartListener: function(entry, listener){
sp.TrackEntryListeners.getListeners(entry).startListener = listener;
},
+ setTrackInterruptListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).interruptListener = listener;
+ },
+
setTrackEndListener: function(entry, listener){
sp.TrackEntryListeners.getListeners(entry).endListener = listener;
},
+ setTrackDisposeListener: function(entry, listener){
+ sp.TrackEntryListeners.getListeners(entry).disposeListener = listener;
+ },
+
setTrackCompleteListener: function(entry, listener){
sp.TrackEntryListeners.getListeners(entry).completeListener = listener;
},
@@ -265,73 +333,8 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
sp.TrackEntryListeners.getListeners(entry).eventListener = listener;
},
- onTrackEntryEvent: function(traceIndex, type, event, loopCount){
- var entry = this._state.getCurrent(traceIndex);
- if(!entry.rendererObject)
- return;
- var listeners = entry.rendererObject;
- switch (type){
- case sp.ANIMATION_EVENT_TYPE.START:
- if(listeners.startListener)
- listeners.startListener(traceIndex);
- break;
- case sp.ANIMATION_EVENT_TYPE.END:
- if(listeners.endListener)
- listeners.endListener(traceIndex);
- break;
- case sp.ANIMATION_EVENT_TYPE.COMPLETE:
- if(listeners.completeListener)
- listeners.completeListener(traceIndex, loopCount);
- break;
- case sp.ANIMATION_EVENT_TYPE.EVENT:
- if(listeners.eventListener)
- listeners.eventListener(traceIndex, event);
- break;
- }
- },
-
- onAnimationStateEvent: function(trackIndex, type, event, loopCount) {
- switch(type){
- case sp.ANIMATION_EVENT_TYPE.START:
- if(this._startListener)
- this._startListener(trackIndex);
- break;
- case sp.ANIMATION_EVENT_TYPE.END:
- if(this._endListener)
- this._endListener(trackIndex);
- break;
- case sp.ANIMATION_EVENT_TYPE.COMPLETE:
- if(this._completeListener)
- this._completeListener(trackIndex, loopCount);
- break;
- case sp.ANIMATION_EVENT_TYPE.EVENT:
- if(this._eventListener)
- this._eventListener(trackIndex, event);
- break;
- }
- },
-
getState: function(){
return this._state;
- },
-
- _onAnimationStateStart: function (trackIndex) {
- this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.START, null, 0);
- },
- _onAnimationStateEnd: function (trackIndex) {
- this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.END, null, 0);
- },
- _onAnimationStateComplete: function (trackIndex, count) {
- this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.COMPLETE, null, count);
- },
- _onAnimationStateEvent: function (trackIndex, event) {
- this._animationStateCallback(trackIndex, sp.ANIMATION_EVENT_TYPE.EVENT, event, 0);
- },
- _animationStateCallback: function (trackIndex, type, event, loopCount) {
- this.onAnimationStateEvent(trackIndex, type, event, loopCount);
- if (this._target && this._callback) {
- this._callback.call(this._target, this, trackIndex, type, event, loopCount)
- }
}
});
@@ -343,6 +346,6 @@ sp.SkeletonAnimation = sp.Skeleton.extend(/** @lends sp.SkeletonAnimation# */{
* @param {Number} [scale] scale can be specified on the JSON or binary loader which will scale the bone positions, image sizes, and animation translations.
* @returns {sp.Skeleton}
*/
-sp.SkeletonAnimation.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
+sp.SkeletonAnimation.createWithJsonFile = sp.SkeletonAnimation.create = function (skeletonDataFile, atlasFile/* or atlas*/, scale) {
return new sp.SkeletonAnimation(skeletonDataFile, atlasFile, scale);
-};
\ No newline at end of file
+};
diff --git a/extensions/spine/CCSkeletonCanvasRenderCmd.js b/extensions/spine/CCSkeletonCanvasRenderCmd.js
index 1b4f873cd1..f31924ec19 100644
--- a/extensions/spine/CCSkeletonCanvasRenderCmd.js
+++ b/extensions/spine/CCSkeletonCanvasRenderCmd.js
@@ -22,192 +22,226 @@
THE SOFTWARE.
****************************************************************************/
-(function(){
- sp.Skeleton.CanvasRenderCmd = function(renderableObject){
- cc.Node.CanvasRenderCmd.call(this, renderableObject);
- this._needDraw = true;
- };
-
- var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
- proto.constructor = sp.Skeleton.CanvasRenderCmd;
-
- proto.rendering = function (wrapper, scaleX, scaleY) {
- var node = this._node, i, n, slot, slotNode;
- wrapper = wrapper || cc._renderContext;
-
- var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
- for(i = 0, n = drawOrder.length; i < n; i++){
- slot = drawOrder[i];
- slotNode = slot._slotNode;
- if(slotNode._visible && slotNode._renderCmd && slot.currentSprite){
- slotNode._renderCmd.transform(this, true);
- slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
- slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
- }
+(function () {
+
+var spine = sp.spine;
+
+sp.Skeleton.CanvasRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+};
+
+var proto = sp.Skeleton.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
+proto.constructor = sp.Skeleton.CanvasRenderCmd;
+
+proto.rendering = function (wrapper, scaleX, scaleY) {
+ var node = this._node, i, n, slot, slotNode;
+ wrapper = wrapper || cc._renderContext;
+
+ var locSkeleton = node._skeleton, drawOrder = locSkeleton.drawOrder;
+ for (i = 0, n = drawOrder.length; i < n; i++) {
+ slot = drawOrder[i];
+ slotNode = slot._slotNode;
+ if (slotNode._visible && slotNode._renderCmd && slot.currentSprite) {
+ slotNode._renderCmd.transform(this, true);
+ slot.currentSprite._renderCmd.rendering(wrapper, scaleX, scaleY);
+ slotNode._renderCmd._dirtyFlag = slot.currentSprite._renderCmd._dirtyFlag = 0;
}
-
- if (!node._debugSlots && !node._debugBones)
- return;
-
- wrapper.setTransform(this._worldTransform, scaleX, scaleY);
- wrapper.setGlobalAlpha(1);
- var attachment, drawingUtil = cc._drawingUtil;
- if (node._debugSlots) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- var points = [];
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment || slot.attachment.type != sp.ATTACHMENT_TYPE.REGION)
- continue;
- attachment = slot.attachment;
- this._updateRegionAttachmentSlot(attachment, slot, points);
- drawingUtil.drawPoly(points, 4, true);
- }
+ }
+
+ if (!node._debugSlots && !node._debugBones)
+ return;
+
+ wrapper.setTransform(this._worldTransform, scaleX, scaleY);
+ wrapper.setGlobalAlpha(1);
+ var attachment, drawingUtil = cc._drawingUtil;
+ if (node._debugSlots) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ var points = [];
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment || !(slot.attachment instanceof spine.RegionAttachment))
+ continue;
+ attachment = slot.attachment;
+ this._updateRegionAttachmentSlot(attachment, slot, points);
+ drawingUtil.drawPoly(points, 4, true);
+ }
+ }
+
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(
+ {x: bone.worldX, y: bone.worldY},
+ {x: x, y: y});
}
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.m00 + bone.worldX;
- var y = bone.data.length * bone.m10 + bone.worldY;
- drawingUtil.drawLine(
- {x: bone.worldX, y: bone.worldY},
- {x: x, y: y});
- }
-
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+ // Bone origins.
+ var pointSize = 4;
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY});
- if (i === 0)
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint({x: bone.worldX, y: bone.worldY}, pointSize);
+ if (i === 0)
+ drawingUtil.setDrawColor(0, 255, 0, 255);
}
- };
-
- proto._updateRegionAttachmentSlot = function(attachment, slot, points) {
- if(!points)
- return;
-
- var vertices = {}, VERTEX = sp.VERTEX_INDEX, bone = slot.bone;
- attachment.computeVertices(bone.skeleton.x, bone.skeleton.y, bone, vertices);
- points.length = 0;
- points.push(cc.p(vertices[VERTEX.X1], vertices[VERTEX.Y1]));
- points.push(cc.p(vertices[VERTEX.X4], vertices[VERTEX.Y4]));
- points.push(cc.p(vertices[VERTEX.X3], vertices[VERTEX.Y3]));
- points.push(cc.p(vertices[VERTEX.X2], vertices[VERTEX.Y2]));
- };
-
- proto._createChildFormSkeletonData = function(){
- var node = this._node;
- var locSkeleton = node._skeleton, spriteName, sprite;
- for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
- var slot = locSkeleton.slots[i], attachment = slot.attachment;
- var slotNode = new cc.Node();
- slot._slotNode = slotNode;
-
- if(attachment instanceof spine.RegionAttachment){
- spriteName = attachment.rendererObject.name;
- sprite = this._createSprite(slot, attachment);
- slot.currentSprite = sprite;
- slot.currentSpriteName = spriteName;
- slotNode.addChild(sprite);
- } else if(attachment instanceof spine.MeshAttachment){
- //todo for mesh
- }
+ }
+};
+
+proto.updateStatus = function() {
+ this.originUpdateStatus();
+ this._updateCurrentRegions();
+ this._regionFlag = cc.Node.CanvasRenderCmd.RegionStatus.DirtyDouble;
+ this._dirtyFlag &= ~cc.Node._dirtyFlags.contentDirty;
+};
+
+proto.getLocalBB = function() {
+ return this._node.getBoundingBox();
+};
+
+proto._updateRegionAttachmentSlot = function (attachment, slot, points) {
+ if (!points)
+ return;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+ var VERTEX = spine.RegionAttachment;
+ points.length = 0;
+ points.push(cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]));
+ points.push(cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4]));
+ points.push(cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]));
+ points.push(cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]));
+};
+
+proto._createChildFormSkeletonData = function () {
+ var node = this._node;
+ var locSkeleton = node._skeleton, spriteName, sprite;
+ for (var i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var slot = locSkeleton.slots[i], attachment = slot.attachment;
+ var slotNode = new cc.Node();
+ slot._slotNode = slotNode;
+
+ if (attachment instanceof spine.RegionAttachment) {
+ spriteName = attachment.region.name;
+ sprite = this._createSprite(slot, attachment);
+ slot.currentSprite = sprite;
+ slot.currentSpriteName = spriteName;
+ slotNode.addChild(sprite);
+ } else if (attachment instanceof spine.MeshAttachment) {
+ //todo for mesh
}
- };
-
- proto._createSprite = function(slot, attachment){
- var rendererObject = attachment.rendererObject;
- var texture = rendererObject.page._texture;
- var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
- var sprite = new cc.Sprite();
- sprite.initWithTexture(rendererObject.page._texture, rect, rendererObject.rotate, false);
- sprite._rect.width = attachment.width;
- sprite._rect.height = attachment.height;
- sprite.setContentSize(attachment.width, attachment.height);
- sprite.setRotation(-attachment.rotation);
- sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
- rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
-
- slot.sprites = slot.sprites || {};
- slot.sprites[rendererObject.name] = sprite;
-
- return sprite;
- };
-
- proto._updateChild = function(){
- var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
- var i, n, selSprite;
-
- var slot, attachment, slotNode;
- for(i = 0, n = slots.length; i < n; i++){
- slot = slots[i];
- attachment = slot.attachment;
- slotNode = slot._slotNode;
- if(!attachment){
- slotNode.setVisible(false);
- continue;
- }
- var type = attachment.type;
- if (type === spine.AttachmentType.region){
- if(attachment.rendererObject){
- if(!slot.currentSpriteName || slot.currentSpriteName !== attachment.name){
- var spriteName = attachment.rendererObject.name;
- if(slot.currentSprite !== undefined)
- slot.currentSprite.setVisible(false);
- slot.sprites = slot.sprites ||{};
- if(slot.sprites[spriteName] !== undefined)
- slot.sprites[spriteName].setVisible(true);
- else{
- var sprite = this._createSprite(slot, attachment);
- slotNode.addChild(sprite);
- }
- slot.currentSprite = slot.sprites[spriteName];
- slot.currentSpriteName = spriteName;
+ }
+};
+
+var loaded = function (sprite, texture, attachment) {
+ var rendererObject = attachment.region;
+ var rect = new cc.Rect(rendererObject.x, rendererObject.y, rendererObject.width, rendererObject.height);
+ sprite.initWithTexture(texture, rect, rendererObject.rotate, false);
+ sprite._rect.width = attachment.width;
+ sprite._rect.height = attachment.height;
+ sprite.setContentSize(attachment.width, attachment.height);
+ sprite.setRotation(-attachment.rotation);
+ sprite.setScale(rendererObject.width / rendererObject.originalWidth * attachment.scaleX,
+ rendererObject.height / rendererObject.originalHeight * attachment.scaleY);
+};
+
+proto._createSprite = function (slot, attachment) {
+ var rendererObject = attachment.region;
+ var texture = rendererObject.texture.getRealTexture();
+ var sprite = new cc.Sprite();
+ if (texture.isLoaded()) {
+ loaded(sprite, texture, attachment);
+ } else {
+ texture.addEventListener('load', function () {
+ loaded(sprite, texture, attachment);
+ }, this);
+ }
+ slot.sprites = slot.sprites || {};
+ slot.sprites[rendererObject.name] = sprite;
+ return sprite;
+};
+
+proto._updateChild = function () {
+ var locSkeleton = this._node._skeleton, slots = locSkeleton.slots;
+ var color = this._displayedColor, opacity = this._displayedOpacity;
+ var i, n, selSprite, ax, ay;
+
+ var slot, attachment, slotNode;
+ for (i = 0, n = slots.length; i < n; i++) {
+ slot = slots[i];
+ attachment = slot.attachment;
+ slotNode = slot._slotNode;
+ if (!attachment) {
+ slotNode.setVisible(false);
+ continue;
+ }
+ if (attachment instanceof spine.RegionAttachment) {
+ if (attachment.region) {
+ if (!slot.currentSpriteName || slot.currentSpriteName !== attachment.name) {
+ var spriteName = attachment.region.name;
+ if (slot.currentSprite !== undefined)
+ slot.currentSprite.setVisible(false);
+ slot.sprites = slot.sprites || {};
+ if (slot.sprites[spriteName] !== undefined)
+ slot.sprites[spriteName].setVisible(true);
+ else {
+ var sprite = this._createSprite(slot, attachment);
+ slotNode.addChild(sprite);
}
+ slot.currentSprite = slot.sprites[spriteName];
+ slot.currentSpriteName = spriteName;
}
- var bone = slot.bone;
- slotNode.setPosition(bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01,
- bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11);
- slotNode.setScale(bone.worldScaleX, bone.worldScaleY);
-
- //set the color and opacity
- selSprite = slot.currentSprite;
- selSprite._flippedX = bone.worldFlipX;
- selSprite._flippedY = bone.worldFlipY;
- if(selSprite._flippedY || selSprite._flippedX){
- slotNode.setRotation(bone.worldRotation);
- selSprite.setRotation(attachment.rotation);
- }else{
- slotNode.setRotation(-bone.worldRotation);
- selSprite.setRotation(-attachment.rotation);
- }
-
- //hack for sprite
- selSprite._renderCmd._displayedOpacity = 0 | (locSkeleton.a * slot.a * 255);
- var r = 0 | (locSkeleton.r * slot.r * 255), g = 0 | (locSkeleton.g * slot.g * 255), b = 0 | (locSkeleton.b * slot.b * 255);
- selSprite.setColor(cc.color(r,g,b));
- selSprite._renderCmd._updateColor();
- } else if (type === spine.AttachmentType.skinnedmesh) {
- //todo for mesh
+ }
+ var bone = slot.bone;
+ if (attachment.region.offsetX === 0 && attachment.region.offsetY === 0) {
+ ax = attachment.x;
+ ay = attachment.y;
+ }
+ else {
+ //var regionScaleX = attachment.width / attachment.regionOriginalWidth * attachment.scaleX;
+ //ax = attachment.x + attachment.regionOffsetX * regionScaleX - (attachment.width * attachment.scaleX - attachment.regionWidth * regionScaleX) / 2;
+ ax = (attachment.offset[0] + attachment.offset[4]) * 0.5;
+ ay = (attachment.offset[1] + attachment.offset[5]) * 0.5;
+ }
+ slotNode.setPosition(bone.worldX + ax * bone.a + ay * bone.b, bone.worldY + ax * bone.c + ay * bone.d);
+ slotNode.setScale(bone.getWorldScaleX(), bone.getWorldScaleY());
+
+ //set the color and opacity
+ selSprite = slot.currentSprite;
+ selSprite._flippedX = bone.skeleton.flipX;
+ selSprite._flippedY = bone.skeleton.flipY;
+ if (selSprite._flippedY || selSprite._flippedX) {
+ slotNode.setRotation(bone.getWorldRotationX());
+ selSprite.setRotation(attachment.rotation);
} else {
- slotNode.setVisible(false);
- continue;
+ slotNode.setRotation(-bone.getWorldRotationX());
+ selSprite.setRotation(-attachment.rotation);
}
- slotNode.setVisible(true);
+
+ //hack for sprite
+ selSprite._renderCmd._displayedOpacity = 0 | (opacity * slot.color.a);
+ var r = 0 | (color.r * slot.color.r), g = 0 | (color.g * slot.color.g), b = 0 | (color.b * slot.color.b);
+ selSprite.setColor(cc.color(r, g, b));
+ selSprite._renderCmd._updateColor();
+ } else if (attachment instanceof spine.MeshAttachment) {
+ // Can not render mesh
+ } else {
+ slotNode.setVisible(false);
+ continue;
}
- };
-})();
\ No newline at end of file
+ slotNode.setVisible(true);
+ }
+};
+
+})();
diff --git a/extensions/spine/CCSkeletonTexture.js b/extensions/spine/CCSkeletonTexture.js
new file mode 100644
index 0000000000..9250369c30
--- /dev/null
+++ b/extensions/spine/CCSkeletonTexture.js
@@ -0,0 +1,67 @@
+/****************************************************************************
+ Copyright (c) 2017 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.
+ ****************************************************************************/
+
+sp.SkeletonTexture = function (image) {
+ sp.spine.Texture.call(this, image);
+};
+cc.inherits(sp.SkeletonTexture, sp.spine.Texture);
+cc.extend(sp.SkeletonTexture.prototype, {
+ name: 'sp.SkeletonTexture',
+ _texture: null,
+
+ setRealTexture: function(tex) {
+ this._texture = tex;
+ },
+
+ getRealTexture: function() {
+ return this._texture;
+ },
+
+ setFilters: function(minFilter, magFilter) {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ var gl = cc._renderContext;
+ this.bind();
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
+ }
+ },
+
+ setWraps: function(uWrap, vWrap) {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ var gl = cc._renderContext;
+ this.bind();
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, uWrap);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, vWrap);
+ }
+ },
+
+ dispose: function() {
+ },
+
+ bind: function() {
+ if (cc._renderType === cc.game.RENDER_TYPE_WEBGL) {
+ cc.glBindTexture2D(this._texture);
+ }
+ }
+});
\ No newline at end of file
diff --git a/extensions/spine/CCSkeletonWebGLRenderCmd.js b/extensions/spine/CCSkeletonWebGLRenderCmd.js
index ca0f14b613..535e4c0ac5 100644
--- a/extensions/spine/CCSkeletonWebGLRenderCmd.js
+++ b/extensions/spine/CCSkeletonWebGLRenderCmd.js
@@ -22,225 +22,326 @@
THE SOFTWARE.
****************************************************************************/
-(function(){
- sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
- cc.Node.WebGLRenderCmd.call(this, renderableObject);
- this._needDraw = true;
- this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURECOLOR));
- this._tmpQuad = new cc.V3F_C4B_T2F_Quad();
- };
-
- var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
- proto.constructor = sp.Skeleton.WebGLRenderCmd;
-
- proto.rendering = function (ctx) {
- var node = this._node, tmpQuad = this._tmpQuad;
- this._shaderProgram.use();
- this._shaderProgram._setUniformForMVPMatrixWithMat4(this._stackMatrix);
-// cc.glBlendFunc(this._blendFunc.src, this._blendFunc.dst);
- var color = node.getColor(), locSkeleton = node._skeleton;
- locSkeleton.r = color.r / 255;
- locSkeleton.g = color.g / 255;
- locSkeleton.b = color.b / 255;
- locSkeleton.a = node.getOpacity() / 255;
- if (node._premultipliedAlpha) {
- locSkeleton.r *= locSkeleton.a;
- locSkeleton.g *= locSkeleton.a;
- locSkeleton.b *= locSkeleton.a;
+(function () {
+
+var spine = sp.spine;
+
+sp.Skeleton.WebGLRenderCmd = function (renderableObject) {
+ this._rootCtor(renderableObject);
+ this._needDraw = true;
+ this._matrix = new cc.math.Matrix4();
+ this._matrix.identity();
+ this._currTexture = null;
+ this._currBlendFunc = {};
+ this.vertexType = cc.renderer.VertexType.CUSTOM;
+ this.setShaderProgram(cc.shaderCache.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR));
+};
+
+var proto = sp.Skeleton.WebGLRenderCmd.prototype = Object.create(cc.Node.WebGLRenderCmd.prototype);
+proto.constructor = sp.Skeleton.WebGLRenderCmd;
+
+proto.uploadData = function (f32buffer, ui32buffer, vertexDataOffset){
+ var node = this._node;
+ var color = this._displayedColor, locSkeleton = node._skeleton;
+
+ var attachment, slot, i, n;
+ var premultiAlpha = node._premultipliedAlpha;
+
+ locSkeleton.r = color.r / 255;
+ locSkeleton.g = color.g / 255;
+ locSkeleton.b = color.b / 255;
+ locSkeleton.a = this._displayedOpacity / 255;
+ if (premultiAlpha) {
+ locSkeleton.r *= locSkeleton.a;
+ locSkeleton.g *= locSkeleton.a;
+ locSkeleton.b *= locSkeleton.a;
+ }
+
+ var debugSlotsInfo = null;
+ if (this._node._debugSlots) {
+ debugSlotsInfo = [];
+ }
+
+ for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
+ slot = locSkeleton.drawOrder[i];
+ if (!slot.attachment)
+ continue;
+ attachment = slot.attachment;
+
+ // get the vertices length
+ var vertCount = 0;
+ if (attachment instanceof spine.RegionAttachment) {
+ vertCount = 6; // a quad = two triangles = six vertices
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ vertCount = attachment.regionUVs.length / 2;
+ }
+ else {
+ continue;
}
- var additive, textureAtlas, attachment, slot, i, n;
- var locBlendFunc = node._blendFunc;
-
- //for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- for (i = 0, n = locSkeleton.drawOrder.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment)
- continue;
- attachment = slot.attachment;
-
- switch(slot.attachment.type) {
- case sp.ATTACHMENT_TYPE.REGION:
- this._updateRegionAttachmentQuad(attachment, slot, tmpQuad, node._premultipliedAlpha);
- break;
- case sp.ATTACHMENT_TYPE.MESH:
- this._updateMeshAttachmentQuad(attachment, slot, tmpQuad, node._premultipliedAlpha);
- break;
- case sp.ATTACHMENT_TYPE.SKINNED_MESH:
- break;
- default:
- continue;
- }
+ // no vertices to render
+ if (vertCount === 0) {
+ continue;
+ }
- var regionTextureAtlas = node.getTextureAtlas(attachment);
+ var regionTextureAtlas = node.getTextureAtlas(attachment);
- if (slot.data.additiveBlending != additive) {
- if (textureAtlas) {
- textureAtlas.drawQuads();
- textureAtlas.removeAllQuads();
- }
- additive = !additive;
- cc.glBlendFunc(locBlendFunc.src, additive ? cc.ONE : locBlendFunc.dst);
- } else if (regionTextureAtlas != textureAtlas && textureAtlas) {
- textureAtlas.drawQuads();
- textureAtlas.removeAllQuads();
- }
- textureAtlas = regionTextureAtlas;
-
- var quadCount = textureAtlas.getTotalQuads();
- if (textureAtlas.getCapacity() == quadCount) {
- textureAtlas.drawQuads();
- textureAtlas.removeAllQuads();
- if (!textureAtlas.resizeCapacity(textureAtlas.getCapacity() * 2))
- return;
- }
+ // Broken for changing batch info
+ this._currTexture = regionTextureAtlas.texture.getRealTexture();
+ var batchBroken = cc.renderer._updateBatchedInfo(this._currTexture, this._getBlendFunc(slot.data.blendMode, premultiAlpha), this._glProgramState);
- textureAtlas.updateQuad(tmpQuad, quadCount);
+ // keep the same logic with RendererWebGL.js, avoid vertex data overflow
+ var uploadAll = vertexDataOffset / 6 + vertCount > (cc.BATCH_VERTEX_COUNT - 200) * 0.5;
+ // Broken for vertex data overflow
+ if (!batchBroken && uploadAll) {
+ // render the cached data
+ cc.renderer._batchRendering();
+ batchBroken = true;
+ }
+ if (batchBroken) {
+ vertexDataOffset = 0;
+ }
+
+ // update the vertex buffer
+ var slotDebugPoints = null;
+ if (attachment instanceof spine.RegionAttachment) {
+ slotDebugPoints = this._uploadRegionAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else if (attachment instanceof spine.MeshAttachment) {
+ this._uploadMeshAttachmentData(attachment, slot, premultiAlpha, f32buffer, ui32buffer, vertexDataOffset);
+ }
+ else {
+ continue;
}
- if (textureAtlas) {
- textureAtlas.drawQuads();
- textureAtlas.removeAllQuads();
+ if (this._node._debugSlots) {
+ debugSlotsInfo[i] = slotDebugPoints;
}
- if (node._debugBones || node._debugSlots) {
- cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
- //cc.kmGLPushMatrixWitMat4(this._stackMatrix);
- cc.current_stack.stack.push(cc.current_stack.top);
- cc.current_stack.top = this._stackMatrix;
- var drawingUtil = cc._drawingUtil;
-
- if (node._debugSlots) {
- // Slots.
- drawingUtil.setDrawColor(0, 0, 255, 255);
- drawingUtil.setLineWidth(1);
-
- for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
- slot = locSkeleton.drawOrder[i];
- if (!slot.attachment || slot.attachment.type != sp.ATTACHMENT_TYPE.REGION)
- continue;
- attachment = slot.attachment;
- this._updateRegionAttachmentQuad(attachment, slot, tmpQuad);
-
- var points = [];
- points.push(cc.p(tmpQuad.bl.vertices.x, tmpQuad.bl.vertices.y));
- points.push(cc.p(tmpQuad.br.vertices.x, tmpQuad.br.vertices.y));
- points.push(cc.p(tmpQuad.tr.vertices.x, tmpQuad.tr.vertices.y));
- points.push(cc.p(tmpQuad.tl.vertices.x, tmpQuad.tl.vertices.y));
+ // update the index buffer
+ if (attachment instanceof spine.RegionAttachment) {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.TRIANGLE);
+ } else {
+ cc.renderer._increaseBatchingSize(vertCount, cc.renderer.VertexType.CUSTOM, attachment.triangles);
+ }
+ // update the index data
+ vertexDataOffset += vertCount * 6;
+ }
+
+ if (node._debugBones || node._debugSlots) {
+ // flush previous vertices
+ cc.renderer._batchRendering();
+
+ var wt = this._worldTransform, mat = this._matrix.mat;
+ mat[0] = wt.a;
+ mat[4] = wt.c;
+ mat[12] = wt.tx;
+ mat[1] = wt.b;
+ mat[5] = wt.d;
+ mat[13] = wt.ty;
+ cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
+ cc.current_stack.stack.push(cc.current_stack.top);
+ cc.current_stack.top = this._matrix;
+ var drawingUtil = cc._drawingUtil;
+
+ if (node._debugSlots && debugSlotsInfo && debugSlotsInfo.length > 0) {
+ // Slots.
+ drawingUtil.setDrawColor(0, 0, 255, 255);
+ drawingUtil.setLineWidth(1);
+
+ for (i = 0, n = locSkeleton.slots.length; i < n; i++) {
+ var points = debugSlotsInfo[i];
+ if (points) {
drawingUtil.drawPoly(points, 4, true);
}
}
+ }
- if (node._debugBones) {
- // Bone lengths.
- var bone;
- drawingUtil.setLineWidth(2);
- drawingUtil.setDrawColor(255, 0, 0, 255);
-
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- var x = bone.data.length * bone.m00 + bone.worldX;
- var y = bone.data.length * bone.m10 + bone.worldY;
- drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
- }
+ if (node._debugBones) {
+ // Bone lengths.
+ var bone;
+ drawingUtil.setLineWidth(2);
+ drawingUtil.setDrawColor(255, 0, 0, 255);
+
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ var x = bone.data.length * bone.a + bone.worldX;
+ var y = bone.data.length * bone.c + bone.worldY;
+ drawingUtil.drawLine(cc.p(bone.worldX, bone.worldY), cc.p(x, y));
+ }
- // Bone origins.
- drawingUtil.setPointSize(4);
- drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
+ // Bone origins.
+ drawingUtil.setPointSize(4);
+ drawingUtil.setDrawColor(0, 0, 255, 255); // Root bone is blue.
- for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
- bone = locSkeleton.bones[i];
- drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
- if (i == 0) {
- drawingUtil.setDrawColor(0, 255, 0, 255);
- }
+ for (i = 0, n = locSkeleton.bones.length; i < n; i++) {
+ bone = locSkeleton.bones[i];
+ drawingUtil.drawPoint(cc.p(bone.worldX, bone.worldY));
+ if (i == 0) {
+ drawingUtil.setDrawColor(0, 255, 0, 255);
}
}
- cc.kmGLPopMatrix();
- }
- };
-
- proto._createChildFormSkeletonData = function(){};
-
- proto._updateChild = function(){};
-
- proto._updateRegionAttachmentQuad = function(self, slot, quad, premultipliedAlpha) {
- var vertices = {};
- self.computeVertices(slot.bone.skeleton.x, slot.bone.skeleton.y, slot.bone, vertices);
- var r = slot.bone.skeleton.r * slot.r * 255;
- var g = slot.bone.skeleton.g * slot.g * 255;
- var b = slot.bone.skeleton.b * slot.b * 255;
- var normalizedAlpha = slot.bone.skeleton.a * slot.a;
-
- if (premultipliedAlpha) {
- r *= normalizedAlpha;
- g *= normalizedAlpha;
- b *= normalizedAlpha;
- }
- var a = normalizedAlpha * 255;
-
- quad.bl.colors.r = quad.tl.colors.r = quad.tr.colors.r = quad.br.colors.r = r;
- quad.bl.colors.g = quad.tl.colors.g = quad.tr.colors.g = quad.br.colors.g = g;
- quad.bl.colors.b = quad.tl.colors.b = quad.tr.colors.b = quad.br.colors.b = b;
- quad.bl.colors.a = quad.tl.colors.a = quad.tr.colors.a = quad.br.colors.a = a;
-
- var VERTEX = sp.VERTEX_INDEX;
- quad.bl.vertices.x = vertices[VERTEX.X1];
- quad.bl.vertices.y = vertices[VERTEX.Y1];
- quad.tl.vertices.x = vertices[VERTEX.X2];
- quad.tl.vertices.y = vertices[VERTEX.Y2];
- quad.tr.vertices.x = vertices[VERTEX.X3];
- quad.tr.vertices.y = vertices[VERTEX.Y3];
- quad.br.vertices.x = vertices[VERTEX.X4];
- quad.br.vertices.y = vertices[VERTEX.Y4];
-
- quad.bl.texCoords.u = self.uvs[VERTEX.X1];
- quad.bl.texCoords.v = self.uvs[VERTEX.Y1];
- quad.tl.texCoords.u = self.uvs[VERTEX.X2];
- quad.tl.texCoords.v = self.uvs[VERTEX.Y2];
- quad.tr.texCoords.u = self.uvs[VERTEX.X3];
- quad.tr.texCoords.v = self.uvs[VERTEX.Y3];
- quad.br.texCoords.u = self.uvs[VERTEX.X4];
- quad.br.texCoords.v = self.uvs[VERTEX.Y4];
- };
-
- proto._updateMeshAttachmentQuad = function(self, slot, quad, premultipliedAlpha) {
- var vertices = {};
- self.computeWorldVertices(slot.bone.x, slot.bone.y, slot, vertices);
- var r = slot.bone.skeleton.r * slot.r * 255;
- var g = slot.bone.skeleton.g * slot.g * 255;
- var b = slot.bone.skeleton.b * slot.b * 255;
- var normalizedAlpha = slot.bone.skeleton.a * slot.a;
- if (premultipliedAlpha) {
- r *= normalizedAlpha;
- g *= normalizedAlpha;
- b *= normalizedAlpha;
}
- var a = normalizedAlpha * 255;
-
- quad.bl.colors.r = quad.tl.colors.r = quad.tr.colors.r = quad.br.colors.r = r;
- quad.bl.colors.g = quad.tl.colors.g = quad.tr.colors.g = quad.br.colors.g = g;
- quad.bl.colors.b = quad.tl.colors.b = quad.tr.colors.b = quad.br.colors.b = b;
- quad.bl.colors.a = quad.tl.colors.a = quad.tr.colors.a = quad.br.colors.a = a;
-
- var VERTEX = sp.VERTEX_INDEX;
- quad.bl.vertices.x = vertices[VERTEX.X1];
- quad.bl.vertices.y = vertices[VERTEX.Y1];
- quad.tl.vertices.x = vertices[VERTEX.X2];
- quad.tl.vertices.y = vertices[VERTEX.Y2];
- quad.tr.vertices.x = vertices[VERTEX.X3];
- quad.tr.vertices.y = vertices[VERTEX.Y3];
- quad.br.vertices.x = vertices[VERTEX.X4];
- quad.br.vertices.y = vertices[VERTEX.Y4];
-
- quad.bl.texCoords.u = self.uvs[VERTEX.X1];
- quad.bl.texCoords.v = self.uvs[VERTEX.Y1];
- quad.tl.texCoords.u = self.uvs[VERTEX.X2];
- quad.tl.texCoords.v = self.uvs[VERTEX.Y2];
- quad.tr.texCoords.u = self.uvs[VERTEX.X3];
- quad.tr.texCoords.v = self.uvs[VERTEX.Y3];
- quad.br.texCoords.u = self.uvs[VERTEX.X4];
- quad.br.texCoords.v = self.uvs[VERTEX.Y4];
- };
-})();
\ No newline at end of file
+ cc.kmGLPopMatrix();
+ }
+
+ return 0;
+};
+
+proto._getBlendFunc = function (blendMode, premultiAlpha) {
+ var ret = this._currBlendFunc;
+ switch (blendMode) {
+ case spine.BlendMode.Normal:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Additive:
+ ret.src = premultiAlpha ? cc.ONE : cc.SRC_ALPHA;
+ ret.dst = cc.ONE;
+ break;
+ case spine.BlendMode.Multiply:
+ ret.src = cc.DST_COLOR;
+ ret.dst = cc.ONE_MINUS_SRC_ALPHA;
+ break;
+ case spine.BlendMode.Screen:
+ ret.src = cc.ONE;
+ ret.dst = cc.ONE_MINUS_SRC_COLOR;
+ break;
+ default:
+ ret = this._node._blendFunc;
+ break;
+ }
+
+ return ret;
+};
+
+proto._createChildFormSkeletonData = function(){};
+
+proto._updateChild = function(){};
+
+proto._uploadRegionAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ // the vertices in format:
+ // [
+ // X1, Y1, C1R, C1G, C1B, C1A, U1, V1, // bottom left
+ // X2, Y2, C2R, C2G, C2B, C2A, U2, V2, // top left
+ // X3, Y3, C3R, C3G, C3B, C3A, U3, V3, // top right
+ // X4, Y4, C4R, C4G, C4B, C4A, U4, V4 // bottom right
+ // ]
+ //
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+
+ var vertices = spine.Utils.setArraySize(new Array(), 8, 0);
+ attachment.computeWorldVertices(slot.bone, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color;
+ var slotColor = slot.color;
+ var regionColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * regionColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * regionColor.r * multiplier,
+ skeletonColor.g * slotColor.g * regionColor.g * multiplier,
+ skeletonColor.b * slotColor.b * regionColor.b * multiplier,
+ alpha);
+
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+
+ var offset = vertexDataOffset;
+ // generate 6 vertices data (two triangles) from the quad vertices
+ // using two angles : (0, 1, 2) & (0, 2, 3)
+ for (var i = 0; i < 6; i++) {
+ var srcIdx = i < 4 ? i % 3 : i - 2;
+ var vx = vertices[srcIdx * 2],
+ vy = vertices[srcIdx * 2 + 1];
+ var x = vx * wa + vy * wc + wx,
+ y = vx * wb + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[srcIdx * 2];
+ f32buffer[offset + 5] = uvs[srcIdx * 2 + 1];
+ offset += 6;
+ }
+
+ if (this._node._debugSlots) {
+ // return the quad points info if debug slot enabled
+ var VERTEX = spine.RegionAttachment;
+ return [
+ cc.p(vertices[VERTEX.OX1], vertices[VERTEX.OY1]),
+ cc.p(vertices[VERTEX.OX2], vertices[VERTEX.OY2]),
+ cc.p(vertices[VERTEX.OX3], vertices[VERTEX.OY3]),
+ cc.p(vertices[VERTEX.OX4], vertices[VERTEX.OY4])
+ ];
+ }
+};
+
+proto._uploadMeshAttachmentData = function(attachment, slot, premultipliedAlpha, f32buffer, ui32buffer, vertexDataOffset) {
+ var wt = this._worldTransform,
+ wa = wt.a, wb = wt.b, wc = wt.c, wd = wt.d,
+ wx = wt.tx, wy = wt.ty,
+ z = this._node.vertexZ;
+ // get the vertex data
+ var verticesLength = attachment.worldVerticesLength;
+ var vertices = spine.Utils.setArraySize(new Array(), verticesLength, 0);
+ attachment.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2);
+
+ var uvs = attachment.uvs;
+
+ // get the colors data
+ var skeleton = slot.bone.skeleton;
+ var skeletonColor = skeleton.color, slotColor = slot.color, meshColor = attachment.color;
+ var alpha = skeletonColor.a * slotColor.a * meshColor.a;
+ var multiplier = premultipliedAlpha ? alpha : 1;
+ var colors = attachment.tempColor;
+ colors.set(skeletonColor.r * slotColor.r * meshColor.r * multiplier,
+ skeletonColor.g * slotColor.g * meshColor.g * multiplier,
+ skeletonColor.b * slotColor.b * meshColor.b * multiplier,
+ alpha);
+
+ var offset = vertexDataOffset;
+ var nodeColor = this._displayedColor;
+ var nodeR = nodeColor.r,
+ nodeG = nodeColor.g,
+ nodeB = nodeColor.b,
+ nodeA = this._displayedOpacity;
+ for (var i = 0, n = vertices.length; i < n; i += 2) {
+ var vx = vertices[i],
+ vy = vertices[i + 1];
+ var x = vx * wa + vy * wb + wx,
+ y = vx * wc + vy * wd + wy;
+ var r = colors.r * nodeR,
+ g = colors.g * nodeG,
+ b = colors.b * nodeB,
+ a = colors.a * nodeA;
+ var color = ((a<<24) | (b<<16) | (g<<8) | r);
+
+ f32buffer[offset] = x;
+ f32buffer[offset + 1] = y;
+ f32buffer[offset + 2] = z;
+ ui32buffer[offset + 3] = color;
+ f32buffer[offset + 4] = uvs[i];
+ f32buffer[offset + 5] = uvs[i + 1];
+ offset += 6;
+ }
+};
+
+})();
diff --git a/extensions/spine/LICENSE b/extensions/spine/LICENSE
new file mode 100644
index 0000000000..daceab94a4
--- /dev/null
+++ b/extensions/spine/LICENSE
@@ -0,0 +1,27 @@
+Spine Runtimes Software License v2.5
+
+Copyright (c) 2013-2016, Esoteric Software
+All rights reserved.
+
+You are granted a perpetual, non-exclusive, non-sublicensable, and
+non-transferable license to use, install, execute, and perform the Spine
+Runtimes software and derivative works solely for personal or internal
+use. Without the written permission of Esoteric Software (see Section 2 of
+the Spine Software License Agreement), you may not (a) modify, translate,
+adapt, or develop new applications using the Spine Runtimes or otherwise
+create derivative works or improvements of the Spine Runtimes or (b) remove,
+delete, alter, or obscure any trademarks or any copyright, trademark, patent,
+or other intellectual property or proprietary rights notices on or in the
+Software, including any copy thereof. Redistributions in binary or source
+form must include this license and terms.
+
+THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF
+USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/extensions/spine/Spine.js b/extensions/spine/Spine.js
index 047db2b5ac..e7c0d894ea 100644
--- a/extensions/spine/Spine.js
+++ b/extensions/spine/Spine.js
@@ -1,2628 +1,6458 @@
-/******************************************************************************
- * Spine Runtimes Software License
- * Version 2.1
- *
- * Copyright (c) 2013, Esoteric Software
- * All rights reserved.
- *
- * You are granted a perpetual, non-exclusive, non-sublicensable and
- * non-transferable license to install, execute and perform the Spine Runtimes
- * Software (the "Software") solely for internal use. Without the written
- * permission of Esoteric Software (typically granted by licensing Spine), you
- * may not (a) modify, translate, adapt or otherwise create derivative works,
- * improvements of the Software or develop new applications using the Software
- * or (b) remove, delete, alter or obscure any trademarks or any copyright,
- * trademark, patent or other intellectual property or proprietary rights
- * notices on or in the Software, including any copy thereof. Redistributions
- * in binary or source form must include this license and terms.
- *
- * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *****************************************************************************/
-
-var spine = {
- radDeg: 180 / Math.PI,
- degRad: Math.PI / 180,
- temp: [],
- Float32Array: (typeof(Float32Array) === 'undefined') ? Array : Float32Array,
- Uint16Array: (typeof(Uint16Array) === 'undefined') ? Array : Uint16Array
-};
-
-spine.BoneData = function (name, parent) {
- this.name = name;
- this.parent = parent;
-};
-spine.BoneData.prototype = {
- length: 0,
- x: 0, y: 0,
- rotation: 0,
- scaleX: 1, scaleY: 1,
- inheritScale: true,
- inheritRotation: true,
- flipX: false, flipY: false
-};
-
-spine.SlotData = function (name, boneData) {
- this.name = name;
- this.boneData = boneData;
-};
-spine.SlotData.prototype = {
- r: 1, g: 1, b: 1, a: 1,
- attachmentName: null,
- additiveBlending: false
-};
-
-spine.IkConstraintData = function (name) {
- this.name = name;
- this.bones = [];
-};
-spine.IkConstraintData.prototype = {
- target: null,
- bendDirection: 1,
- mix: 1
-};
-
-spine.Bone = function (boneData, skeleton, parent) {
- this.data = boneData;
- this.skeleton = skeleton;
- this.parent = parent;
- this.setToSetupPose();
-};
-spine.Bone.yDown = false;
-spine.Bone.prototype = {
- x: 0, y: 0,
- rotation: 0, rotationIK: 0,
- scaleX: 1, scaleY: 1,
- flipX: false, flipY: false,
- m00: 0, m01: 0, worldX: 0, // a b x
- m10: 0, m11: 0, worldY: 0, // c d y
- worldRotation: 0,
- worldScaleX: 1, worldScaleY: 1,
- worldFlipX: false, worldFlipY: false,
- updateWorldTransform: function () {
- var parent = this.parent;
- if (parent) {
- this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX;
- this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY;
- if (this.data.inheritScale) {
- this.worldScaleX = parent.worldScaleX * this.scaleX;
- this.worldScaleY = parent.worldScaleY * this.scaleY;
- } else {
- this.worldScaleX = this.scaleX;
- this.worldScaleY = this.scaleY;
- }
- this.worldRotation = this.data.inheritRotation ? (parent.worldRotation + this.rotationIK) : this.rotationIK;
- this.worldFlipX = parent.worldFlipX != this.flipX;
- this.worldFlipY = parent.worldFlipY != this.flipY;
- } else {
- var skeletonFlipX = this.skeleton.flipX, skeletonFlipY = this.skeleton.flipY;
- this.worldX = skeletonFlipX ? -this.x : this.x;
- this.worldY = (skeletonFlipY != spine.Bone.yDown) ? -this.y : this.y;
- this.worldScaleX = this.scaleX;
- this.worldScaleY = this.scaleY;
- this.worldRotation = this.rotationIK;
- this.worldFlipX = skeletonFlipX != this.flipX;
- this.worldFlipY = skeletonFlipY != this.flipY;
- }
- var radians = this.worldRotation * spine.degRad;
- var cos = Math.cos(radians);
- var sin = Math.sin(radians);
- if (this.worldFlipX) {
- this.m00 = -cos * this.worldScaleX;
- this.m01 = sin * this.worldScaleY;
- } else {
- this.m00 = cos * this.worldScaleX;
- this.m01 = -sin * this.worldScaleY;
- }
- if (this.worldFlipY != spine.Bone.yDown) {
- this.m10 = -sin * this.worldScaleX;
- this.m11 = -cos * this.worldScaleY;
- } else {
- this.m10 = sin * this.worldScaleX;
- this.m11 = cos * this.worldScaleY;
- }
- },
- setToSetupPose: function () {
- var data = this.data;
- this.x = data.x;
- this.y = data.y;
- this.rotation = data.rotation;
- this.rotationIK = this.rotation;
- this.scaleX = data.scaleX;
- this.scaleY = data.scaleY;
- this.flipX = data.flipX;
- this.flipY = data.flipY;
- },
- worldToLocal: function (world) {
- var dx = world[0] - this.worldX, dy = world[1] - this.worldY;
- var m00 = this.m00, m10 = this.m10, m01 = this.m01, m11 = this.m11;
- if (this.worldFlipX != (this.worldFlipY != spine.Bone.yDown)) {
- m00 = -m00;
- m11 = -m11;
- }
- var invDet = 1 / (m00 * m11 - m01 * m10);
- world[0] = dx * m00 * invDet - dy * m01 * invDet;
- world[1] = dy * m11 * invDet - dx * m10 * invDet;
- },
- localToWorld: function (local) {
- var localX = local[0], localY = local[1];
- local[0] = localX * this.m00 + localY * this.m01 + this.worldX;
- local[1] = localX * this.m10 + localY * this.m11 + this.worldY;
- }
-};
-
-spine.Slot = function (slotData, bone) {
- this.data = slotData;
- this.bone = bone;
- this.setToSetupPose();
-};
-spine.Slot.prototype = {
- r: 1, g: 1, b: 1, a: 1,
- _attachmentTime: 0,
- attachment: null,
- attachmentVertices: [],
- setAttachment: function (attachment) {
- this.attachment = attachment;
- this._attachmentTime = this.bone.skeleton.time;
- this.attachmentVertices.length = 0;
- },
- setAttachmentTime: function (time) {
- this._attachmentTime = this.bone.skeleton.time - time;
- },
- getAttachmentTime: function () {
- return this.bone.skeleton.time - this._attachmentTime;
- },
- setToSetupPose: function () {
- var data = this.data;
- this.r = data.r;
- this.g = data.g;
- this.b = data.b;
- this.a = data.a;
-
- var slotDatas = this.bone.skeleton.data.slots;
- for (var i = 0, n = slotDatas.length; i < n; i++) {
- if (slotDatas[i] == data) {
- this.setAttachment(!data.attachmentName ? null : this.bone.skeleton.getAttachmentBySlotIndex(i, data.attachmentName));
- break;
- }
- }
- }
-};
-
-spine.IkConstraint = function (data, skeleton) {
- this.data = data;
- this.mix = data.mix;
- this.bendDirection = data.bendDirection;
-
- this.bones = [];
- for (var i = 0, n = data.bones.length; i < n; i++)
- this.bones.push(skeleton.findBone(data.bones[i].name));
- this.target = skeleton.findBone(data.target.name);
-};
-spine.IkConstraint.prototype = {
- apply: function () {
- var target = this.target;
- var bones = this.bones;
- switch (bones.length) {
- case 1:
- spine.IkConstraint.apply1(bones[0], target.worldX, target.worldY, this.mix);
- break;
- case 2:
- spine.IkConstraint.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.mix);
- break;
- }
- }
-};
-/** Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified in the world
- * coordinate system. */
-spine.IkConstraint.apply1 = function (bone, targetX, targetY, alpha) {
- var parentRotation = (!bone.data.inheritRotation || !bone.parent) ? 0 : bone.parent.worldRotation;
- var rotation = bone.rotation;
- var rotationIK = Math.atan2(targetY - bone.worldY, targetX - bone.worldX) * spine.radDeg;
- if (bone.worldFlipX != (bone.worldFlipY != spine.Bone.yDown)) rotationIK = -rotationIK;
- rotationIK -= parentRotation;
- bone.rotationIK = rotation + (rotationIK - rotation) * alpha;
-};
-/** Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as possible. The
- * target is specified in the world coordinate system.
- * @param child Any descendant bone of the parent. */
-spine.IkConstraint.apply2 = function (parent, child, targetX, targetY, bendDirection, alpha) {
- var childRotation = child.rotation, parentRotation = parent.rotation;
- if (!alpha) {
- child.rotationIK = childRotation;
- parent.rotationIK = parentRotation;
- return;
- }
- var positionX, positionY, tempPosition = spine.temp;
- var parentParent = parent.parent;
- if (parentParent) {
- tempPosition[0] = targetX;
- tempPosition[1] = targetY;
- parentParent.worldToLocal(tempPosition);
- targetX = (tempPosition[0] - parent.x) * parentParent.worldScaleX;
- targetY = (tempPosition[1] - parent.y) * parentParent.worldScaleY;
- } else {
- targetX -= parent.x;
- targetY -= parent.y;
- }
- if (child.parent == parent) {
- positionX = child.x;
- positionY = child.y;
- } else {
- tempPosition[0] = child.x;
- tempPosition[1] = child.y;
- child.parent.localToWorld(tempPosition);
- parent.worldToLocal(tempPosition);
- positionX = tempPosition[0];
- positionY = tempPosition[1];
- }
- var childX = positionX * parent.worldScaleX, childY = positionY * parent.worldScaleY;
- var offset = Math.atan2(childY, childX);
- var len1 = Math.sqrt(childX * childX + childY * childY), len2 = child.data.length * child.worldScaleX;
- // Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett, http://www.ryanjuckett.com/
- var cosDenom = 2 * len1 * len2;
- if (cosDenom < 0.0001) {
- child.rotationIK = childRotation + (Math.atan2(targetY, targetX) * spine.radDeg - parentRotation - childRotation) * alpha;
- return;
- }
- var cos = (targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom;
- if (cos < -1)
- cos = -1;
- else if (cos > 1)
- cos = 1;
- var childAngle = Math.acos(cos) * bendDirection;
- var adjacent = len1 + len2 * cos, opposite = len2 * Math.sin(childAngle);
- var parentAngle = Math.atan2(targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite);
- var rotation = (parentAngle - offset) * spine.radDeg - parentRotation;
- if (rotation > 180)
- rotation -= 360;
- else if (rotation < -180) //
- rotation += 360;
- parent.rotationIK = parentRotation + rotation * alpha;
- rotation = (childAngle + offset) * spine.radDeg - childRotation;
- if (rotation > 180)
- rotation -= 360;
- else if (rotation < -180) //
- rotation += 360;
- child.rotationIK = childRotation + (rotation + parent.worldRotation - child.parent.worldRotation) * alpha;
-};
-
-spine.Skin = function (name) {
- this.name = name;
- this.attachments = {};
-};
-spine.Skin.prototype = {
- addAttachment: function (slotIndex, name, attachment) {
- this.attachments[slotIndex + ":" + name] = attachment;
- },
- getAttachment: function (slotIndex, name) {
- return this.attachments[slotIndex + ":" + name];
- },
- _attachAll: function (skeleton, oldSkin) {
- for (var key in oldSkin.attachments) {
- var colon = key.indexOf(":");
- var slotIndex = parseInt(key.substring(0, colon));
- var name = key.substring(colon + 1);
- var slot = skeleton.slots[slotIndex];
- if (slot.attachment && slot.attachment.name == name) {
- var attachment = this.getAttachment(slotIndex, name);
- if (attachment) slot.setAttachment(attachment);
- }
- }
- }
-};
-
-spine.Animation = function (name, timelines, duration) {
- this.name = name;
- this.timelines = timelines;
- this.duration = duration;
-};
-spine.Animation.prototype = {
- apply: function (skeleton, lastTime, time, loop, events) {
- if (loop && this.duration != 0) {
- time %= this.duration;
- lastTime %= this.duration;
- }
- var timelines = this.timelines;
- for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, 1);
- },
- mix: function (skeleton, lastTime, time, loop, events, alpha) {
- if (loop && this.duration != 0) {
- time %= this.duration;
- lastTime %= this.duration;
- }
- var timelines = this.timelines;
- for (var i = 0, n = timelines.length; i < n; i++)
- timelines[i].apply(skeleton, lastTime, time, events, alpha);
- }
-};
-spine.Animation.binarySearch = function (values, target, step) {
- var low = 0;
- var high = Math.floor(values.length / step) - 2;
- if (!high) return step;
- var current = high >>> 1;
- while (true) {
- if (values[(current + 1) * step] <= target)
- low = current + 1;
- else
- high = current;
- if (low == high) return (low + 1) * step;
- current = (low + high) >>> 1;
- }
-};
-spine.Animation.binarySearch1 = function (values, target) {
- var low = 0;
- var high = values.length - 2;
- if (!high) return 1;
- var current = high >>> 1;
- while (true) {
- if (values[current + 1] <= target)
- low = current + 1;
- else
- high = current;
- if (low == high) return low + 1;
- current = (low + high) >>> 1;
- }
-};
-spine.Animation.linearSearch = function (values, target, step) {
- for (var i = 0, last = values.length - step; i <= last; i += step)
- if (values[i] > target) return i;
- return -1;
-};
-
-spine.Curves = function (frameCount) {
- this.curves = []; // type, x, y, ...
- //this.curves.length = (frameCount - 1) * 19/*BEZIER_SIZE*/;
-};
-spine.Curves.prototype = {
- setLinear: function (frameIndex) {
- this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 0/*LINEAR*/;
- },
- setStepped: function (frameIndex) {
- this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 1/*STEPPED*/;
- },
- /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
- * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
- * the difference between the keyframe's values. */
- setCurve: function (frameIndex, cx1, cy1, cx2, cy2) {
- var subdiv1 = 1 / 10/*BEZIER_SEGMENTS*/, subdiv2 = subdiv1 * subdiv1, subdiv3 = subdiv2 * subdiv1;
- var pre1 = 3 * subdiv1, pre2 = 3 * subdiv2, pre4 = 6 * subdiv2, pre5 = 6 * subdiv3;
- var tmp1x = -cx1 * 2 + cx2, tmp1y = -cy1 * 2 + cy2, tmp2x = (cx1 - cx2) * 3 + 1, tmp2y = (cy1 - cy2) * 3 + 1;
- var dfx = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv3, dfy = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv3;
- var ddfx = tmp1x * pre4 + tmp2x * pre5, ddfy = tmp1y * pre4 + tmp2y * pre5;
- var dddfx = tmp2x * pre5, dddfy = tmp2y * pre5;
-
- var i = frameIndex * 19/*BEZIER_SIZE*/;
- var curves = this.curves;
- curves[i++] = 2/*BEZIER*/;
-
- var x = dfx, y = dfy;
- for (var n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) {
- curves[i] = x;
- curves[i + 1] = y;
- dfx += ddfx;
- dfy += ddfy;
- ddfx += dddfx;
- ddfy += dddfy;
- x += dfx;
- y += dfy;
- }
- },
- getCurvePercent: function (frameIndex, percent) {
- percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent);
- var curves = this.curves;
- var i = frameIndex * 19/*BEZIER_SIZE*/;
- var type = curves[i];
- if (type === 0/*LINEAR*/) return percent;
- if (type == 1/*STEPPED*/) return 0;
- i++;
- var x = 0;
- for (var start = i, n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) {
- x = curves[i];
- if (x >= percent) {
- var prevX, prevY;
- if (i == start) {
- prevX = 0;
- prevY = 0;
- } else {
- prevX = curves[i - 2];
- prevY = curves[i - 1];
- }
- return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
- }
- }
- var y = curves[i - 1];
- return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
- }
-};
-
-spine.RotateTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, angle, ...
- this.frames.length = frameCount * 2;
-};
-spine.RotateTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 2;
- },
- setFrame: function (frameIndex, time, angle) {
- frameIndex *= 2;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = angle;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var bone = skeleton.bones[this.boneIndex];
-
- if (time >= frames[frames.length - 2]) { // Time is after last frame.
- var amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- bone.rotation += amount * alpha;
- return;
- }
-
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 2);
- var prevFrameValue = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent);
-
- var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - prevFrameValue;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- amount = bone.data.rotation + (prevFrameValue + amount * percent) - bone.rotation;
- while (amount > 180)
- amount -= 360;
- while (amount < -180)
- amount += 360;
- bone.rotation += amount * alpha;
- }
-};
-
-spine.TranslateTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, x, y, ...
- this.frames.length = frameCount * 3;
-};
-spine.TranslateTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, x, y) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = x;
- this.frames[frameIndex + 2] = y;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var bone = skeleton.bones[this.boneIndex];
-
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha;
- bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha;
- return;
- }
-
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameX = frames[frameIndex - 2];
- var prevFrameY = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
-
- bone.x += (bone.data.x + prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent - bone.x) * alpha;
- bone.y += (bone.data.y + prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent - bone.y) * alpha;
- }
-};
-
-spine.ScaleTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, x, y, ...
- this.frames.length = frameCount * 3;
-};
-spine.ScaleTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, x, y) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = x;
- this.frames[frameIndex + 2] = y;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var bone = skeleton.bones[this.boneIndex];
-
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- bone.scaleX += (bone.data.scaleX * frames[frames.length - 2] - bone.scaleX) * alpha;
- bone.scaleY += (bone.data.scaleY * frames[frames.length - 1] - bone.scaleY) * alpha;
- return;
- }
-
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameX = frames[frameIndex - 2];
- var prevFrameY = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
-
- bone.scaleX += (bone.data.scaleX * (prevFrameX + (frames[frameIndex + 1/*FRAME_X*/] - prevFrameX) * percent) - bone.scaleX) * alpha;
- bone.scaleY += (bone.data.scaleY * (prevFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - prevFrameY) * percent) - bone.scaleY) * alpha;
- }
-};
-
-spine.ColorTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, r, g, b, a, ...
- this.frames.length = frameCount * 5;
-};
-spine.ColorTimeline.prototype = {
- slotIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 5;
- },
- setFrame: function (frameIndex, time, r, g, b, a) {
- frameIndex *= 5;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = r;
- this.frames[frameIndex + 2] = g;
- this.frames[frameIndex + 3] = b;
- this.frames[frameIndex + 4] = a;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var r, g, b, a;
- if (time >= frames[frames.length - 5]) {
- // Time is after last frame.
- var i = frames.length - 1;
- r = frames[i - 3];
- g = frames[i - 2];
- b = frames[i - 1];
- a = frames[i];
- } else {
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 5);
- var prevFrameR = frames[frameIndex - 4];
- var prevFrameG = frames[frameIndex - 3];
- var prevFrameB = frames[frameIndex - 2];
- var prevFrameA = frames[frameIndex - 1];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent);
-
- r = prevFrameR + (frames[frameIndex + 1/*FRAME_R*/] - prevFrameR) * percent;
- g = prevFrameG + (frames[frameIndex + 2/*FRAME_G*/] - prevFrameG) * percent;
- b = prevFrameB + (frames[frameIndex + 3/*FRAME_B*/] - prevFrameB) * percent;
- a = prevFrameA + (frames[frameIndex + 4/*FRAME_A*/] - prevFrameA) * percent;
- }
- var slot = skeleton.slots[this.slotIndex];
- if (alpha < 1) {
- slot.r += (r - slot.r) * alpha;
- slot.g += (g - slot.g) * alpha;
- slot.b += (b - slot.b) * alpha;
- slot.a += (a - slot.a) * alpha;
- } else {
- slot.r = r;
- slot.g = g;
- slot.b = b;
- slot.a = a;
- }
- }
-};
-
-spine.AttachmentTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, ...
- this.frames.length = frameCount;
- this.attachmentNames = [];
- this.attachmentNames.length = frameCount;
-};
-spine.AttachmentTimeline.prototype = {
- slotIndex: 0,
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, attachmentName) {
- this.frames[frameIndex] = time;
- this.attachmentNames[frameIndex] = attachmentName;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) {
- if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0);
- return;
- } else if (lastTime > time) //
- lastTime = -1;
-
- var frameIndex = time >= frames[frames.length - 1] ? frames.length - 1 : spine.Animation.binarySearch1(frames, time) - 1;
- if (frames[frameIndex] < lastTime) return;
-
- var attachmentName = this.attachmentNames[frameIndex];
- skeleton.slots[this.slotIndex].setAttachment(
- !attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName));
- }
-};
-
-spine.EventTimeline = function (frameCount) {
- this.frames = []; // time, ...
- this.frames.length = frameCount;
- this.events = [];
- this.events.length = frameCount;
-};
-spine.EventTimeline.prototype = {
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, event) {
- this.frames[frameIndex] = time;
- this.events[frameIndex] = event;
- },
- /** Fires events for frames > lastTime and <= time. */
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- if (!firedEvents) return;
-
- var frames = this.frames;
- var frameCount = frames.length;
-
- if (lastTime > time) { // Fire events after last time for looped animations.
- this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha);
- lastTime = -1;
- } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
- return;
- if (time < frames[0]) return; // Time is before first frame.
-
- var frameIndex;
- if (lastTime < frames[0])
- frameIndex = 0;
- else {
- frameIndex = spine.Animation.binarySearch1(frames, lastTime);
- var frame = frames[frameIndex];
- while (frameIndex > 0) { // Fire multiple events with the same frame.
- if (frames[frameIndex - 1] != frame) break;
- frameIndex--;
- }
- }
- var events = this.events;
- for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
- firedEvents.push(events[frameIndex]);
- }
-};
-
-spine.DrawOrderTimeline = function (frameCount) {
- this.frames = []; // time, ...
- this.frames.length = frameCount;
- this.drawOrders = [];
- this.drawOrders.length = frameCount;
-};
-spine.DrawOrderTimeline.prototype = {
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, drawOrder) {
- this.frames[frameIndex] = time;
- this.drawOrders[frameIndex] = drawOrder;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var frameIndex;
- if (time >= frames[frames.length - 1]) // Time is after last frame.
- frameIndex = frames.length - 1;
- else
- frameIndex = spine.Animation.binarySearch1(frames, time) - 1;
-
- var drawOrder = skeleton.drawOrder;
- var slots = skeleton.slots;
- var drawOrderToSetupIndex = this.drawOrders[frameIndex];
- if (!drawOrderToSetupIndex) {
- for (var i = 0, n = slots.length; i < n; i++)
- drawOrder[i] = slots[i];
- } else {
- for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
- drawOrder[i] = skeleton.slots[drawOrderToSetupIndex[i]];
- }
-
- }
-};
-
-spine.FfdTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = [];
- this.frames.length = frameCount;
- this.frameVertices = [];
- this.frameVertices.length = frameCount;
-};
-spine.FfdTimeline.prototype = {
- slotIndex: 0,
- attachment: 0,
- getFrameCount: function () {
- return this.frames.length;
- },
- setFrame: function (frameIndex, time, vertices) {
- this.frames[frameIndex] = time;
- this.frameVertices[frameIndex] = vertices;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var slot = skeleton.slots[this.slotIndex];
- if (slot.attachment != this.attachment) return;
-
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var frameVertices = this.frameVertices;
- var vertexCount = frameVertices[0].length;
-
- var vertices = slot.attachmentVertices;
- if (vertices.length != vertexCount) alpha = 1;
- vertices.length = vertexCount;
-
- if (time >= frames[frames.length - 1]) { // Time is after last frame.
- var lastVertices = frameVertices[frames.length - 1];
- if (alpha < 1) {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
- } else {
- for (var i = 0; i < vertexCount; i++)
- vertices[i] = lastVertices[i];
- }
- return;
- }
-
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch1(frames, time);
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
-
- var prevVertices = frameVertices[frameIndex - 1];
- var nextVertices = frameVertices[frameIndex];
-
- if (alpha < 1) {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
- }
- } else {
- for (var i = 0; i < vertexCount; i++) {
- var prev = prevVertices[i];
- vertices[i] = prev + (nextVertices[i] - prev) * percent;
- }
- }
- }
-};
-
-spine.IkConstraintTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, mix, bendDirection, ...
- this.frames.length = frameCount * 3;
-};
-spine.IkConstraintTimeline.prototype = {
- ikConstraintIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 3;
- },
- setFrame: function (frameIndex, time, mix, bendDirection) {
- frameIndex *= 3;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = mix;
- this.frames[frameIndex + 2] = bendDirection;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) return; // Time is before first frame.
-
- var ikConstraint = skeleton.ikConstraints[this.ikConstraintIndex];
-
- if (time >= frames[frames.length - 3]) { // Time is after last frame.
- ikConstraint.mix += (frames[frames.length - 2] - ikConstraint.mix) * alpha;
- ikConstraint.bendDirection = frames[frames.length - 1];
- return;
- }
-
- // Interpolate between the previous frame and the current frame.
- var frameIndex = spine.Animation.binarySearch(frames, time, 3);
- var prevFrameMix = frames[frameIndex + -2/*PREV_FRAME_MIX*/];
- var frameTime = frames[frameIndex];
- var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime);
- percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent);
-
- var mix = prevFrameMix + (frames[frameIndex + 1/*FRAME_MIX*/] - prevFrameMix) * percent;
- ikConstraint.mix += (mix - ikConstraint.mix) * alpha;
- ikConstraint.bendDirection = frames[frameIndex + -1/*PREV_FRAME_BEND_DIRECTION*/];
- }
-};
-
-spine.FlipXTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, flip, ...
- this.frames.length = frameCount * 2;
-};
-spine.FlipXTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 2;
- },
- setFrame: function (frameIndex, time, flip) {
- frameIndex *= 2;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = flip ? 1 : 0;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) {
- if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0);
- return;
- } else if (lastTime > time) //
- lastTime = -1;
- var frameIndex = (time >= frames[frames.length - 2] ? frames.length : spine.Animation.binarySearch(frames, time, 2)) - 2;
- if (frames[frameIndex] < lastTime) return;
- skeleton.bones[this.boneIndex].flipX = frames[frameIndex + 1] != 0;
- }
-};
-
-spine.FlipYTimeline = function (frameCount) {
- this.curves = new spine.Curves(frameCount);
- this.frames = []; // time, flip, ...
- this.frames.length = frameCount * 2;
-};
-spine.FlipYTimeline.prototype = {
- boneIndex: 0,
- getFrameCount: function () {
- return this.frames.length / 2;
- },
- setFrame: function (frameIndex, time, flip) {
- frameIndex *= 2;
- this.frames[frameIndex] = time;
- this.frames[frameIndex + 1] = flip ? 1 : 0;
- },
- apply: function (skeleton, lastTime, time, firedEvents, alpha) {
- var frames = this.frames;
- if (time < frames[0]) {
- if (lastTime > time) this.apply(skeleton, lastTime, Number.MAX_VALUE, null, 0);
- return;
- } else if (lastTime > time) //
- lastTime = -1;
- var frameIndex = (time >= frames[frames.length - 2] ? frames.length : spine.Animation.binarySearch(frames, time, 2)) - 2;
- if (frames[frameIndex] < lastTime) return;
- skeleton.bones[this.boneIndex].flipY = frames[frameIndex + 1] != 0;
- }
-};
-
-spine.SkeletonData = function () {
- this.bones = [];
- this.slots = [];
- this.skins = [];
- this.events = [];
- this.animations = [];
- this.ikConstraints = [];
-};
-spine.SkeletonData.prototype = {
- name: null,
- defaultSkin: null,
- width: 0, height: 0,
- version: null, hash: null,
- /** @return May be null. */
- findBone: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].name == boneName) return bones[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findBoneIndex: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].name == boneName) return i;
- return -1;
- },
- /** @return May be null. */
- findSlot: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- if (slots[i].name == slotName) return slot[i];
- }
- return null;
- },
- /** @return -1 if the bone was not found. */
- findSlotIndex: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].name == slotName) return i;
- return -1;
- },
- /** @return May be null. */
- findSkin: function (skinName) {
- var skins = this.skins;
- for (var i = 0, n = skins.length; i < n; i++)
- if (skins[i].name == skinName) return skins[i];
- return null;
- },
- /** @return May be null. */
- findEvent: function (eventName) {
- var events = this.events;
- for (var i = 0, n = events.length; i < n; i++)
- if (events[i].name == eventName) return events[i];
- return null;
- },
- /** @return May be null. */
- findAnimation: function (animationName) {
- var animations = this.animations;
- for (var i = 0, n = animations.length; i < n; i++)
- if (animations[i].name == animationName) return animations[i];
- return null;
- },
- /** @return May be null. */
- findIkConstraint: function (ikConstraintName) {
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++)
- if (ikConstraints[i].name == ikConstraintName) return ikConstraints[i];
- return null;
- }
-};
-
-spine.Skeleton = function (skeletonData) {
- this.data = skeletonData;
-
- this.bones = [];
- for (var i = 0, n = skeletonData.bones.length; i < n; i++) {
- var boneData = skeletonData.bones[i];
- var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)];
- this.bones.push(new spine.Bone(boneData, this, parent));
- }
-
- this.slots = [];
- this.drawOrder = [];
- for (var i = 0, n = skeletonData.slots.length; i < n; i++) {
- var slotData = skeletonData.slots[i];
- var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)];
- var slot = new spine.Slot(slotData, bone);
- this.slots.push(slot);
- this.drawOrder.push(slot);
- }
-
- this.ikConstraints = [];
- for (var i = 0, n = skeletonData.ikConstraints.length; i < n; i++)
- this.ikConstraints.push(new spine.IkConstraint(skeletonData.ikConstraints[i], this));
-
- this.boneCache = [];
- this.updateCache();
-};
-spine.Skeleton.prototype = {
- x: 0, y: 0,
- skin: null,
- r: 1, g: 1, b: 1, a: 1,
- time: 0,
- flipX: false, flipY: false,
- /** Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or removed. */
- updateCache: function () {
- var ikConstraints = this.ikConstraints;
- var ikConstraintsCount = ikConstraints.length;
-
- var arrayCount = ikConstraintsCount + 1;
- var boneCache = this.boneCache;
- if (boneCache.length > arrayCount) boneCache.length = arrayCount;
- for (var i = 0, n = boneCache.length; i < n; i++)
- boneCache[i].length = 0;
- while (boneCache.length < arrayCount)
- boneCache[boneCache.length] = [];
-
- var nonIkBones = boneCache[0];
- var bones = this.bones;
-
- outer:
- for (var i = 0, n = bones.length; i < n; i++) {
- var bone = bones[i];
- var current = bone;
- do {
- for (var ii = 0; ii < ikConstraintsCount; ii++) {
- var ikConstraint = ikConstraints[ii];
- var parent = ikConstraint.bones[0];
- var child= ikConstraint.bones[ikConstraint.bones.length - 1];
- while (true) {
- if (current == child) {
- boneCache[ii].push(bone);
- boneCache[ii + 1].push(bone);
- continue outer;
- }
- if (child == parent) break;
- child = child.parent;
- }
- }
- current = current.parent;
- } while (current);
- nonIkBones[nonIkBones.length] = bone;
- }
- },
- /** Updates the world transform for each bone. */
- updateWorldTransform: function () {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++) {
- var bone = bones[i];
- bone.rotationIK = bone.rotation;
- }
- var i = 0, last = this.boneCache.length - 1;
- while (true) {
- var cacheBones = this.boneCache[i];
- for (var ii = 0, nn = cacheBones.length; ii < nn; ii++)
- cacheBones[ii].updateWorldTransform();
- if (i == last) break;
- this.ikConstraints[i].apply();
- i++;
- }
- },
- /** Sets the bones and slots to their setup pose values. */
- setToSetupPose: function () {
- this.setBonesToSetupPose();
- this.setSlotsToSetupPose();
- },
- setBonesToSetupPose: function () {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- bones[i].setToSetupPose();
-
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++) {
- var ikConstraint = ikConstraints[i];
- ikConstraint.bendDirection = ikConstraint.data.bendDirection;
- ikConstraint.mix = ikConstraint.data.mix;
- }
- },
- setSlotsToSetupPose: function () {
- var slots = this.slots;
- var drawOrder = this.drawOrder;
- for (var i = 0, n = slots.length; i < n; i++) {
- drawOrder[i] = slots[i];
- slots[i].setToSetupPose(i);
- }
- },
- /** @return May return null. */
- getRootBone: function () {
- return this.bones.length ? this.bones[0] : null;
- },
- /** @return May be null. */
- findBone: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].data.name == boneName) return bones[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findBoneIndex: function (boneName) {
- var bones = this.bones;
- for (var i = 0, n = bones.length; i < n; i++)
- if (bones[i].data.name == boneName) return i;
- return -1;
- },
- /** @return May be null. */
- findSlot: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].data.name == slotName) return slots[i];
- return null;
- },
- /** @return -1 if the bone was not found. */
- findSlotIndex: function (slotName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++)
- if (slots[i].data.name == slotName) return i;
- return -1;
- },
- setSkinByName: function (skinName) {
- var skin = this.data.findSkin(skinName);
- if (!skin) throw "Skin not found: " + skinName;
- this.setSkin(skin);
- },
- /** Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default skin}.
- * Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was
- * no old skin, each slot's setup mode attachment is attached from the new skin.
- * @param newSkin May be null. */
- setSkin: function (newSkin) {
- if (newSkin) {
- if (this.skin)
- newSkin._attachAll(this, this.skin);
- else {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- var slot = slots[i];
- var name = slot.data.attachmentName;
- if (name) {
- var attachment = newSkin.getAttachment(i, name);
- if (attachment) slot.setAttachment(attachment);
- }
- }
- }
- }
- this.skin = newSkin;
- },
- /** @return May be null. */
- getAttachmentBySlotName: function (slotName, attachmentName) {
- return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName);
- },
- /** @return May be null. */
- getAttachmentBySlotIndex: function (slotIndex, attachmentName) {
- if (this.skin) {
- var attachment = this.skin.getAttachment(slotIndex, attachmentName);
- if (attachment) return attachment;
- }
- if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName);
- return null;
- },
- /** @param attachmentName May be null. */
- setAttachment: function (slotName, attachmentName) {
- var slots = this.slots;
- for (var i = 0, n = slots.length; i < n; i++) {
- var slot = slots[i];
- if (slot.data.name == slotName) {
- var attachment = null;
- if (attachmentName) {
- attachment = this.getAttachmentBySlotIndex(i, attachmentName);
- if (!attachment) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName;
- }
- slot.setAttachment(attachment);
- return;
- }
- }
- throw "Slot not found: " + slotName;
- },
- /** @return May be null. */
- findIkConstraint: function (ikConstraintName) {
- var ikConstraints = this.ikConstraints;
- for (var i = 0, n = ikConstraints.length; i < n; i++)
- if (ikConstraints[i].data.name == ikConstraintName) return ikConstraints[i];
- return null;
- },
- update: function (delta) {
- this.time += delta;
- }
-};
-
-spine.EventData = function (name) {
- this.name = name;
-};
-spine.EventData.prototype = {
- intValue: 0,
- floatValue: 0,
- stringValue: null
-};
-
-spine.Event = function (data) {
- this.data = data;
-};
-spine.Event.prototype = {
- intValue: 0,
- floatValue: 0,
- stringValue: null
-};
-
-spine.AttachmentType = {
- region: 0,
- boundingbox: 1,
- mesh: 2,
- skinnedmesh: 3
-};
-
-spine.RegionAttachment = function (name) {
- this.name = name;
- this.offset = [];
- this.offset.length = 8;
- this.uvs = [];
- this.uvs.length = 8;
-};
-spine.RegionAttachment.prototype = {
- type: spine.AttachmentType.region,
- x: 0, y: 0,
- rotation: 0,
- scaleX: 1, scaleY: 1,
- width: 0, height: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- rendererObject: null,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- setUVs: function (u, v, u2, v2, rotate) {
- var uvs = this.uvs;
- if (rotate) {
- uvs[2/*X2*/] = u;
- uvs[3/*Y2*/] = v2;
- uvs[4/*X3*/] = u;
- uvs[5/*Y3*/] = v;
- uvs[6/*X4*/] = u2;
- uvs[7/*Y4*/] = v;
- uvs[0/*X1*/] = u2;
- uvs[1/*Y1*/] = v2;
- } else {
- uvs[0/*X1*/] = u;
- uvs[1/*Y1*/] = v2;
- uvs[2/*X2*/] = u;
- uvs[3/*Y2*/] = v;
- uvs[4/*X3*/] = u2;
- uvs[5/*Y3*/] = v;
- uvs[6/*X4*/] = u2;
- uvs[7/*Y4*/] = v2;
- }
- },
- updateOffset: function () {
- var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX;
- var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY;
- var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX;
- var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY;
- var localX2 = localX + this.regionWidth * regionScaleX;
- var localY2 = localY + this.regionHeight * regionScaleY;
- var radians = this.rotation * spine.degRad;
- var cos = Math.cos(radians);
- var sin = Math.sin(radians);
- var localXCos = localX * cos + this.x;
- var localXSin = localX * sin;
- var localYCos = localY * cos + this.y;
- var localYSin = localY * sin;
- var localX2Cos = localX2 * cos + this.x;
- var localX2Sin = localX2 * sin;
- var localY2Cos = localY2 * cos + this.y;
- var localY2Sin = localY2 * sin;
- var offset = this.offset;
- offset[0/*X1*/] = localXCos - localYSin;
- offset[1/*Y1*/] = localYCos + localXSin;
- offset[2/*X2*/] = localXCos - localY2Sin;
- offset[3/*Y2*/] = localY2Cos + localXSin;
- offset[4/*X3*/] = localX2Cos - localY2Sin;
- offset[5/*Y3*/] = localY2Cos + localX2Sin;
- offset[6/*X4*/] = localX2Cos - localYSin;
- offset[7/*Y4*/] = localYCos + localX2Sin;
- },
- computeVertices: function (x, y, bone, vertices) {
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
- var offset = this.offset;
- vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x;
- vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y;
- vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x;
- vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y;
- vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x;
- vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y;
- vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x;
- vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y;
- }
-};
-
-spine.MeshAttachment = function (name) {
- this.name = name;
-};
-spine.MeshAttachment.prototype = {
- type: spine.AttachmentType.mesh,
- vertices: null,
- uvs: null,
- regionUVs: null,
- triangles: null,
- hullLength: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- rendererObject: null,
- regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- edges: null,
- width: 0, height: 0,
- updateUVs: function () {
- var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV;
- var n = this.regionUVs.length;
- if (!this.uvs || this.uvs.length != n) {
- this.uvs = new spine.Float32Array(n);
- }
- if (this.regionRotate) {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width;
- this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height;
- }
- } else {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i] * width;
- this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height;
- }
- }
- },
- computeWorldVertices: function (x, y, slot, worldVertices) {
- var bone = slot.bone;
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
- var vertices = this.vertices;
- var verticesCount = vertices.length;
- if (slot.attachmentVertices.length == verticesCount) vertices = slot.attachmentVertices;
- for (var i = 0; i < verticesCount; i += 2) {
- var vx = vertices[i];
- var vy = vertices[i + 1];
- worldVertices[i] = vx * m00 + vy * m01 + x;
- worldVertices[i + 1] = vx * m10 + vy * m11 + y;
- }
- }
-};
-
-spine.SkinnedMeshAttachment = function (name) {
- this.name = name;
-};
-spine.SkinnedMeshAttachment.prototype = {
- type: spine.AttachmentType.skinnedmesh,
- bones: null,
- weights: null,
- uvs: null,
- regionUVs: null,
- triangles: null,
- hullLength: 0,
- r: 1, g: 1, b: 1, a: 1,
- path: null,
- rendererObject: null,
- regionU: 0, regionV: 0, regionU2: 0, regionV2: 0, regionRotate: false,
- regionOffsetX: 0, regionOffsetY: 0,
- regionWidth: 0, regionHeight: 0,
- regionOriginalWidth: 0, regionOriginalHeight: 0,
- edges: null,
- width: 0, height: 0,
- updateUVs: function (u, v, u2, v2, rotate) {
- var width = this.regionU2 - this.regionU, height = this.regionV2 - this.regionV;
- var n = this.regionUVs.length;
- if (!this.uvs || this.uvs.length != n) {
- this.uvs = new spine.Float32Array(n);
- }
- if (this.regionRotate) {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i + 1] * width;
- this.uvs[i + 1] = this.regionV + height - this.regionUVs[i] * height;
- }
- } else {
- for (var i = 0; i < n; i += 2) {
- this.uvs[i] = this.regionU + this.regionUVs[i] * width;
- this.uvs[i + 1] = this.regionV + this.regionUVs[i + 1] * height;
- }
- }
- },
- computeWorldVertices: function (x, y, slot, worldVertices) {
- var skeletonBones = slot.bone.skeleton.bones;
- var weights = this.weights;
- var bones = this.bones;
-
- var w = 0, v = 0, b = 0, f = 0, n = bones.length, nn;
- var wx, wy, bone, vx, vy, weight;
- if (!slot.attachmentVertices.length) {
- for (; v < n; w += 2) {
- wx = 0;
- wy = 0;
- nn = bones[v++] + v;
- for (; v < nn; v++, b += 3) {
- bone = skeletonBones[bones[v]];
- vx = weights[b];
- vy = weights[b + 1];
- weight = weights[b + 2];
- wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
- wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
- }
- worldVertices[w] = wx + x;
- worldVertices[w + 1] = wy + y;
- }
- } else {
- var ffd = slot.attachmentVertices;
- for (; v < n; w += 2) {
- wx = 0;
- wy = 0;
- nn = bones[v++] + v;
- for (; v < nn; v++, b += 3, f += 2) {
- bone = skeletonBones[bones[v]];
- vx = weights[b] + ffd[f];
- vy = weights[b + 1] + ffd[f + 1];
- weight = weights[b + 2];
- wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
- wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
- }
- worldVertices[w] = wx + x;
- worldVertices[w + 1] = wy + y;
- }
- }
- }
-};
-
-spine.BoundingBoxAttachment = function (name) {
- this.name = name;
- this.vertices = [];
-};
-spine.BoundingBoxAttachment.prototype = {
- type: spine.AttachmentType.boundingbox,
- computeWorldVertices: function (x, y, bone, worldVertices) {
- x += bone.worldX;
- y += bone.worldY;
- var m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
- var vertices = this.vertices;
- for (var i = 0, n = vertices.length; i < n; i += 2) {
- var px = vertices[i];
- var py = vertices[i + 1];
- worldVertices[i] = px * m00 + py * m01 + x;
- worldVertices[i + 1] = px * m10 + py * m11 + y;
- }
- }
-};
-
-spine.AnimationStateData = function (skeletonData) {
- this.skeletonData = skeletonData;
- this.animationToMixTime = {};
-};
-spine.AnimationStateData.prototype = {
- defaultMix: 0,
- setMixByName: function (fromName, toName, duration) {
- var from = this.skeletonData.findAnimation(fromName);
- if (!from) throw "Animation not found: " + fromName;
- var to = this.skeletonData.findAnimation(toName);
- if (!to) throw "Animation not found: " + toName;
- this.setMix(from, to, duration);
- },
- setMix: function (from, to, duration) {
- this.animationToMixTime[from.name + ":" + to.name] = duration;
- },
- getMix: function (from, to) {
- var key = from.name + ":" + to.name;
- return this.animationToMixTime.hasOwnProperty(key) ? this.animationToMixTime[key] : this.defaultMix;
- }
-};
-
-spine.TrackEntry = function () {};
-spine.TrackEntry.prototype = {
- next: null, previous: null,
- animation: null,
- loop: false,
- delay: 0, time: 0, lastTime: -1, endTime: 0,
- timeScale: 1,
- mixTime: 0, mixDuration: 0, mix: 1,
- onStart: null, onEnd: null, onComplete: null, onEvent: null
-};
-
-spine.AnimationState = function (stateData) {
- this.data = stateData;
- this.tracks = [];
- this.events = [];
-};
-spine.AnimationState.prototype = {
- onStart: null,
- onEnd: null,
- onComplete: null,
- onEvent: null,
- timeScale: 1,
- update: function (delta) {
- delta *= this.timeScale;
- for (var i = 0; i < this.tracks.length; i++) {
- var current = this.tracks[i];
- if (!current) continue;
-
- current.time += delta * current.timeScale;
- if (current.previous) {
- var previousDelta = delta * current.previous.timeScale;
- current.previous.time += previousDelta;
- current.mixTime += previousDelta;
- }
-
- var next = current.next;
- if (next) {
- next.time = current.lastTime - next.delay;
- if (next.time >= 0) this.setCurrent(i, next);
- } else {
- // End non-looping animation when it reaches its end time and there is no next entry.
- if (!current.loop && current.lastTime >= current.endTime) this.clearTrack(i);
- }
- }
- },
- apply: function (skeleton) {
- for (var i = 0; i < this.tracks.length; i++) {
- var current = this.tracks[i];
- if (!current) continue;
-
- this.events.length = 0;
-
- var time = current.time;
- var lastTime = current.lastTime;
- var endTime = current.endTime;
- var loop = current.loop;
- if (!loop && time > endTime) time = endTime;
-
- var previous = current.previous;
- if (!previous) {
- if (current.mix == 1)
- current.animation.apply(skeleton, current.lastTime, time, loop, this.events);
- else
- current.animation.mix(skeleton, current.lastTime, time, loop, this.events, current.mix);
- } else {
- var previousTime = previous.time;
- if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
- previous.animation.apply(skeleton, previousTime, previousTime, previous.loop, null);
-
- var alpha = current.mixTime / current.mixDuration * current.mix;
- if (alpha >= 1) {
- alpha = 1;
- current.previous = null;
- }
- current.animation.mix(skeleton, current.lastTime, time, loop, this.events, alpha);
- }
-
- for (var ii = 0, nn = this.events.length; ii < nn; ii++) {
- var event = this.events[ii];
- if (current.onEvent) current.onEvent(i, event);
- if (this.onEvent) this.onEvent(i, event);
- }
-
- // Check if completed the animation or a loop iteration.
- if (loop ? (lastTime % endTime > time % endTime) : (lastTime < endTime && time >= endTime)) {
- var count = Math.floor(time / endTime);
- if (current.onComplete) current.onComplete(i, count);
- if (this.onComplete) this.onComplete(i, count);
- }
-
- current.lastTime = current.time;
- }
- },
- clearTracks: function () {
- for (var i = 0, n = this.tracks.length; i < n; i++)
- this.clearTrack(i);
- this.tracks.length = 0;
- },
- clearTrack: function (trackIndex) {
- if (trackIndex >= this.tracks.length) return;
- var current = this.tracks[trackIndex];
- if (!current) return;
-
- if (current.onEnd) current.onEnd(trackIndex);
- if (this.onEnd) this.onEnd(trackIndex);
-
- this.tracks[trackIndex] = null;
- },
- _expandToIndex: function (index) {
- if (index < this.tracks.length) return this.tracks[index];
- while (index >= this.tracks.length)
- this.tracks.push(null);
- return null;
- },
- setCurrent: function (index, entry) {
- var current = this._expandToIndex(index);
- if (current) {
- var previous = current.previous;
- current.previous = null;
-
- if (current.onEnd) current.onEnd(index);
- if (this.onEnd) this.onEnd(index);
-
- entry.mixDuration = this.data.getMix(current.animation, entry.animation);
- if (entry.mixDuration > 0) {
- entry.mixTime = 0;
- // If a mix is in progress, mix from the closest animation.
- if (previous && current.mixTime / current.mixDuration < 0.5)
- entry.previous = previous;
- else
- entry.previous = current;
- }
- }
-
- this.tracks[index] = entry;
-
- if (entry.onStart) entry.onStart(index);
- if (this.onStart) this.onStart(index);
- },
- setAnimationByName: function (trackIndex, animationName, loop) {
- var animation = this.data.skeletonData.findAnimation(animationName);
- if (!animation) throw "Animation not found: " + animationName;
- return this.setAnimation(trackIndex, animation, loop);
- },
- /** Set the current animation. Any queued animations are cleared. */
- setAnimation: function (trackIndex, animation, loop) {
- var entry = new spine.TrackEntry();
- entry.animation = animation;
- entry.loop = loop;
- entry.endTime = animation.duration;
- this.setCurrent(trackIndex, entry);
- return entry;
- },
- addAnimationByName: function (trackIndex, animationName, loop, delay) {
- var animation = this.data.skeletonData.findAnimation(animationName);
- if (!animation) throw "Animation not found: " + animationName;
- return this.addAnimation(trackIndex, animation, loop, delay);
- },
- /** Adds an animation to be played delay seconds after the current or last queued animation.
- * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */
- addAnimation: function (trackIndex, animation, loop, delay) {
- var entry = new spine.TrackEntry();
- entry.animation = animation;
- entry.loop = loop;
- entry.endTime = animation.duration;
-
- var last = this._expandToIndex(trackIndex);
- if (last) {
- while (last.next)
- last = last.next;
- last.next = entry;
- } else
- this.tracks[trackIndex] = entry;
-
- if (delay <= 0) {
- if (last)
- delay += last.endTime - this.data.getMix(last.animation, animation);
- else
- delay = 0;
- }
- entry.delay = delay;
-
- return entry;
- },
- /** May be null. */
- getCurrent: function (trackIndex) {
- if (trackIndex >= this.tracks.length) return null;
- return this.tracks[trackIndex];
- }
-};
-
-spine.SkeletonJson = function (attachmentLoader) {
- this.attachmentLoader = attachmentLoader;
-};
-spine.SkeletonJson.prototype = {
- scale: 1,
- readSkeletonData: function (root, name) {
- var skeletonData = new spine.SkeletonData();
- skeletonData.name = name;
-
- // Skeleton.
- var skeletonMap = root["skeleton"];
- if (skeletonMap) {
- skeletonData.hash = skeletonMap["hash"];
- skeletonData.version = skeletonMap["spine"];
- skeletonData.width = skeletonMap["width"] || 0;
- skeletonData.height = skeletonMap["height"] || 0;
- }
-
- // Bones.
- var bones = root["bones"];
- for (var i = 0, n = bones.length; i < n; i++) {
- var boneMap = bones[i];
- var parent = null;
- if (boneMap["parent"]) {
- parent = skeletonData.findBone(boneMap["parent"]);
- if (!parent) throw "Parent bone not found: " + boneMap["parent"];
- }
- var boneData = new spine.BoneData(boneMap["name"], parent);
- boneData.length = (boneMap["length"] || 0) * this.scale;
- boneData.x = (boneMap["x"] || 0) * this.scale;
- boneData.y = (boneMap["y"] || 0) * this.scale;
- boneData.rotation = (boneMap["rotation"] || 0);
- boneData.scaleX = boneMap.hasOwnProperty("scaleX") ? boneMap["scaleX"] : 1;
- boneData.scaleY = boneMap.hasOwnProperty("scaleY") ? boneMap["scaleY"] : 1;
- boneData.inheritScale = boneMap.hasOwnProperty("inheritScale") ? boneMap["inheritScale"] : true;
- boneData.inheritRotation = boneMap.hasOwnProperty("inheritRotation") ? boneMap["inheritRotation"] : true;
- skeletonData.bones.push(boneData);
- }
-
- // IK constraints.
- var ik = root["ik"];
- if (ik) {
- for (var i = 0, n = ik.length; i < n; i++) {
- var ikMap = ik[i];
- var ikConstraintData = new spine.IkConstraintData(ikMap["name"]);
-
- var bones = ikMap["bones"];
- for (var ii = 0, nn = bones.length; ii < nn; ii++) {
- var bone = skeletonData.findBone(bones[ii]);
- if (!bone) throw "IK bone not found: " + bones[ii];
- ikConstraintData.bones.push(bone);
- }
-
- ikConstraintData.target = skeletonData.findBone(ikMap["target"]);
- if (!ikConstraintData.target) throw "Target bone not found: " + ikMap["target"];
-
- ikConstraintData.bendDirection = (!ikMap.hasOwnProperty("bendPositive") || ikMap["bendPositive"]) ? 1 : -1;
- ikConstraintData.mix = ikMap.hasOwnProperty("mix") ? ikMap["mix"] : 1;
-
- skeletonData.ikConstraints.push(ikConstraintData);
- }
- }
-
- // Slots.
- var slots = root["slots"];
- for (var i = 0, n = slots.length; i < n; i++) {
- var slotMap = slots[i];
- var boneData = skeletonData.findBone(slotMap["bone"]);
- if (!boneData) throw "Slot bone not found: " + slotMap["bone"];
- var slotData = new spine.SlotData(slotMap["name"], boneData);
-
- var color = slotMap["color"];
- if (color) {
- slotData.r = this.toColor(color, 0);
- slotData.g = this.toColor(color, 1);
- slotData.b = this.toColor(color, 2);
- slotData.a = this.toColor(color, 3);
- }
-
- slotData.attachmentName = slotMap["attachment"];
- slotData.additiveBlending = slotMap["additive"] && slotMap["additive"] == "true";
-
- skeletonData.slots.push(slotData);
- }
-
- // Skins.
- var skins = root["skins"];
- for (var skinName in skins) {
- if (!skins.hasOwnProperty(skinName)) continue;
- var skinMap = skins[skinName];
- var skin = new spine.Skin(skinName);
- for (var slotName in skinMap) {
- if (!skinMap.hasOwnProperty(slotName)) continue;
- var slotIndex = skeletonData.findSlotIndex(slotName);
- var slotEntry = skinMap[slotName];
- for (var attachmentName in slotEntry) {
- if (!slotEntry.hasOwnProperty(attachmentName)) continue;
- var attachment = this.readAttachment(skin, attachmentName, slotEntry[attachmentName]);
- if (attachment) skin.addAttachment(slotIndex, attachmentName, attachment);
- }
- }
- skeletonData.skins.push(skin);
- if (skin.name == "default") skeletonData.defaultSkin = skin;
- }
-
- // Events.
- var events = root["events"];
- for (var eventName in events) {
- if (!events.hasOwnProperty(eventName)) continue;
- var eventMap = events[eventName];
- var eventData = new spine.EventData(eventName);
- eventData.intValue = eventMap["int"] || 0;
- eventData.floatValue = eventMap["float"] || 0;
- eventData.stringValue = eventMap["string"] || null;
- skeletonData.events.push(eventData);
- }
-
- // Animations.
- var animations = root["animations"];
- for (var animationName in animations) {
- if (!animations.hasOwnProperty(animationName)) continue;
- this.readAnimation(animationName, animations[animationName], skeletonData);
- }
-
- return skeletonData;
- },
- readAttachment: function (skin, name, map) {
- name = map["name"] || name;
-
- var type = spine.AttachmentType[map["type"] || "region"];
- var path = map["path"] || name;
-
- var scale = this.scale;
- if (type == spine.AttachmentType.region) {
- var region = this.attachmentLoader.newRegionAttachment(skin, name, path);
- if (!region) return null;
- region.path = path;
- region.x = (map["x"] || 0) * scale;
- region.y = (map["y"] || 0) * scale;
- region.scaleX = map.hasOwnProperty("scaleX") ? map["scaleX"] : 1;
- region.scaleY = map.hasOwnProperty("scaleY") ? map["scaleY"] : 1;
- region.rotation = map["rotation"] || 0;
- region.width = (map["width"] || 0) * scale;
- region.height = (map["height"] || 0) * scale;
-
- var color = map["color"];
- if (color) {
- region.r = this.toColor(color, 0);
- region.g = this.toColor(color, 1);
- region.b = this.toColor(color, 2);
- region.a = this.toColor(color, 3);
- }
-
- region.updateOffset();
- return region;
- } else if (type == spine.AttachmentType.mesh) {
- var mesh = this.attachmentLoader.newMeshAttachment(skin, name, path);
- if (!mesh) return null;
- mesh.path = path;
- mesh.vertices = this.getFloatArray(map, "vertices", scale);
- mesh.triangles = this.getIntArray(map, "triangles");
- mesh.regionUVs = this.getFloatArray(map, "uvs", 1);
- mesh.updateUVs();
-
- color = map["color"];
- if (color) {
- mesh.r = this.toColor(color, 0);
- mesh.g = this.toColor(color, 1);
- mesh.b = this.toColor(color, 2);
- mesh.a = this.toColor(color, 3);
- }
-
- mesh.hullLength = (map["hull"] || 0) * 2;
- if (map["edges"]) mesh.edges = this.getIntArray(map, "edges");
- mesh.width = (map["width"] || 0) * scale;
- mesh.height = (map["height"] || 0) * scale;
- return mesh;
- } else if (type == spine.AttachmentType.skinnedmesh) {
- var mesh = this.attachmentLoader.newSkinnedMeshAttachment(skin, name, path);
- if (!mesh) return null;
- mesh.path = path;
-
- var uvs = this.getFloatArray(map, "uvs", 1);
- var vertices = this.getFloatArray(map, "vertices", 1);
- var weights = [];
- var bones = [];
- for (var i = 0, n = vertices.length; i < n; ) {
- var boneCount = vertices[i++] | 0;
- bones[bones.length] = boneCount;
- for (var nn = i + boneCount * 4; i < nn; ) {
- bones[bones.length] = vertices[i];
- weights[weights.length] = vertices[i + 1] * scale;
- weights[weights.length] = vertices[i + 2] * scale;
- weights[weights.length] = vertices[i + 3];
- i += 4;
- }
- }
- mesh.bones = bones;
- mesh.weights = weights;
- mesh.triangles = this.getIntArray(map, "triangles");
- mesh.regionUVs = uvs;
- mesh.updateUVs();
-
- color = map["color"];
- if (color) {
- mesh.r = this.toColor(color, 0);
- mesh.g = this.toColor(color, 1);
- mesh.b = this.toColor(color, 2);
- mesh.a = this.toColor(color, 3);
- }
-
- mesh.hullLength = (map["hull"] || 0) * 2;
- if (map["edges"]) mesh.edges = this.getIntArray(map, "edges");
- mesh.width = (map["width"] || 0) * scale;
- mesh.height = (map["height"] || 0) * scale;
- return mesh;
- } else if (type == spine.AttachmentType.boundingbox) {
- var attachment = this.attachmentLoader.newBoundingBoxAttachment(skin, name);
- var vertices = map["vertices"];
- for (var i = 0, n = vertices.length; i < n; i++)
- attachment.vertices.push(vertices[i] * scale);
- return attachment;
- }
- throw "Unknown attachment type: " + type;
- },
- readAnimation: function (name, map, skeletonData) {
- var timelines = [];
- var duration = 0;
-
- var slots = map["slots"];
- for (var slotName in slots) {
- if (!slots.hasOwnProperty(slotName)) continue;
- var slotMap = slots[slotName];
- var slotIndex = skeletonData.findSlotIndex(slotName);
-
- for (var timelineName in slotMap) {
- if (!slotMap.hasOwnProperty(timelineName)) continue;
- var values = slotMap[timelineName];
- if (timelineName == "color") {
- var timeline = new spine.ColorTimeline(values.length);
- timeline.slotIndex = slotIndex;
-
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var color = valueMap["color"];
- var r = this.toColor(color, 0);
- var g = this.toColor(color, 1);
- var b = this.toColor(color, 2);
- var a = this.toColor(color, 3);
- timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5] || 0);
-
- } else if (timelineName == "attachment") {
- var timeline = new spine.AttachmentTimeline(values.length);
- timeline.slotIndex = slotIndex;
-
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]);
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1] || 0);
-
- } else
- throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")";
- }
- }
-
- var bones = map["bones"];
- for (var boneName in bones) {
- if (!bones.hasOwnProperty(boneName)) continue;
- var boneIndex = skeletonData.findBoneIndex(boneName);
- if (boneIndex == -1) throw "Bone not found: " + boneName;
- var boneMap = bones[boneName];
-
- for (var timelineName in boneMap) {
- if (!boneMap.hasOwnProperty(timelineName)) continue;
- var values = boneMap[timelineName];
- if (timelineName == "rotate") {
- var timeline = new spine.RotateTimeline(values.length);
- timeline.boneIndex = boneIndex;
-
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2] || 0);
-
- } else if (timelineName == "translate" || timelineName == "scale") {
- var timeline;
- var timelineScale = 1;
- if (timelineName == "scale")
- timeline = new spine.ScaleTimeline(values.length);
- else {
- timeline = new spine.TranslateTimeline(values.length);
- timelineScale = this.scale;
- }
- timeline.boneIndex = boneIndex;
-
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var x = (valueMap["x"] || 0) * timelineScale;
- var y = (valueMap["y"] || 0) * timelineScale;
- timeline.setFrame(frameIndex, valueMap["time"], x, y);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3] || 0);
-
- } else if (timelineName == "flipX" || timelineName == "flipY") {
- var x = timelineName == "flipX";
- var timeline = x ? new spine.FlipXTimeline(values.length) : new spine.FlipYTimeline(values.length);
- timeline.boneIndex = boneIndex;
-
- var field = x ? "x" : "y";
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- timeline.setFrame(frameIndex, valueMap["time"], valueMap[field] || false);
- frameIndex++;
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2] || 0);
- } else
- throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")";
- }
- }
-
- var ikMap = map["ik"];
- for (var ikConstraintName in ikMap) {
- if (!ikMap.hasOwnProperty(ikConstraintName)) continue;
- var ikConstraint = skeletonData.findIkConstraint(ikConstraintName);
- var values = ikMap[ikConstraintName];
- var timeline = new spine.IkConstraintTimeline(values.length);
- timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(ikConstraint);
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var mix = valueMap.hasOwnProperty("mix") ? valueMap["mix"] : 1;
- var bendDirection = (!valueMap.hasOwnProperty("bendPositive") || valueMap["bendPositive"]) ? 1 : -1;
- timeline.setFrame(frameIndex, valueMap["time"], mix, bendDirection);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.frameCount * 3 - 3] || 0);
- }
-
- var ffd = map["ffd"];
- for (var skinName in ffd) {
- var skin = skeletonData.findSkin(skinName);
- var slotMap = ffd[skinName];
- for (slotName in slotMap) {
- var slotIndex = skeletonData.findSlotIndex(slotName);
- var meshMap = slotMap[slotName];
- for (var meshName in meshMap) {
- var values = meshMap[meshName];
- var timeline = new spine.FfdTimeline(values.length);
- var attachment = skin.getAttachment(slotIndex, meshName);
- if (!attachment) throw "FFD attachment not found: " + meshName;
- timeline.slotIndex = slotIndex;
- timeline.attachment = attachment;
-
- var isMesh = attachment.type == spine.AttachmentType.mesh;
- var vertexCount;
- if (isMesh)
- vertexCount = attachment.vertices.length;
- else
- vertexCount = attachment.weights.length / 3 * 2;
-
- var frameIndex = 0;
- for (var i = 0, n = values.length; i < n; i++) {
- var valueMap = values[i];
- var vertices;
- if (!valueMap["vertices"]) {
- if (isMesh)
- vertices = attachment.vertices;
- else {
- vertices = [];
- vertices.length = vertexCount;
- }
- } else {
- var verticesValue = valueMap["vertices"];
- var vertices = [];
- vertices.length = vertexCount;
- var start = valueMap["offset"] || 0;
- var nn = verticesValue.length;
- if (this.scale == 1) {
- for (var ii = 0; ii < nn; ii++)
- vertices[ii + start] = verticesValue[ii];
- } else {
- for (var ii = 0; ii < nn; ii++)
- vertices[ii + start] = verticesValue[ii] * this.scale;
- }
- if (isMesh) {
- var meshVertices = attachment.vertices;
- for (var ii = 0, nn = vertices.length; ii < nn; ii++)
- vertices[ii] += meshVertices[ii];
- }
- }
-
- timeline.setFrame(frameIndex, valueMap["time"], vertices);
- this.readCurve(timeline, frameIndex, valueMap);
- frameIndex++;
- }
- timelines[timelines.length] = timeline;
- duration = Math.max(duration, timeline.frames[timeline.frameCount - 1] || 0);
- }
- }
- }
-
- var drawOrderValues = map["drawOrder"];
- if (!drawOrderValues) drawOrderValues = map["draworder"];
- if (drawOrderValues) {
- var timeline = new spine.DrawOrderTimeline(drawOrderValues.length);
- var slotCount = skeletonData.slots.length;
- var frameIndex = 0;
- for (var i = 0, n = drawOrderValues.length; i < n; i++) {
- var drawOrderMap = drawOrderValues[i];
- var drawOrder = null;
- if (drawOrderMap["offsets"]) {
- drawOrder = [];
- drawOrder.length = slotCount;
- for (var ii = slotCount - 1; ii >= 0; ii--)
- drawOrder[ii] = -1;
- var offsets = drawOrderMap["offsets"];
- var unchanged = [];
- unchanged.length = slotCount - offsets.length;
- var originalIndex = 0, unchangedIndex = 0;
- for (var ii = 0, nn = offsets.length; ii < nn; ii++) {
- var offsetMap = offsets[ii];
- var slotIndex = skeletonData.findSlotIndex(offsetMap["slot"]);
- if (slotIndex == -1) throw "Slot not found: " + offsetMap["slot"];
- // Collect unchanged items.
- while (originalIndex != slotIndex)
- unchanged[unchangedIndex++] = originalIndex++;
- // Set changed items.
- drawOrder[originalIndex + offsetMap["offset"]] = originalIndex++;
- }
- // Collect remaining unchanged items.
- while (originalIndex < slotCount)
- unchanged[unchangedIndex++] = originalIndex++;
- // Fill in unchanged items.
- for (var ii = slotCount - 1; ii >= 0; ii--)
- if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
- }
- timeline.setFrame(frameIndex++, drawOrderMap["time"], drawOrder);
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1] || 0);
- }
-
- var events = map["events"];
- if (events) {
- var timeline = new spine.EventTimeline(events.length);
- var frameIndex = 0;
- for (var i = 0, n = events.length; i < n; i++) {
- var eventMap = events[i];
- var eventData = skeletonData.findEvent(eventMap["name"]);
- if (!eventData) throw "Event not found: " + eventMap["name"];
- var event = new spine.Event(eventData);
- event.intValue = eventMap.hasOwnProperty("int") ? eventMap["int"] : eventData.intValue;
- event.floatValue = eventMap.hasOwnProperty("float") ? eventMap["float"] : eventData.floatValue;
- event.stringValue = eventMap.hasOwnProperty("string") ? eventMap["string"] : eventData.stringValue;
- timeline.setFrame(frameIndex++, eventMap["time"], event);
- }
- timelines.push(timeline);
- duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1] || 0);
- }
-
- skeletonData.animations.push(new spine.Animation(name, timelines, duration));
- },
- readCurve: function (timeline, frameIndex, valueMap) {
- var curve = valueMap["curve"];
- if (!curve)
- timeline.curves.setLinear(frameIndex);
- else if (curve == "stepped")
- timeline.curves.setStepped(frameIndex);
- else if (curve instanceof Array)
- timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]);
- },
- toColor: function (hexString, colorIndex) {
- if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString;
- return parseInt(hexString.substring(colorIndex * 2, (colorIndex * 2) + 2), 16) / 255;
- },
- getFloatArray: function (map, name, scale) {
- var list = map[name];
- var values = new spine.Float32Array(list.length);
- var i = 0, n = list.length;
- if (scale == 1) {
- for (; i < n; i++)
- values[i] = list[i];
- } else {
- for (; i < n; i++)
- values[i] = list[i] * scale;
- }
- return values;
- },
- getIntArray: function (map, name) {
- var list = map[name];
- var values = new spine.Uint16Array(list.length);
- for (var i = 0, n = list.length; i < n; i++)
- values[i] = list[i] | 0;
- return values;
- }
-};
-
-spine.Atlas = function (atlasText, textureLoader) {
- this.textureLoader = textureLoader;
- this.pages = [];
- this.regions = [];
-
- var reader = new spine.AtlasReader(atlasText);
- var tuple = [];
- tuple.length = 4;
- var page = null;
- while (true) {
- var line = reader.readLine();
- if (line === null) break;
- line = reader.trim(line);
- if (!line.length)
- page = null;
- else if (!page) {
- page = new spine.AtlasPage();
- page.name = line;
-
- if (reader.readTuple(tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
- page.width = parseInt(tuple[0]);
- page.height = parseInt(tuple[1]);
- reader.readTuple(tuple);
- }
- page.format = spine.Atlas.Format[tuple[0]];
-
- reader.readTuple(tuple);
- page.minFilter = spine.Atlas.TextureFilter[tuple[0]];
- page.magFilter = spine.Atlas.TextureFilter[tuple[1]];
-
- var direction = reader.readValue();
- page.uWrap = spine.Atlas.TextureWrap.clampToEdge;
- page.vWrap = spine.Atlas.TextureWrap.clampToEdge;
- if (direction == "x")
- page.uWrap = spine.Atlas.TextureWrap.repeat;
- else if (direction == "y")
- page.vWrap = spine.Atlas.TextureWrap.repeat;
- else if (direction == "xy")
- page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat;
-
- textureLoader.load(page, line, this);
-
- this.pages.push(page);
-
- } else {
- var region = new spine.AtlasRegion();
- region.name = line;
- region.page = page;
-
- region.rotate = reader.readValue() == "true";
-
- reader.readTuple(tuple);
- var x = parseInt(tuple[0]);
- var y = parseInt(tuple[1]);
-
- reader.readTuple(tuple);
- var width = parseInt(tuple[0]);
- var height = parseInt(tuple[1]);
-
- region.u = x / page.width;
- region.v = y / page.height;
- if (region.rotate) {
- region.u2 = (x + height) / page.width;
- region.v2 = (y + width) / page.height;
- } else {
- region.u2 = (x + width) / page.width;
- region.v2 = (y + height) / page.height;
- }
- region.x = x;
- region.y = y;
- region.width = Math.abs(width);
- region.height = Math.abs(height);
-
- if (reader.readTuple(tuple) == 4) { // split is optional
- region.splits = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
-
- if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits
- region.pads = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])];
-
- reader.readTuple(tuple);
- }
- }
-
- region.originalWidth = parseInt(tuple[0]);
- region.originalHeight = parseInt(tuple[1]);
-
- reader.readTuple(tuple);
- region.offsetX = parseInt(tuple[0]);
- region.offsetY = parseInt(tuple[1]);
-
- region.index = parseInt(reader.readValue());
-
- this.regions.push(region);
- }
- }
-};
-spine.Atlas.prototype = {
- findRegion: function (name) {
- var regions = this.regions;
- for (var i = 0, n = regions.length; i < n; i++)
- if (regions[i].name == name) return regions[i];
- return null;
- },
- dispose: function () {
- var pages = this.pages;
- for (var i = 0, n = pages.length; i < n; i++)
- this.textureLoader.unload(pages[i].rendererObject);
- },
- updateUVs: function (page) {
- var regions = this.regions;
- for (var i = 0, n = regions.length; i < n; i++) {
- var region = regions[i];
- if (region.page != page) continue;
- region.u = region.x / page.width;
- region.v = region.y / page.height;
- if (region.rotate) {
- region.u2 = (region.x + region.height) / page.width;
- region.v2 = (region.y + region.width) / page.height;
- } else {
- region.u2 = (region.x + region.width) / page.width;
- region.v2 = (region.y + region.height) / page.height;
- }
- }
- }
-};
-
-spine.Atlas.Format = {
- alpha: 0,
- intensity: 1,
- luminanceAlpha: 2,
- rgb565: 3,
- rgba4444: 4,
- rgb888: 5,
- rgba8888: 6
-};
-
-spine.Atlas.TextureFilter = {
- nearest: 0,
- linear: 1,
- mipMap: 2,
- mipMapNearestNearest: 3,
- mipMapLinearNearest: 4,
- mipMapNearestLinear: 5,
- mipMapLinearLinear: 6
-};
-
-spine.Atlas.TextureWrap = {
- mirroredRepeat: 0,
- clampToEdge: 1,
- repeat: 2
-};
-
-spine.AtlasPage = function () {};
-spine.AtlasPage.prototype = {
- name: null,
- format: null,
- minFilter: null,
- magFilter: null,
- uWrap: null,
- vWrap: null,
- rendererObject: null,
- width: 0,
- height: 0
-};
-
-spine.AtlasRegion = function () {};
-spine.AtlasRegion.prototype = {
- page: null,
- name: null,
- x: 0, y: 0,
- width: 0, height: 0,
- u: 0, v: 0, u2: 0, v2: 0,
- offsetX: 0, offsetY: 0,
- originalWidth: 0, originalHeight: 0,
- index: 0,
- rotate: false,
- splits: null,
- pads: null
-};
-
-spine.AtlasReader = function (text) {
- this.lines = text.split(/\r\n|\r|\n/);
-};
-spine.AtlasReader.prototype = {
- index: 0,
- trim: function (value) {
- return value.replace(/^\s+|\s+$/g, "");
- },
- readLine: function () {
- if (this.index >= this.lines.length) return null;
- return this.lines[this.index++];
- },
- readValue: function () {
- var line = this.readLine();
- var colon = line.indexOf(":");
- if (colon == -1) throw "Invalid line: " + line;
- return this.trim(line.substring(colon + 1));
- },
- /** Returns the number of tuple values read (1, 2 or 4). */
- readTuple: function (tuple) {
- var line = this.readLine();
- var colon = line.indexOf(":");
- if (colon == -1) throw "Invalid line: " + line;
- var i = 0, lastMatch = colon + 1;
- for (; i < 3; i++) {
- var comma = line.indexOf(",", lastMatch);
- if (comma == -1) break;
- tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch));
- lastMatch = comma + 1;
- }
- tuple[i] = this.trim(line.substring(lastMatch));
- return i + 1;
- }
-};
-
-spine.AtlasAttachmentLoader = function (atlas) {
- this.atlas = atlas;
-};
-spine.AtlasAttachmentLoader.prototype = {
- newRegionAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (region attachment: " + name + ")";
- var attachment = new spine.RegionAttachment(name);
- attachment.rendererObject = region;
- attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate);
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newMeshAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (mesh attachment: " + name + ")";
- var attachment = new spine.MeshAttachment(name);
- attachment.rendererObject = region;
- attachment.regionU = region.u;
- attachment.regionV = region.v;
- attachment.regionU2 = region.u2;
- attachment.regionV2 = region.v2;
- attachment.regionRotate = region.rotate;
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newSkinnedMeshAttachment: function (skin, name, path) {
- var region = this.atlas.findRegion(path);
- if (!region) throw "Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")";
- var attachment = new spine.SkinnedMeshAttachment(name);
- attachment.rendererObject = region;
- attachment.regionU = region.u;
- attachment.regionV = region.v;
- attachment.regionU2 = region.u2;
- attachment.regionV2 = region.v2;
- attachment.regionRotate = region.rotate;
- attachment.regionOffsetX = region.offsetX;
- attachment.regionOffsetY = region.offsetY;
- attachment.regionWidth = region.width;
- attachment.regionHeight = region.height;
- attachment.regionOriginalWidth = region.originalWidth;
- attachment.regionOriginalHeight = region.originalHeight;
- return attachment;
- },
- newBoundingBoxAttachment: function (skin, name) {
- return new spine.BoundingBoxAttachment(name);
- }
-};
-
-spine.SkeletonBounds = function () {
- this.polygonPool = [];
- this.polygons = [];
- this.boundingBoxes = [];
-};
-spine.SkeletonBounds.prototype = {
- minX: 0, minY: 0, maxX: 0, maxY: 0,
- update: function (skeleton, updateAabb) {
- var slots = skeleton.slots;
- var slotCount = slots.length;
- var x = skeleton.x, y = skeleton.y;
- var boundingBoxes = this.boundingBoxes;
- var polygonPool = this.polygonPool;
- var polygons = this.polygons;
-
- boundingBoxes.length = 0;
- for (var i = 0, n = polygons.length; i < n; i++)
- polygonPool.push(polygons[i]);
- polygons.length = 0;
-
- for (var i = 0; i < slotCount; i++) {
- var slot = slots[i];
- var boundingBox = slot.attachment;
- if (boundingBox.type != spine.AttachmentType.boundingbox) continue;
- boundingBoxes.push(boundingBox);
-
- var poolCount = polygonPool.length, polygon;
- if (poolCount > 0) {
- polygon = polygonPool[poolCount - 1];
- polygonPool.splice(poolCount - 1, 1);
- } else
- polygon = [];
- polygons.push(polygon);
-
- polygon.length = boundingBox.vertices.length;
- boundingBox.computeWorldVertices(x, y, slot.bone, polygon);
- }
-
- if (updateAabb) this.aabbCompute();
- },
- aabbCompute: function () {
- var polygons = this.polygons;
- var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = Number.MIN_VALUE, maxY = Number.MIN_VALUE;
- for (var i = 0, n = polygons.length; i < n; i++) {
- var vertices = polygons[i];
- for (var ii = 0, nn = vertices.length; ii < nn; ii += 2) {
- var x = vertices[ii];
- var y = vertices[ii + 1];
- minX = Math.min(minX, x);
- minY = Math.min(minY, y);
- maxX = Math.max(maxX, x);
- maxY = Math.max(maxY, y);
- }
- }
- this.minX = minX;
- this.minY = minY;
- this.maxX = maxX;
- this.maxY = maxY;
- },
- /** Returns true if the axis aligned bounding box contains the point. */
- aabbContainsPoint: function (x, y) {
- return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY;
- },
- /** Returns true if the axis aligned bounding box intersects the line segment. */
- aabbIntersectsSegment: function (x1, y1, x2, y2) {
- var minX = this.minX, minY = this.minY, maxX = this.maxX, maxY = this.maxY;
- if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
- return false;
- var m = (y2 - y1) / (x2 - x1);
- var y = m * (minX - x1) + y1;
- if (y > minY && y < maxY) return true;
- y = m * (maxX - x1) + y1;
- if (y > minY && y < maxY) return true;
- var x = (minY - y1) / m + x1;
- if (x > minX && x < maxX) return true;
- x = (maxY - y1) / m + x1;
- if (x > minX && x < maxX) return true;
- return false;
- },
- /** Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds. */
- aabbIntersectsSkeleton: function (bounds) {
- return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY;
- },
- /** Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
- * efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true. */
- containsPoint: function (x, y) {
- var polygons = this.polygons;
- for (var i = 0, n = polygons.length; i < n; i++)
- if (this.polygonContainsPoint(polygons[i], x, y)) return this.boundingBoxes[i];
- return null;
- },
- /** Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
- * more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true. */
- intersectsSegment: function (x1, y1, x2, y2) {
- var polygons = this.polygons;
- for (var i = 0, n = polygons.length; i < n; i++)
- if (polygons[i].intersectsSegment(x1, y1, x2, y2)) return this.boundingBoxes[i];
- return null;
- },
- /** Returns true if the polygon contains the point. */
- polygonContainsPoint: function (polygon, x, y) {
- var nn = polygon.length;
- var prevIndex = nn - 2;
- var inside = false;
- for (var ii = 0; ii < nn; ii += 2) {
- var vertexY = polygon[ii + 1];
- var prevY = polygon[prevIndex + 1];
- if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
- var vertexX = polygon[ii];
- if (vertexX + (y - vertexY) / (prevY - vertexY) * (polygon[prevIndex] - vertexX) < x) inside = !inside;
- }
- prevIndex = ii;
- }
- return inside;
- },
- /** Returns true if the polygon contains the line segment. */
- polygonIntersectsSegment: function (polygon, x1, y1, x2, y2) {
- var nn = polygon.length;
- var width12 = x1 - x2, height12 = y1 - y2;
- var det1 = x1 * y2 - y1 * x2;
- var x3 = polygon[nn - 2], y3 = polygon[nn - 1];
- for (var ii = 0; ii < nn; ii += 2) {
- var x4 = polygon[ii], y4 = polygon[ii + 1];
- var det2 = x3 * y4 - y3 * x4;
- var width34 = x3 - x4, height34 = y3 - y4;
- var det3 = width12 * height34 - height12 * width34;
- var x = (det1 * width34 - width12 * det2) / det3;
- if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
- var y = (det1 * height34 - height12 * det2) / det3;
- if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true;
- }
- x3 = x4;
- y3 = y4;
- }
- return false;
- },
- getPolygon: function (attachment) {
- var index = this.boundingBoxes.indexOf(attachment);
- return index == -1 ? null : this.polygons[index];
- },
- getWidth: function () {
- return this.maxX - this.minX;
- },
- getHeight: function () {
- return this.maxY - this.minY;
- }
-};
\ No newline at end of file
+// Spine runtime version 3.6.39
+
+var __extends = (this && this.__extends) || (function () {
+ var extendStatics = Object.setPrototypeOf ||
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+ return function (d, b) {
+ extendStatics(d, b);
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+ };
+})();
+var spine;
+(function (spine) {
+ var Animation = (function () {
+ function Animation(name, timelines, duration) {
+ if (name == null)
+ throw new Error("name cannot be null.");
+ if (timelines == null)
+ throw new Error("timelines cannot be null.");
+ this.name = name;
+ this.timelines = timelines;
+ this.duration = duration;
+ }
+ Animation.prototype.apply = function (skeleton, lastTime, time, loop, events, alpha, pose, direction) {
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ if (loop && this.duration != 0) {
+ time %= this.duration;
+ if (lastTime > 0)
+ lastTime %= this.duration;
+ }
+ var timelines = this.timelines;
+ for (var i = 0, n = timelines.length; i < n; i++)
+ timelines[i].apply(skeleton, lastTime, time, events, alpha, pose, direction);
+ };
+ Animation.binarySearch = function (values, target, step) {
+ if (step === void 0) { step = 1; }
+ var low = 0;
+ var high = values.length / step - 2;
+ if (high == 0)
+ return step;
+ var current = high >>> 1;
+ while (true) {
+ if (values[(current + 1) * step] <= target)
+ low = current + 1;
+ else
+ high = current;
+ if (low == high)
+ return (low + 1) * step;
+ current = (low + high) >>> 1;
+ }
+ };
+ Animation.linearSearch = function (values, target, step) {
+ for (var i = 0, last = values.length - step; i <= last; i += step)
+ if (values[i] > target)
+ return i;
+ return -1;
+ };
+ return Animation;
+ }());
+ spine.Animation = Animation;
+ var MixPose;
+ (function (MixPose) {
+ MixPose[MixPose["setup"] = 0] = "setup";
+ MixPose[MixPose["current"] = 1] = "current";
+ MixPose[MixPose["currentLayered"] = 2] = "currentLayered";
+ })(MixPose = spine.MixPose || (spine.MixPose = {}));
+ var MixDirection;
+ (function (MixDirection) {
+ MixDirection[MixDirection["in"] = 0] = "in";
+ MixDirection[MixDirection["out"] = 1] = "out";
+ })(MixDirection = spine.MixDirection || (spine.MixDirection = {}));
+ var TimelineType;
+ (function (TimelineType) {
+ TimelineType[TimelineType["rotate"] = 0] = "rotate";
+ TimelineType[TimelineType["translate"] = 1] = "translate";
+ TimelineType[TimelineType["scale"] = 2] = "scale";
+ TimelineType[TimelineType["shear"] = 3] = "shear";
+ TimelineType[TimelineType["attachment"] = 4] = "attachment";
+ TimelineType[TimelineType["color"] = 5] = "color";
+ TimelineType[TimelineType["deform"] = 6] = "deform";
+ TimelineType[TimelineType["event"] = 7] = "event";
+ TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder";
+ TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint";
+ TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint";
+ TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition";
+ TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing";
+ TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix";
+ TimelineType[TimelineType["twoColor"] = 14] = "twoColor";
+ })(TimelineType = spine.TimelineType || (spine.TimelineType = {}));
+ var CurveTimeline = (function () {
+ function CurveTimeline(frameCount) {
+ if (frameCount <= 0)
+ throw new Error("frameCount must be > 0: " + frameCount);
+ this.curves = spine.Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE);
+ }
+ CurveTimeline.prototype.getFrameCount = function () {
+ return this.curves.length / CurveTimeline.BEZIER_SIZE + 1;
+ };
+ CurveTimeline.prototype.setLinear = function (frameIndex) {
+ this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR;
+ };
+ CurveTimeline.prototype.setStepped = function (frameIndex) {
+ this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED;
+ };
+ CurveTimeline.prototype.getCurveType = function (frameIndex) {
+ var index = frameIndex * CurveTimeline.BEZIER_SIZE;
+ if (index == this.curves.length)
+ return CurveTimeline.LINEAR;
+ var type = this.curves[index];
+ if (type == CurveTimeline.LINEAR)
+ return CurveTimeline.LINEAR;
+ if (type == CurveTimeline.STEPPED)
+ return CurveTimeline.STEPPED;
+ return CurveTimeline.BEZIER;
+ };
+ CurveTimeline.prototype.setCurve = function (frameIndex, cx1, cy1, cx2, cy2) {
+ var tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03;
+ var dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006;
+ var ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy;
+ var dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667;
+ var i = frameIndex * CurveTimeline.BEZIER_SIZE;
+ var curves = this.curves;
+ curves[i++] = CurveTimeline.BEZIER;
+ var x = dfx, y = dfy;
+ for (var n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
+ curves[i] = x;
+ curves[i + 1] = y;
+ dfx += ddfx;
+ dfy += ddfy;
+ ddfx += dddfx;
+ ddfy += dddfy;
+ x += dfx;
+ y += dfy;
+ }
+ };
+ CurveTimeline.prototype.getCurvePercent = function (frameIndex, percent) {
+ percent = spine.MathUtils.clamp(percent, 0, 1);
+ var curves = this.curves;
+ var i = frameIndex * CurveTimeline.BEZIER_SIZE;
+ var type = curves[i];
+ if (type == CurveTimeline.LINEAR)
+ return percent;
+ if (type == CurveTimeline.STEPPED)
+ return 0;
+ i++;
+ var x = 0;
+ for (var start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) {
+ x = curves[i];
+ if (x >= percent) {
+ var prevX = void 0, prevY = void 0;
+ if (i == start) {
+ prevX = 0;
+ prevY = 0;
+ }
+ else {
+ prevX = curves[i - 2];
+ prevY = curves[i - 1];
+ }
+ return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
+ }
+ }
+ var y = curves[i - 1];
+ return y + (1 - y) * (percent - x) / (1 - x);
+ };
+ return CurveTimeline;
+ }());
+ CurveTimeline.LINEAR = 0;
+ CurveTimeline.STEPPED = 1;
+ CurveTimeline.BEZIER = 2;
+ CurveTimeline.BEZIER_SIZE = 10 * 2 - 1;
+ spine.CurveTimeline = CurveTimeline;
+ var RotateTimeline = (function (_super) {
+ __extends(RotateTimeline, _super);
+ function RotateTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount << 1);
+ return _this;
+ }
+ RotateTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.rotate << 24) + this.boneIndex;
+ };
+ RotateTimeline.prototype.setFrame = function (frameIndex, time, degrees) {
+ frameIndex <<= 1;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + RotateTimeline.ROTATION] = degrees;
+ };
+ RotateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.rotation = bone.data.rotation;
+ return;
+ case MixPose.current:
+ var r_1 = bone.data.rotation - bone.rotation;
+ r_1 -= (16384 - ((16384.499999999996 - r_1 / 360) | 0)) * 360;
+ bone.rotation += r_1 * alpha;
+ }
+ return;
+ }
+ if (time >= frames[frames.length - RotateTimeline.ENTRIES]) {
+ if (pose == MixPose.setup)
+ bone.rotation = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] * alpha;
+ else {
+ var r_2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION] - bone.rotation;
+ r_2 -= (16384 - ((16384.499999999996 - r_2 / 360) | 0)) * 360;
+ bone.rotation += r_2 * alpha;
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES);
+ var prevRotation = frames[frame + RotateTimeline.PREV_ROTATION];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
+ var r = frames[frame + RotateTimeline.ROTATION] - prevRotation;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ r = prevRotation + r * percent;
+ if (pose == MixPose.setup) {
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ bone.rotation = bone.data.rotation + r * alpha;
+ }
+ else {
+ r = bone.data.rotation + r - bone.rotation;
+ r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360;
+ bone.rotation += r * alpha;
+ }
+ };
+ return RotateTimeline;
+ }(CurveTimeline));
+ RotateTimeline.ENTRIES = 2;
+ RotateTimeline.PREV_TIME = -2;
+ RotateTimeline.PREV_ROTATION = -1;
+ RotateTimeline.ROTATION = 1;
+ spine.RotateTimeline = RotateTimeline;
+ var TranslateTimeline = (function (_super) {
+ __extends(TranslateTimeline, _super);
+ function TranslateTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES);
+ return _this;
+ }
+ TranslateTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.translate << 24) + this.boneIndex;
+ };
+ TranslateTimeline.prototype.setFrame = function (frameIndex, time, x, y) {
+ frameIndex *= TranslateTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TranslateTimeline.X] = x;
+ this.frames[frameIndex + TranslateTimeline.Y] = y;
+ };
+ TranslateTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.x = bone.data.x;
+ bone.y = bone.data.y;
+ return;
+ case MixPose.current:
+ bone.x += (bone.data.x - bone.x) * alpha;
+ bone.y += (bone.data.y - bone.y) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) {
+ x = frames[frames.length + TranslateTimeline.PREV_X];
+ y = frames[frames.length + TranslateTimeline.PREV_Y];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES);
+ x = frames[frame + TranslateTimeline.PREV_X];
+ y = frames[frame + TranslateTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime));
+ x += (frames[frame + TranslateTimeline.X] - x) * percent;
+ y += (frames[frame + TranslateTimeline.Y] - y) * percent;
+ }
+ if (pose == MixPose.setup) {
+ bone.x = bone.data.x + x * alpha;
+ bone.y = bone.data.y + y * alpha;
+ }
+ else {
+ bone.x += (bone.data.x + x - bone.x) * alpha;
+ bone.y += (bone.data.y + y - bone.y) * alpha;
+ }
+ };
+ return TranslateTimeline;
+ }(CurveTimeline));
+ TranslateTimeline.ENTRIES = 3;
+ TranslateTimeline.PREV_TIME = -3;
+ TranslateTimeline.PREV_X = -2;
+ TranslateTimeline.PREV_Y = -1;
+ TranslateTimeline.X = 1;
+ TranslateTimeline.Y = 2;
+ spine.TranslateTimeline = TranslateTimeline;
+ var ScaleTimeline = (function (_super) {
+ __extends(ScaleTimeline, _super);
+ function ScaleTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ ScaleTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.scale << 24) + this.boneIndex;
+ };
+ ScaleTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.scaleX = bone.data.scaleX;
+ bone.scaleY = bone.data.scaleY;
+ return;
+ case MixPose.current:
+ bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
+ bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) {
+ x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX;
+ y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY;
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES);
+ x = frames[frame + ScaleTimeline.PREV_X];
+ y = frames[frame + ScaleTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime));
+ x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX;
+ y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY;
+ }
+ if (alpha == 1) {
+ bone.scaleX = x;
+ bone.scaleY = y;
+ }
+ else {
+ var bx = 0, by = 0;
+ if (pose == MixPose.setup) {
+ bx = bone.data.scaleX;
+ by = bone.data.scaleY;
+ }
+ else {
+ bx = bone.scaleX;
+ by = bone.scaleY;
+ }
+ if (direction == MixDirection.out) {
+ x = Math.abs(x) * spine.MathUtils.signum(bx);
+ y = Math.abs(y) * spine.MathUtils.signum(by);
+ }
+ else {
+ bx = Math.abs(bx) * spine.MathUtils.signum(x);
+ by = Math.abs(by) * spine.MathUtils.signum(y);
+ }
+ bone.scaleX = bx + (x - bx) * alpha;
+ bone.scaleY = by + (y - by) * alpha;
+ }
+ };
+ return ScaleTimeline;
+ }(TranslateTimeline));
+ spine.ScaleTimeline = ScaleTimeline;
+ var ShearTimeline = (function (_super) {
+ __extends(ShearTimeline, _super);
+ function ShearTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ ShearTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.shear << 24) + this.boneIndex;
+ };
+ ShearTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var frames = this.frames;
+ var bone = skeleton.bones[this.boneIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ bone.shearX = bone.data.shearX;
+ bone.shearY = bone.data.shearY;
+ return;
+ case MixPose.current:
+ bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
+ }
+ return;
+ }
+ var x = 0, y = 0;
+ if (time >= frames[frames.length - ShearTimeline.ENTRIES]) {
+ x = frames[frames.length + ShearTimeline.PREV_X];
+ y = frames[frames.length + ShearTimeline.PREV_Y];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES);
+ x = frames[frame + ShearTimeline.PREV_X];
+ y = frames[frame + ShearTimeline.PREV_Y];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime));
+ x = x + (frames[frame + ShearTimeline.X] - x) * percent;
+ y = y + (frames[frame + ShearTimeline.Y] - y) * percent;
+ }
+ if (pose == MixPose.setup) {
+ bone.shearX = bone.data.shearX + x * alpha;
+ bone.shearY = bone.data.shearY + y * alpha;
+ }
+ else {
+ bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
+ bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
+ }
+ };
+ return ShearTimeline;
+ }(TranslateTimeline));
+ spine.ShearTimeline = ShearTimeline;
+ var ColorTimeline = (function (_super) {
+ __extends(ColorTimeline, _super);
+ function ColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES);
+ return _this;
+ }
+ ColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.color << 24) + this.slotIndex;
+ };
+ ColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a) {
+ frameIndex *= ColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + ColorTimeline.R] = r;
+ this.frames[frameIndex + ColorTimeline.G] = g;
+ this.frames[frameIndex + ColorTimeline.B] = b;
+ this.frames[frameIndex + ColorTimeline.A] = a;
+ };
+ ColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ return;
+ case MixPose.current:
+ var color = slot.color, setup = slot.data.color;
+ color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0;
+ if (time >= frames[frames.length - ColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + ColorTimeline.PREV_R];
+ g = frames[i + ColorTimeline.PREV_G];
+ b = frames[i + ColorTimeline.PREV_B];
+ a = frames[i + ColorTimeline.PREV_A];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, ColorTimeline.ENTRIES);
+ r = frames[frame + ColorTimeline.PREV_R];
+ g = frames[frame + ColorTimeline.PREV_G];
+ b = frames[frame + ColorTimeline.PREV_B];
+ a = frames[frame + ColorTimeline.PREV_A];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + ColorTimeline.R] - r) * percent;
+ g += (frames[frame + ColorTimeline.G] - g) * percent;
+ b += (frames[frame + ColorTimeline.B] - b) * percent;
+ a += (frames[frame + ColorTimeline.A] - a) * percent;
+ }
+ if (alpha == 1)
+ slot.color.set(r, g, b, a);
+ else {
+ var color = slot.color;
+ if (pose == MixPose.setup)
+ color.setFromColor(slot.data.color);
+ color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha);
+ }
+ };
+ return ColorTimeline;
+ }(CurveTimeline));
+ ColorTimeline.ENTRIES = 5;
+ ColorTimeline.PREV_TIME = -5;
+ ColorTimeline.PREV_R = -4;
+ ColorTimeline.PREV_G = -3;
+ ColorTimeline.PREV_B = -2;
+ ColorTimeline.PREV_A = -1;
+ ColorTimeline.R = 1;
+ ColorTimeline.G = 2;
+ ColorTimeline.B = 3;
+ ColorTimeline.A = 4;
+ spine.ColorTimeline = ColorTimeline;
+ var TwoColorTimeline = (function (_super) {
+ __extends(TwoColorTimeline, _super);
+ function TwoColorTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES);
+ return _this;
+ }
+ TwoColorTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.twoColor << 24) + this.slotIndex;
+ };
+ TwoColorTimeline.prototype.setFrame = function (frameIndex, time, r, g, b, a, r2, g2, b2) {
+ frameIndex *= TwoColorTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TwoColorTimeline.R] = r;
+ this.frames[frameIndex + TwoColorTimeline.G] = g;
+ this.frames[frameIndex + TwoColorTimeline.B] = b;
+ this.frames[frameIndex + TwoColorTimeline.A] = a;
+ this.frames[frameIndex + TwoColorTimeline.R2] = r2;
+ this.frames[frameIndex + TwoColorTimeline.G2] = g2;
+ this.frames[frameIndex + TwoColorTimeline.B2] = b2;
+ };
+ TwoColorTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var frames = this.frames;
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ slot.color.setFromColor(slot.data.color);
+ slot.darkColor.setFromColor(slot.data.darkColor);
+ return;
+ case MixPose.current:
+ var light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor;
+ light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha);
+ dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0);
+ }
+ return;
+ }
+ var r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
+ if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) {
+ var i = frames.length;
+ r = frames[i + TwoColorTimeline.PREV_R];
+ g = frames[i + TwoColorTimeline.PREV_G];
+ b = frames[i + TwoColorTimeline.PREV_B];
+ a = frames[i + TwoColorTimeline.PREV_A];
+ r2 = frames[i + TwoColorTimeline.PREV_R2];
+ g2 = frames[i + TwoColorTimeline.PREV_G2];
+ b2 = frames[i + TwoColorTimeline.PREV_B2];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES);
+ r = frames[frame + TwoColorTimeline.PREV_R];
+ g = frames[frame + TwoColorTimeline.PREV_G];
+ b = frames[frame + TwoColorTimeline.PREV_B];
+ a = frames[frame + TwoColorTimeline.PREV_A];
+ r2 = frames[frame + TwoColorTimeline.PREV_R2];
+ g2 = frames[frame + TwoColorTimeline.PREV_G2];
+ b2 = frames[frame + TwoColorTimeline.PREV_B2];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime));
+ r += (frames[frame + TwoColorTimeline.R] - r) * percent;
+ g += (frames[frame + TwoColorTimeline.G] - g) * percent;
+ b += (frames[frame + TwoColorTimeline.B] - b) * percent;
+ a += (frames[frame + TwoColorTimeline.A] - a) * percent;
+ r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent;
+ g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent;
+ b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent;
+ }
+ if (alpha == 1) {
+ slot.color.set(r, g, b, a);
+ slot.darkColor.set(r2, g2, b2, 1);
+ }
+ else {
+ var light = slot.color, dark = slot.darkColor;
+ if (pose == MixPose.setup) {
+ light.setFromColor(slot.data.color);
+ dark.setFromColor(slot.data.darkColor);
+ }
+ light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha);
+ dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0);
+ }
+ };
+ return TwoColorTimeline;
+ }(CurveTimeline));
+ TwoColorTimeline.ENTRIES = 8;
+ TwoColorTimeline.PREV_TIME = -8;
+ TwoColorTimeline.PREV_R = -7;
+ TwoColorTimeline.PREV_G = -6;
+ TwoColorTimeline.PREV_B = -5;
+ TwoColorTimeline.PREV_A = -4;
+ TwoColorTimeline.PREV_R2 = -3;
+ TwoColorTimeline.PREV_G2 = -2;
+ TwoColorTimeline.PREV_B2 = -1;
+ TwoColorTimeline.R = 1;
+ TwoColorTimeline.G = 2;
+ TwoColorTimeline.B = 3;
+ TwoColorTimeline.A = 4;
+ TwoColorTimeline.R2 = 5;
+ TwoColorTimeline.G2 = 6;
+ TwoColorTimeline.B2 = 7;
+ spine.TwoColorTimeline = TwoColorTimeline;
+ var AttachmentTimeline = (function () {
+ function AttachmentTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.attachmentNames = new Array(frameCount);
+ }
+ AttachmentTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.attachment << 24) + this.slotIndex;
+ };
+ AttachmentTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ AttachmentTimeline.prototype.setFrame = function (frameIndex, time, attachmentName) {
+ this.frames[frameIndex] = time;
+ this.attachmentNames[frameIndex] = attachmentName;
+ };
+ AttachmentTimeline.prototype.apply = function (skeleton, lastTime, time, events, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ if (direction == MixDirection.out && pose == MixPose.setup) {
+ var attachmentName_1 = slot.data.attachmentName;
+ slot.setAttachment(attachmentName_1 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_1));
+ return;
+ }
+ var frames = this.frames;
+ if (time < frames[0]) {
+ if (pose == MixPose.setup) {
+ var attachmentName_2 = slot.data.attachmentName;
+ slot.setAttachment(attachmentName_2 == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName_2));
+ }
+ return;
+ }
+ var frameIndex = 0;
+ if (time >= frames[frames.length - 1])
+ frameIndex = frames.length - 1;
+ else
+ frameIndex = Animation.binarySearch(frames, time, 1) - 1;
+ var attachmentName = this.attachmentNames[frameIndex];
+ skeleton.slots[this.slotIndex]
+ .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName));
+ };
+ return AttachmentTimeline;
+ }());
+ spine.AttachmentTimeline = AttachmentTimeline;
+ var zeros = null;
+ var DeformTimeline = (function (_super) {
+ __extends(DeformTimeline, _super);
+ function DeformTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount);
+ _this.frameVertices = new Array(frameCount);
+ if (zeros == null)
+ zeros = spine.Utils.newFloatArray(64);
+ return _this;
+ }
+ DeformTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex;
+ };
+ DeformTimeline.prototype.setFrame = function (frameIndex, time, vertices) {
+ this.frames[frameIndex] = time;
+ this.frameVertices[frameIndex] = vertices;
+ };
+ DeformTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var slot = skeleton.slots[this.slotIndex];
+ var slotAttachment = slot.getAttachment();
+ if (!(slotAttachment instanceof spine.VertexAttachment) || !slotAttachment.applyDeform(this.attachment))
+ return;
+ var verticesArray = slot.attachmentVertices;
+ var frameVertices = this.frameVertices;
+ var vertexCount = frameVertices[0].length;
+ var vertices = spine.Utils.setArraySize(verticesArray, vertexCount);
+ var frames = this.frames;
+ if (time < frames[0]) {
+ var vertexAttachment = slotAttachment;
+ switch (pose) {
+ case MixPose.setup:
+ var zeroVertices;
+ if (vertexAttachment.bones == null) {
+ zeroVertices = vertexAttachment.vertices;
+ }
+ else {
+ zeroVertices = zeros;
+ if (zeroVertices.length < vertexCount)
+ zeros = zeroVertices = spine.Utils.newFloatArray(vertexCount);
+ }
+ spine.Utils.arrayCopy(zeroVertices, 0, vertices, 0, vertexCount);
+ return;
+ case MixPose.current:
+ if (alpha == 1)
+ break;
+ if (vertexAttachment.bones == null) {
+ var setupVertices = vertexAttachment.vertices;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
+ }
+ else {
+ alpha = 1 - alpha;
+ for (var i = 0; i < vertexCount; i++)
+ vertices[i] *= alpha;
+ }
+ }
+ return;
+ }
+ if (time >= frames[frames.length - 1]) {
+ var lastVertices = frameVertices[frames.length - 1];
+ if (alpha == 1) {
+ spine.Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount);
+ }
+ else if (pose == MixPose.setup) {
+ var vertexAttachment = slotAttachment;
+ if (vertexAttachment.bones == null) {
+ var setupVertices_1 = vertexAttachment.vertices;
+ for (var i_1 = 0; i_1 < vertexCount; i_1++) {
+ var setup = setupVertices_1[i_1];
+ vertices[i_1] = setup + (lastVertices[i_1] - setup) * alpha;
+ }
+ }
+ else {
+ for (var i_2 = 0; i_2 < vertexCount; i_2++)
+ vertices[i_2] = lastVertices[i_2] * alpha;
+ }
+ }
+ else {
+ for (var i_3 = 0; i_3 < vertexCount; i_3++)
+ vertices[i_3] += (lastVertices[i_3] - vertices[i_3]) * alpha;
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time);
+ var prevVertices = frameVertices[frame - 1];
+ var nextVertices = frameVertices[frame];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime));
+ if (alpha == 1) {
+ for (var i_4 = 0; i_4 < vertexCount; i_4++) {
+ var prev = prevVertices[i_4];
+ vertices[i_4] = prev + (nextVertices[i_4] - prev) * percent;
+ }
+ }
+ else if (pose == MixPose.setup) {
+ var vertexAttachment = slotAttachment;
+ if (vertexAttachment.bones == null) {
+ var setupVertices_2 = vertexAttachment.vertices;
+ for (var i_5 = 0; i_5 < vertexCount; i_5++) {
+ var prev = prevVertices[i_5], setup = setupVertices_2[i_5];
+ vertices[i_5] = setup + (prev + (nextVertices[i_5] - prev) * percent - setup) * alpha;
+ }
+ }
+ else {
+ for (var i_6 = 0; i_6 < vertexCount; i_6++) {
+ var prev = prevVertices[i_6];
+ vertices[i_6] = (prev + (nextVertices[i_6] - prev) * percent) * alpha;
+ }
+ }
+ }
+ else {
+ for (var i_7 = 0; i_7 < vertexCount; i_7++) {
+ var prev = prevVertices[i_7];
+ vertices[i_7] += (prev + (nextVertices[i_7] - prev) * percent - vertices[i_7]) * alpha;
+ }
+ }
+ };
+ return DeformTimeline;
+ }(CurveTimeline));
+ spine.DeformTimeline = DeformTimeline;
+ var EventTimeline = (function () {
+ function EventTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.events = new Array(frameCount);
+ }
+ EventTimeline.prototype.getPropertyId = function () {
+ return TimelineType.event << 24;
+ };
+ EventTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ EventTimeline.prototype.setFrame = function (frameIndex, event) {
+ this.frames[frameIndex] = event.time;
+ this.events[frameIndex] = event;
+ };
+ EventTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ if (firedEvents == null)
+ return;
+ var frames = this.frames;
+ var frameCount = this.frames.length;
+ if (lastTime > time) {
+ this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, pose, direction);
+ lastTime = -1;
+ }
+ else if (lastTime >= frames[frameCount - 1])
+ return;
+ if (time < frames[0])
+ return;
+ var frame = 0;
+ if (lastTime < frames[0])
+ frame = 0;
+ else {
+ frame = Animation.binarySearch(frames, lastTime);
+ var frameTime = frames[frame];
+ while (frame > 0) {
+ if (frames[frame - 1] != frameTime)
+ break;
+ frame--;
+ }
+ }
+ for (; frame < frameCount && time >= frames[frame]; frame++)
+ firedEvents.push(this.events[frame]);
+ };
+ return EventTimeline;
+ }());
+ spine.EventTimeline = EventTimeline;
+ var DrawOrderTimeline = (function () {
+ function DrawOrderTimeline(frameCount) {
+ this.frames = spine.Utils.newFloatArray(frameCount);
+ this.drawOrders = new Array(frameCount);
+ }
+ DrawOrderTimeline.prototype.getPropertyId = function () {
+ return TimelineType.drawOrder << 24;
+ };
+ DrawOrderTimeline.prototype.getFrameCount = function () {
+ return this.frames.length;
+ };
+ DrawOrderTimeline.prototype.setFrame = function (frameIndex, time, drawOrder) {
+ this.frames[frameIndex] = time;
+ this.drawOrders[frameIndex] = drawOrder;
+ };
+ DrawOrderTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var drawOrder = skeleton.drawOrder;
+ var slots = skeleton.slots;
+ if (direction == MixDirection.out && pose == MixPose.setup) {
+ spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
+ return;
+ }
+ var frames = this.frames;
+ if (time < frames[0]) {
+ if (pose == MixPose.setup)
+ spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length);
+ return;
+ }
+ var frame = 0;
+ if (time >= frames[frames.length - 1])
+ frame = frames.length - 1;
+ else
+ frame = Animation.binarySearch(frames, time) - 1;
+ var drawOrderToSetupIndex = this.drawOrders[frame];
+ if (drawOrderToSetupIndex == null)
+ spine.Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length);
+ else {
+ for (var i = 0, n = drawOrderToSetupIndex.length; i < n; i++)
+ drawOrder[i] = slots[drawOrderToSetupIndex[i]];
+ }
+ };
+ return DrawOrderTimeline;
+ }());
+ spine.DrawOrderTimeline = DrawOrderTimeline;
+ var IkConstraintTimeline = (function (_super) {
+ __extends(IkConstraintTimeline, _super);
+ function IkConstraintTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES);
+ return _this;
+ }
+ IkConstraintTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex;
+ };
+ IkConstraintTimeline.prototype.setFrame = function (frameIndex, time, mix, bendDirection) {
+ frameIndex *= IkConstraintTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + IkConstraintTimeline.MIX] = mix;
+ this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection;
+ };
+ IkConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.ikConstraints[this.ikConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.mix = constraint.data.mix;
+ constraint.bendDirection = constraint.data.bendDirection;
+ return;
+ case MixPose.current:
+ constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
+ constraint.bendDirection = constraint.data.bendDirection;
+ }
+ return;
+ }
+ if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) {
+ if (pose == MixPose.setup) {
+ constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha;
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection
+ : frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ else {
+ constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha;
+ if (direction == MixDirection["in"])
+ constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ return;
+ }
+ var frame = Animation.binarySearch(frames, time, IkConstraintTimeline.ENTRIES);
+ var mix = frames[frame + IkConstraintTimeline.PREV_MIX];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime));
+ if (pose == MixPose.setup) {
+ constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha;
+ constraint.bendDirection = direction == MixDirection.out ? constraint.data.bendDirection : frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ else {
+ constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha;
+ if (direction == MixDirection["in"])
+ constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION];
+ }
+ };
+ return IkConstraintTimeline;
+ }(CurveTimeline));
+ IkConstraintTimeline.ENTRIES = 3;
+ IkConstraintTimeline.PREV_TIME = -3;
+ IkConstraintTimeline.PREV_MIX = -2;
+ IkConstraintTimeline.PREV_BEND_DIRECTION = -1;
+ IkConstraintTimeline.MIX = 1;
+ IkConstraintTimeline.BEND_DIRECTION = 2;
+ spine.IkConstraintTimeline = IkConstraintTimeline;
+ var TransformConstraintTimeline = (function (_super) {
+ __extends(TransformConstraintTimeline, _super);
+ function TransformConstraintTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES);
+ return _this;
+ }
+ TransformConstraintTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex;
+ };
+ TransformConstraintTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) {
+ frameIndex *= TransformConstraintTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix;
+ this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix;
+ this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix;
+ this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix;
+ };
+ TransformConstraintTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.transformConstraints[this.transformConstraintIndex];
+ if (time < frames[0]) {
+ var data = constraint.data;
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = data.rotateMix;
+ constraint.translateMix = data.translateMix;
+ constraint.scaleMix = data.scaleMix;
+ constraint.shearMix = data.shearMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
+ constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
+ constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
+ }
+ return;
+ }
+ var rotate = 0, translate = 0, scale = 0, shear = 0;
+ if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) {
+ var i = frames.length;
+ rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE];
+ translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE];
+ scale = frames[i + TransformConstraintTimeline.PREV_SCALE];
+ shear = frames[i + TransformConstraintTimeline.PREV_SHEAR];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES);
+ rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE];
+ translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE];
+ scale = frames[frame + TransformConstraintTimeline.PREV_SCALE];
+ shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime));
+ rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent;
+ translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent;
+ scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent;
+ shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent;
+ }
+ if (pose == MixPose.setup) {
+ var data = constraint.data;
+ constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
+ constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
+ constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha;
+ constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha;
+ }
+ else {
+ constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+ constraint.translateMix += (translate - constraint.translateMix) * alpha;
+ constraint.scaleMix += (scale - constraint.scaleMix) * alpha;
+ constraint.shearMix += (shear - constraint.shearMix) * alpha;
+ }
+ };
+ return TransformConstraintTimeline;
+ }(CurveTimeline));
+ TransformConstraintTimeline.ENTRIES = 5;
+ TransformConstraintTimeline.PREV_TIME = -5;
+ TransformConstraintTimeline.PREV_ROTATE = -4;
+ TransformConstraintTimeline.PREV_TRANSLATE = -3;
+ TransformConstraintTimeline.PREV_SCALE = -2;
+ TransformConstraintTimeline.PREV_SHEAR = -1;
+ TransformConstraintTimeline.ROTATE = 1;
+ TransformConstraintTimeline.TRANSLATE = 2;
+ TransformConstraintTimeline.SCALE = 3;
+ TransformConstraintTimeline.SHEAR = 4;
+ spine.TransformConstraintTimeline = TransformConstraintTimeline;
+ var PathConstraintPositionTimeline = (function (_super) {
+ __extends(PathConstraintPositionTimeline, _super);
+ function PathConstraintPositionTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES);
+ return _this;
+ }
+ PathConstraintPositionTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintPositionTimeline.prototype.setFrame = function (frameIndex, time, value) {
+ frameIndex *= PathConstraintPositionTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value;
+ };
+ PathConstraintPositionTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.position = constraint.data.position;
+ return;
+ case MixPose.current:
+ constraint.position += (constraint.data.position - constraint.position) * alpha;
+ }
+ return;
+ }
+ var position = 0;
+ if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES])
+ position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE];
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES);
+ position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime));
+ position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent;
+ }
+ if (pose == MixPose.setup)
+ constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
+ else
+ constraint.position += (position - constraint.position) * alpha;
+ };
+ return PathConstraintPositionTimeline;
+ }(CurveTimeline));
+ PathConstraintPositionTimeline.ENTRIES = 2;
+ PathConstraintPositionTimeline.PREV_TIME = -2;
+ PathConstraintPositionTimeline.PREV_VALUE = -1;
+ PathConstraintPositionTimeline.VALUE = 1;
+ spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline;
+ var PathConstraintSpacingTimeline = (function (_super) {
+ __extends(PathConstraintSpacingTimeline, _super);
+ function PathConstraintSpacingTimeline(frameCount) {
+ return _super.call(this, frameCount) || this;
+ }
+ PathConstraintSpacingTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintSpacingTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.spacing = constraint.data.spacing;
+ return;
+ case MixPose.current:
+ constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
+ }
+ return;
+ }
+ var spacing = 0;
+ if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES])
+ spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE];
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES);
+ spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime));
+ spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent;
+ }
+ if (pose == MixPose.setup)
+ constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
+ else
+ constraint.spacing += (spacing - constraint.spacing) * alpha;
+ };
+ return PathConstraintSpacingTimeline;
+ }(PathConstraintPositionTimeline));
+ spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline;
+ var PathConstraintMixTimeline = (function (_super) {
+ __extends(PathConstraintMixTimeline, _super);
+ function PathConstraintMixTimeline(frameCount) {
+ var _this = _super.call(this, frameCount) || this;
+ _this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES);
+ return _this;
+ }
+ PathConstraintMixTimeline.prototype.getPropertyId = function () {
+ return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex;
+ };
+ PathConstraintMixTimeline.prototype.setFrame = function (frameIndex, time, rotateMix, translateMix) {
+ frameIndex *= PathConstraintMixTimeline.ENTRIES;
+ this.frames[frameIndex] = time;
+ this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix;
+ this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix;
+ };
+ PathConstraintMixTimeline.prototype.apply = function (skeleton, lastTime, time, firedEvents, alpha, pose, direction) {
+ var frames = this.frames;
+ var constraint = skeleton.pathConstraints[this.pathConstraintIndex];
+ if (time < frames[0]) {
+ switch (pose) {
+ case MixPose.setup:
+ constraint.rotateMix = constraint.data.rotateMix;
+ constraint.translateMix = constraint.data.translateMix;
+ return;
+ case MixPose.current:
+ constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
+ constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
+ }
+ return;
+ }
+ var rotate = 0, translate = 0;
+ if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) {
+ rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE];
+ translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE];
+ }
+ else {
+ var frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES);
+ rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE];
+ translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE];
+ var frameTime = frames[frame];
+ var percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime));
+ rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent;
+ translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent;
+ }
+ if (pose == MixPose.setup) {
+ constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
+ constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
+ }
+ else {
+ constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
+ constraint.translateMix += (translate - constraint.translateMix) * alpha;
+ }
+ };
+ return PathConstraintMixTimeline;
+ }(CurveTimeline));
+ PathConstraintMixTimeline.ENTRIES = 3;
+ PathConstraintMixTimeline.PREV_TIME = -3;
+ PathConstraintMixTimeline.PREV_ROTATE = -2;
+ PathConstraintMixTimeline.PREV_TRANSLATE = -1;
+ PathConstraintMixTimeline.ROTATE = 1;
+ PathConstraintMixTimeline.TRANSLATE = 2;
+ spine.PathConstraintMixTimeline = PathConstraintMixTimeline;
+})(spine || (spine = {}));
+var spine;
+(function (spine) {
+ var AnimationState = (function () {
+ function AnimationState(data) {
+ this.tracks = new Array();
+ this.events = new Array();
+ this.listeners = new Array();
+ this.queue = new EventQueue(this);
+ this.propertyIDs = new spine.IntSet();
+ this.mixingTo = new Array();
+ this.animationsChanged = false;
+ this.timeScale = 1;
+ this.trackEntryPool = new spine.Pool(function () { return new TrackEntry(); });
+ this.data = data;
+ }
+ AnimationState.prototype.update = function (delta) {
+ delta *= this.timeScale;
+ var tracks = this.tracks;
+ for (var i = 0, n = tracks.length; i < n; i++) {
+ var current = tracks[i];
+ if (current == null)
+ continue;
+ current.animationLast = current.nextAnimationLast;
+ current.trackLast = current.nextTrackLast;
+ var currentDelta = delta * current.timeScale;
+ if (current.delay > 0) {
+ current.delay -= currentDelta;
+ if (current.delay > 0)
+ continue;
+ currentDelta = -current.delay;
+ current.delay = 0;
+ }
+ var next = current.next;
+ if (next != null) {
+ var nextTime = current.trackLast - next.delay;
+ if (nextTime >= 0) {
+ next.delay = 0;
+ next.trackTime = nextTime + delta * next.timeScale;
+ current.trackTime += currentDelta;
+ this.setCurrent(i, next, true);
+ while (next.mixingFrom != null) {
+ next.mixTime += currentDelta;
+ next = next.mixingFrom;
+ }
+ continue;
+ }
+ }
+ else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) {
+ tracks[i] = null;
+ this.queue.end(current);
+ this.disposeNext(current);
+ continue;
+ }
+ if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) {
+ var from = current.mixingFrom;
+ current.mixingFrom = null;
+ while (from != null) {
+ this.queue.end(from);
+ from = from.mixingFrom;
+ }
+ }
+ current.trackTime += currentDelta;
+ }
+ this.queue.drain();
+ };
+ AnimationState.prototype.updateMixingFrom = function (to, delta) {
+ var from = to.mixingFrom;
+ if (from == null)
+ return true;
+ var finished = this.updateMixingFrom(from, delta);
+ if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) {
+ if (from.totalAlpha == 0 || to.mixDuration == 0) {
+ to.mixingFrom = from.mixingFrom;
+ to.interruptAlpha = from.interruptAlpha;
+ this.queue.end(from);
+ }
+ return finished;
+ }
+ from.animationLast = from.nextAnimationLast;
+ from.trackLast = from.nextTrackLast;
+ from.trackTime += delta * from.timeScale;
+ to.mixTime += delta * to.timeScale;
+ return false;
+ };
+ AnimationState.prototype.apply = function (skeleton) {
+ if (skeleton == null)
+ throw new Error("skeleton cannot be null.");
+ if (this.animationsChanged)
+ this._animationsChanged();
+ var events = this.events;
+ var tracks = this.tracks;
+ var applied = false;
+ for (var i = 0, n = tracks.length; i < n; i++) {
+ var current = tracks[i];
+ if (current == null || current.delay > 0)
+ continue;
+ applied = true;
+ var currentPose = i == 0 ? spine.MixPose.current : spine.MixPose.currentLayered;
+ var mix = current.alpha;
+ if (current.mixingFrom != null)
+ mix *= this.applyMixingFrom(current, skeleton, currentPose);
+ else if (current.trackTime >= current.trackEnd && current.next == null)
+ mix = 0;
+ var animationLast = current.animationLast, animationTime = current.getAnimationTime();
+ var timelineCount = current.animation.timelines.length;
+ var timelines = current.animation.timelines;
+ if (mix == 1) {
+ for (var ii = 0; ii < timelineCount; ii++)
+ timelines[ii].apply(skeleton, animationLast, animationTime, events, 1, spine.MixPose.setup, spine.MixDirection["in"]);
+ }
+ else {
+ var timelineData = current.timelineData;
+ var firstFrame = current.timelinesRotation.length == 0;
+ if (firstFrame)
+ spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null);
+ var timelinesRotation = current.timelinesRotation;
+ for (var ii = 0; ii < timelineCount; ii++) {
+ var timeline = timelines[ii];
+ var pose = timelineData[ii] >= AnimationState.FIRST ? spine.MixPose.setup : currentPose;
+ if (timeline instanceof spine.RotateTimeline) {
+ this.applyRotateTimeline(timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
+ }
+ else
+ timeline.apply(skeleton, animationLast, animationTime, events, mix, pose, spine.MixDirection["in"]);
+ }
+ }
+ this.queueEvents(current, animationTime);
+ events.length = 0;
+ current.nextAnimationLast = animationTime;
+ current.nextTrackLast = current.trackTime;
+ }
+ this.queue.drain();
+ return applied;
+ };
+ AnimationState.prototype.applyMixingFrom = function (to, skeleton, currentPose) {
+ var from = to.mixingFrom;
+ if (from.mixingFrom != null)
+ this.applyMixingFrom(from, skeleton, currentPose);
+ var mix = 0;
+ if (to.mixDuration == 0)
+ mix = 1;
+ else {
+ mix = to.mixTime / to.mixDuration;
+ if (mix > 1)
+ mix = 1;
+ }
+ var events = mix < from.eventThreshold ? this.events : null;
+ var attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
+ var animationLast = from.animationLast, animationTime = from.getAnimationTime();
+ var timelineCount = from.animation.timelines.length;
+ var timelines = from.animation.timelines;
+ var timelineData = from.timelineData;
+ var timelineDipMix = from.timelineDipMix;
+ var firstFrame = from.timelinesRotation.length == 0;
+ if (firstFrame)
+ spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null);
+ var timelinesRotation = from.timelinesRotation;
+ var pose;
+ var alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha = 0;
+ from.totalAlpha = 0;
+ for (var i = 0; i < timelineCount; i++) {
+ var timeline = timelines[i];
+ switch (timelineData[i]) {
+ case AnimationState.SUBSEQUENT:
+ if (!attachments && timeline instanceof spine.AttachmentTimeline)
+ continue;
+ if (!drawOrder && timeline instanceof spine.DrawOrderTimeline)
+ continue;
+ pose = currentPose;
+ alpha = alphaMix;
+ break;
+ case AnimationState.FIRST:
+ pose = spine.MixPose.setup;
+ alpha = alphaMix;
+ break;
+ case AnimationState.DIP:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ break;
+ default:
+ pose = spine.MixPose.setup;
+ alpha = alphaDip;
+ var dipMix = timelineDipMix[i];
+ alpha *= Math.max(0, 1 - dipMix.mixTime / dipMix.mixDuration);
+ break;
+ }
+ from.totalAlpha += alpha;
+ if (timeline instanceof spine.RotateTimeline)
+ this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame);
+ else {
+ timeline.apply(skeleton, animationLast, animationTime, events, alpha, pose, spine.MixDirection.out);
+ }
+ }
+ if (to.mixDuration > 0)
+ this.queueEvents(from, animationTime);
+ this.events.length = 0;
+ from.nextAnimationLast = animationTime;
+ from.nextTrackLast = from.trackTime;
+ return mix;
+ };
+ AnimationState.prototype.applyRotateTimeline = function (timeline, skeleton, time, alpha, pose, timelinesRotation, i, firstFrame) {
+ if (firstFrame)
+ timelinesRotation[i] = 0;
+ if (alpha == 1) {
+ timeline.apply(skeleton, 0, time, null, 1, pose, spine.MixDirection["in"]);
+ return;
+ }
+ var rotateTimeline = timeline;
+ var frames = rotateTimeline.frames;
+ var bone = skeleton.bones[rotateTimeline.boneIndex];
+ if (time < frames[0]) {
+ if (pose == spine.MixPose.setup)
+ bone.rotation = bone.data.rotation;
+ return;
+ }
+ var r2 = 0;
+ if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES])
+ r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION];
+ else {
+ var frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES);
+ var prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION];
+ var frameTime = frames[frame];
+ var percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime));
+ r2 = frames[frame + spine.RotateTimeline.ROTATION] - prevRotation;
+ r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
+ r2 = prevRotation + r2 * percent + bone.data.rotation;
+ r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360;
+ }
+ var r1 = pose == spine.MixPose.setup ? bone.data.rotation : bone.rotation;
+ var total = 0, diff = r2 - r1;
+ if (diff == 0) {
+ total = timelinesRotation[i];
+ }
+ else {
+ diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360;
+ var lastTotal = 0, lastDiff = 0;
+ if (firstFrame) {
+ lastTotal = 0;
+ lastDiff = diff;
+ }
+ else {
+ lastTotal = timelinesRotation[i];
+ lastDiff = timelinesRotation[i + 1];
+ }
+ var current = diff > 0, dir = lastTotal >= 0;
+ if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) {
+ if (Math.abs(lastTotal) > 180)
+ lastTotal += 360 * spine.MathUtils.signum(lastTotal);
+ dir = current;
+ }
+ total = diff + lastTotal - lastTotal % 360;
+ if (dir != current)
+ total += 360 * spine.MathUtils.signum(lastTotal);
+ timelinesRotation[i] = total;
+ }
+ timelinesRotation[i + 1] = diff;
+ r1 += total * alpha;
+ bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360;
+ };
+ AnimationState.prototype.queueEvents = function (entry, animationTime) {
+ var animationStart = entry.animationStart, animationEnd = entry.animationEnd;
+ var duration = animationEnd - animationStart;
+ var trackLastWrapped = entry.trackLast % duration;
+ var events = this.events;
+ var i = 0, n = events.length;
+ for (; i < n; i++) {
+ var event_1 = events[i];
+ if (event_1.time < trackLastWrapped)
+ break;
+ if (event_1.time > animationEnd)
+ continue;
+ this.queue.event(entry, event_1);
+ }
+ if (entry.loop ? (trackLastWrapped > entry.trackTime % duration)
+ : (animationTime >= animationEnd && entry.animationLast < animationEnd)) {
+ this.queue.complete(entry);
+ }
+ for (; i < n; i++) {
+ var event_2 = events[i];
+ if (event_2.time < animationStart)
+ continue;
+ this.queue.event(entry, events[i]);
+ }
+ };
+ AnimationState.prototype.clearTracks = function () {
+ var oldDrainDisabled = this.queue.drainDisabled;
+ this.queue.drainDisabled = true;
+ for (var i = 0, n = this.tracks.length; i < n; i++)
+ this.clearTrack(i);
+ this.tracks.length = 0;
+ this.queue.drainDisabled = oldDrainDisabled;
+ this.queue.drain();
+ };
+ AnimationState.prototype.clearTrack = function (trackIndex) {
+ if (trackIndex >= this.tracks.length)
+ return;
+ var current = this.tracks[trackIndex];
+ if (current == null)
+ return;
+ this.queue.end(current);
+ this.disposeNext(current);
+ var entry = current;
+ while (true) {
+ var from = entry.mixingFrom;
+ if (from == null)
+ break;
+ this.queue.end(from);
+ entry.mixingFrom = null;
+ entry = from;
+ }
+ this.tracks[current.trackIndex] = null;
+ this.queue.drain();
+ };
+ AnimationState.prototype.setCurrent = function (index, current, interrupt) {
+ var from = this.expandToIndex(index);
+ this.tracks[index] = current;
+ if (from != null) {
+ if (interrupt)
+ this.queue.interrupt(from);
+ current.mixingFrom = from;
+ current.mixTime = 0;
+ if (from.mixingFrom != null && from.mixDuration > 0)
+ current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
+ from.timelinesRotation.length = 0;
+ }
+ this.queue.start(current);
+ };
+ AnimationState.prototype.setAnimation = function (trackIndex, animationName, loop) {
+ var animation = this.data.skeletonData.findAnimation(animationName);
+ if (animation == null)
+ throw new Error("Animation not found: " + animationName);
+ return this.setAnimationWith(trackIndex, animation, loop);
+ };
+ AnimationState.prototype.setAnimationWith = function (trackIndex, animation, loop) {
+ if (animation == null)
+ throw new Error("animation cannot be null.");
+ var interrupt = true;
+ var current = this.expandToIndex(trackIndex);
+ if (current != null) {
+ if (current.nextTrackLast == -1) {
+ this.tracks[trackIndex] = current.mixingFrom;
+ this.queue.interrupt(current);
+ this.queue.end(current);
+ this.disposeNext(current);
+ current = current.mixingFrom;
+ interrupt = false;
+ }
+ else
+ this.disposeNext(current);
+ }
+ var entry = this.trackEntry(trackIndex, animation, loop, current);
+ this.setCurrent(trackIndex, entry, interrupt);
+ this.queue.drain();
+ return entry;
+ };
+ AnimationState.prototype.addAnimation = function (trackIndex, animationName, loop, delay) {
+ var animation = this.data.skeletonData.findAnimation(animationName);
+ if (animation == null)
+ throw new Error("Animation not found: " + animationName);
+ return this.addAnimationWith(trackIndex, animation, loop, delay);
+ };
+ AnimationState.prototype.addAnimationWith = function (trackIndex, animation, loop, delay) {
+ if (animation == null)
+ throw new Error("animation cannot be null.");
+ var last = this.expandToIndex(trackIndex);
+ if (last != null) {
+ while (last.next != null)
+ last = last.next;
+ }
+ var entry = this.trackEntry(trackIndex, animation, loop, last);
+ if (last == null) {
+ this.setCurrent(trackIndex, entry, true);
+ this.queue.drain();
+ }
+ else {
+ last.next = entry;
+ if (delay <= 0) {
+ var duration = last.animationEnd - last.animationStart;
+ if (duration != 0)
+ delay += duration * (1 + ((last.trackTime / duration) | 0)) - this.data.getMix(last.animation, animation);
+ else
+ delay = 0;
+ }
+ }
+ entry.delay = delay;
+ return entry;
+ };
+ AnimationState.prototype.setEmptyAnimation = function (trackIndex, mixDuration) {
+ var entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false);
+ entry.mixDuration = mixDuration;
+ entry.trackEnd = mixDuration;
+ return entry;
+ };
+ AnimationState.prototype.addEmptyAnimation = function (trackIndex, mixDuration, delay) {
+ if (delay <= 0)
+ delay -= mixDuration;
+ var entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay);
+ entry.mixDuration = mixDuration;
+ entry.trackEnd = mixDuration;
+ return entry;
+ };
+ AnimationState.prototype.setEmptyAnimations = function (mixDuration) {
+ var oldDrainDisabled = this.queue.drainDisabled;
+ this.queue.drainDisabled = true;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
+ var current = this.tracks[i];
+ if (current != null)
+ this.setEmptyAnimation(current.trackIndex, mixDuration);
+ }
+ this.queue.drainDisabled = oldDrainDisabled;
+ this.queue.drain();
+ };
+ AnimationState.prototype.expandToIndex = function (index) {
+ if (index < this.tracks.length)
+ return this.tracks[index];
+ spine.Utils.ensureArrayCapacity(this.tracks, index - this.tracks.length + 1, null);
+ this.tracks.length = index + 1;
+ return null;
+ };
+ AnimationState.prototype.trackEntry = function (trackIndex, animation, loop, last) {
+ var entry = this.trackEntryPool.obtain();
+ entry.trackIndex = trackIndex;
+ entry.animation = animation;
+ entry.loop = loop;
+ entry.eventThreshold = 0;
+ entry.attachmentThreshold = 0;
+ entry.drawOrderThreshold = 0;
+ entry.animationStart = 0;
+ entry.animationEnd = animation.duration;
+ entry.animationLast = -1;
+ entry.nextAnimationLast = -1;
+ entry.delay = 0;
+ entry.trackTime = 0;
+ entry.trackLast = -1;
+ entry.nextTrackLast = -1;
+ entry.trackEnd = Number.MAX_VALUE;
+ entry.timeScale = 1;
+ entry.alpha = 1;
+ entry.interruptAlpha = 1;
+ entry.mixTime = 0;
+ entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation);
+ return entry;
+ };
+ AnimationState.prototype.disposeNext = function (entry) {
+ var next = entry.next;
+ while (next != null) {
+ this.queue.dispose(next);
+ next = next.next;
+ }
+ entry.next = null;
+ };
+ AnimationState.prototype._animationsChanged = function () {
+ this.animationsChanged = false;
+ var propertyIDs = this.propertyIDs;
+ propertyIDs.clear();
+ var mixingTo = this.mixingTo;
+ for (var i = 0, n = this.tracks.length; i < n; i++) {
+ var entry = this.tracks[i];
+ if (entry != null)
+ entry.setTimelineData(null, mixingTo, propertyIDs);
+ }
+ };
+ AnimationState.prototype.getCurrent = function (trackIndex) {
+ if (trackIndex >= this.tracks.length)
+ return null;
+ return this.tracks[trackIndex];
+ };
+ AnimationState.prototype.addListener = function (listener) {
+ if (listener == null)
+ throw new Error("listener cannot be null.");
+ this.listeners.push(listener);
+ };
+ AnimationState.prototype.removeListener = function (listener) {
+ var index = this.listeners.indexOf(listener);
+ if (index >= 0)
+ this.listeners.splice(index, 1);
+ };
+ AnimationState.prototype.clearListeners = function () {
+ this.listeners.length = 0;
+ };
+ AnimationState.prototype.clearListenerNotifications = function () {
+ this.queue.clear();
+ };
+ return AnimationState;
+ }());
+ AnimationState.emptyAnimation = new spine.Animation("