diff --git a/.gitignore b/.gitignore index 34d99e1..d5fd3c1 100755 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ node_modules/ .DS_Store lab/audio/ lab/filter/ -static/items/rube/*-backups -build/ +static/items/rube/*-backups \ No newline at end of file diff --git a/README.md b/README.md index 956e9b6..cae17cf 100755 --- a/README.md +++ b/README.md @@ -2,10 +2,8 @@ chuck.js ======== Physical JavaScript Action Browser Multiplayer Game - it will be awesome! - - - - + +[![Foo](http://25.media.tumblr.com/8249dcd3bdb176686421d1914937db1c/tumblr_mzc1ejGxNC1ry8awho1_400.png)](http://chuck-game.tumblr.com/ "Screenshot of chuck.js - click to visit our development blog!") Follow the development at http://chuck-game.tumblr.com/ diff --git a/app/Bootstrap/HttpServer.js b/app/Bootstrap/HttpServer.js index a1293b2..e74a46a 100755 --- a/app/Bootstrap/HttpServer.js +++ b/app/Bootstrap/HttpServer.js @@ -1,74 +1,92 @@ define([ - 'express', - 'http', - 'path', - 'Server/Api', - 'fs' + 'http', + 'node-static', + 'Server/Api' ], -function (express, http, path, Api, fs) { - - "use strict"; +function (http, nodeStatic, Api) { function HttpServer (options, coordinator) { options.port = options.port || 1234; + options.caching = typeof options.caching != 'undefined' ? options.caching : 3600; options.rootDirectory = options.rootDirectory || './'; + this.server = null; this.api = new Api(coordinator); - this.app = express(); - this.server = http.createServer(this.app); + this.init(options); } HttpServer.prototype.init = function (options) { var self = this; - var app = this.app; - // Serve static files - app.use('/static', express.static(path.join(options.rootDirectory, 'static'))); - app.use('/app', express.static(path.join(options.rootDirectory, 'app'))); + var fileServer = new nodeStatic.Server(options.rootDirectory, { cache: options.caching }); - // Serve index.html at root - app.get('/', function(req, res) { - res.sendFile(path.resolve(options.rootDirectory, 'static/html/index.html')); - }); + this.server = http.createServer( + function (req, res) { + + var fullBody = ''; + req.addListener('data', function(chunk) { // doesn't work on Jeenas computer without this + fullBody += chunk.toString(); + }); - // Serve client.js and minified version - app.get('/client.js', function(req, res) { - if (process.env.NODE_ENV === 'production' && fs.existsSync(path.resolve(options.rootDirectory, 'build/client.min.js'))) { - res.sendFile(path.resolve(options.rootDirectory, 'build/client.min.js')); - } else { - res.sendFile(path.resolve(options.rootDirectory, 'client.js')); + req.addListener('error', function(err) { + console.log(''); + }); + + + req.addListener('end', function () { + + switch(true) { + case req.url == '/': + fileServer.serveFile('./static/html/index.html', 200, {}, req, res); + console.checkpoint('HTTP Server serves index'); + break; + + case req.url == '/game.html': + fileServer.serveFile('./static/html/game.html', 200, {}, req, res); + console.checkpoint('HTTP Server serves game'); + break; + + case req.url == '/client.js': + fileServer.serveFile('./client.js', 200, {}, req, res); + break; + + case req.url == '/require.js': + fileServer.serveFile('./node_modules/requirejs/require.js', 200, {}, req, res); + break; + + case req.url == '/screenfull.js': + fileServer.serveFile('./node_modules/screenfull/dist/screenfull.js', 200, {}, req, res); + break; + + case req.url == '/api': + self.api.handleCall(fullBody); + var status = self.api.isError ? 400 : 200; + res.writeHead(status, {"Content-Type": self.api.getContentType()}); + res.end(self.api.getOutput()); + self.api.isError = false; + break; + + case new RegExp(/^\/app/).test(req.url): + fileServer.serve(req, res, function () { + self.handleFileError(res) + }); + break; + + case new RegExp(/^\/static/).test(req.url): + fileServer.serve(req, res, function () { + self.handleFileError(res) + }); + break; + + default: + self.handleFileError(res); + break; + } + }); } - }); - app.get('/client.min.js', function(req, res) { - res.sendFile(path.resolve(options.rootDirectory, 'build/client.min.js')); - }); - - // Serve require.js, screenfull.js, chart.js from node_modules - app.get('/require.js', function(req, res) { - res.sendFile(path.resolve(options.rootDirectory, 'node_modules/requirejs/require.js')); - }); - app.get('/screenfull.js', function(req, res) { - res.sendFile(path.resolve(options.rootDirectory, 'static/vendor/screenfull.js')); - }); - app.get('/chart.js', function(req, res) { - // Chart.js v4 uses 'dist/chart.umd.js' - res.sendFile(path.resolve(options.rootDirectory, 'node_modules/chart.js/dist/chart.umd.js')); - }); - - // API endpoint - app.post('/api', express.text({type: '*/*'}), function(req, res) { - self.api.handleCall(req.body); - var status = self.api.isError ? 400 : 200; - res.status(status).type(self.api.getContentType()).send(self.api.getOutput()); - self.api.isError = false; - }); - - // 404 handler - app.use(function(req, res) { - res.status(404).send('

404 not ... found

'); - }); + ); this.server.once('error', function(err) { if(err.code == 'EADDRINUSE') { @@ -79,6 +97,7 @@ function (express, http, path, Api, fs) { }); this.server.listen(options.port); + console.checkpoint('start HTTP server'); } @@ -86,5 +105,10 @@ function (express, http, path, Api, fs) { return this.server; } + HttpServer.prototype.handleFileError = function (res) { + res.writeHead(404, {'Content-Type': 'text/html'}); + res.end('

404 not ... found

'); + } + return HttpServer; }); \ No newline at end of file diff --git a/app/Bootstrap/Socket.js b/app/Bootstrap/Socket.js index c9a652e..460ac73 100755 --- a/app/Bootstrap/Socket.js +++ b/app/Bootstrap/Socket.js @@ -4,23 +4,29 @@ define([ function (io) { - "use strict"; - function Socket (server, options, coordinator) { + options.logLevel = typeof options.logLevel != 'undefined' + ? options.logLevel + : 0; + this.coordinator = coordinator; - this.io = io(server, { - // No more 'log level' or 'transports' in v4 - // Add any v4-compatible options here if needed - }); + this.socket = io.listen(server); + this.init(options); } Socket.prototype.init = function (options) { + var self = this; - this.io.on('connection', function (socket) { - console.checkpoint('socket receiving connection'); - self.onConnection(socket); + this.socket.configure('development', function () { + this.set('log level', options.logLevel); }); + + this.socket.on('connection', function (user) { + console.checkpoint('socket receiving connection'); + self.onConnection(user); + }); + console.checkpoint('start Socket Listener'); } diff --git a/app/Game/Asset/RubeDoll.json b/app/Game/Asset/RubeDoll.json deleted file mode 100644 index 0ea7dc3..0000000 --- a/app/Game/Asset/RubeDoll.json +++ /dev/null @@ -1,783 +0,0 @@ -{ - "allowSleep" : true, - "autoClearForces" : true, - "body" : - [ - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.04692989960312843, - 0.04692989960312843, - -0.04693000018596649, - -0.04693000018596649 - ], - "y" : - [ - -0.1895969957113266, - 0.1895969957113266, - 0.1895969957113266, - -0.1895969957113266 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0004525936674326658, - "massData-center" : - { - "x" : -5.029141902923584e-08, - "y" : 0 - }, - "massData-mass" : 0.03559110686182976, - "name" : "upperLeftArm", - "position" : - { - "x" : -0.1165359988808632, - "y" : 0.9012569785118103 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture2", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.1366278976202011, - 0.1366278976202011, - -0.1360991001129150, - -0.1360991001129150 - ], - "y" : - [ - -0.3788780868053436, - 0.3830279111862183, - 0.3830279111862183, - -0.3788780868053436 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.01134084537625313, - "massData-center" : - { - "x" : 0.0002643987536430359, - "y" : 0.002074912190437317 - }, - "massData-mass" : 0.2077923566102982, - "name" : "chest", - "position" : - { - "x" : 0.0007875636219978333, - "y" : 0.7995355725288391 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "circle" : - { - "center" : - { - "x" : -0.01561669446527958, - "y" : 0.004700659774243832 - }, - "radius" : 0.2268356680870056 - }, - "density" : 0.2204959988594055, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture1" - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0009264730615541339, - "massData-center" : - { - "x" : -0.01561669446527958, - "y" : 0.004700659774243832 - }, - "massData-mass" : 0.03564291819930077, - "name" : "head", - "position" : - { - "x" : 0.02309736609458923, - "y" : 1.497289657592773 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.04693000018596649, - 0.04693000018596649, - -0.04693005979061127, - -0.04693005979061127 - ], - "y" : - [ - -0.1159216761589050, - 0.1159217953681946, - 0.1159217953681946, - -0.1159216761589050 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0001134485355578363, - "massData-center" : - { - "x" : -2.980232238769531e-08, - "y" : 5.960464477539062e-08 - }, - "massData-mass" : 0.02176084183156490, - "name" : "lowerRightArm", - "position" : - { - "x" : 0.1183081120252609, - "y" : 0.6842151284217834 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.07039500027894974, - 0.07039500027894974, - -0.07039500027894974, - -0.07039500027894974 - ], - "y" : - [ - -0.09294360131025314, - 0.1277720034122467, - 0.1277720034122467, - -0.09294360131025314 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0001869037223514169, - "massData-center" : - { - "x" : 0, - "y" : 0.01741420105099678 - }, - "massData-mass" : 0.03107454814016819, - "name" : "lowerLeftLeg", - "position" : - { - "x" : -0.03829947486519814, - "y" : 0.09799569845199585 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.04693000763654709, - 0.04693000763654709, - -0.04692991077899933, - -0.04692991077899933 - ], - "y" : - [ - -0.1159216761589050, - 0.1159217953681946, - 0.1159217953681946, - -0.1159216761589050 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0001134483172791079, - "massData-center" : - { - "x" : 4.842877032729120e-08, - "y" : 5.960464477539062e-08 - }, - "massData-mass" : 0.02176081016659737, - "name" : "lowerLeftArm", - "position" : - { - "x" : -0.1165381968021393, - "y" : 0.6842151284217834 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.04693000018596649, - 0.04693000018596649, - -0.04693010076880455, - -0.04693010076880455 - ], - "y" : - [ - -0.1895969957113266, - 0.1895969957113266, - 0.1895969957113266, - -0.1895969957113266 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0004525947733782232, - "massData-center" : - { - "x" : -5.029141902923584e-08, - "y" : 0 - }, - "massData-mass" : 0.03559118881821632, - "name" : "upperRightArm", - "position" : - { - "x" : 0.1183080002665520, - "y" : 0.9012569785118103 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.07039496302604675, - 0.07039496302604675, - -0.07039486616849899, - -0.07039486616849899 - ], - "y" : - [ - -0.1890522241592407, - 0.1890524625778198, - 0.1890524625778198, - -0.1890522241592407 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0007221315754577518, - "massData-center" : - { - "x" : 4.842877388000488e-08, - "y" : 1.192092895507812e-07 - }, - "massData-mass" : 0.05323329567909241, - "name" : "upperRightLeg", - "position" : - { - "x" : 0.03859551250934601, - "y" : 0.3325110077857971 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.07039505988359451, - 0.07039505988359451, - -0.07039495557546616, - -0.07039495557546616 - ], - "y" : - [ - -0.1890522241592407, - 0.1890524625778198, - 0.1890524625778198, - -0.1890522241592407 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.000722132739610970, - "massData-center" : - { - "x" : 5.215406417846680e-08, - "y" : 1.192092824453539e-07 - }, - "massData-mass" : 0.05323336645960808, - "name" : "upperLeftLeg", - "position" : - { - "x" : -0.03829947486519814, - "y" : 0.3325110077857971 - }, - "type" : 2 - }, - - { - "angle" : 0, - "angularVelocity" : 0, - "awake" : true, - "fixture" : - [ - - { - "density" : 1, - "filter-groupIndex" : -55, - "friction" : 0.2, - "name" : "fixture3", - "polygon" : - { - "vertices" : - { - "x" : - [ - 0.07039500027894974, - 0.07039500027894974, - -0.07039490342140198, - -0.07039490342140198 - ], - "y" : - [ - -0.09294389933347702, - 0.1276109963655472, - 0.1276109963655472, - -0.09294389933347702 - ] - } - } - } - ], - "linearVelocity" : 0, - "massData-I" : 0.0001864968799054623, - "massData-center" : - { - "x" : 4.842877032729120e-08, - "y" : 0.01733354665338993 - }, - "massData-mass" : 0.03105190023779869, - "name" : "lowerRightLeg", - "position" : - { - "x" : 0.03859551250934601, - "y" : 0.09799569845199585 - }, - "type" : 2 - } - ], - "collisionbitplanes" : - { - "names" : - [ - "bitplane1", - "bitplane2", - "bitplane3", - "bitplane4", - "bitplane5", - "bitplane6", - "bitplane7", - "bitplane8", - "bitplane9", - "bitplane10", - "bitplane11", - "bitplane12", - "bitplane13", - "bitplane14", - "bitplane15", - "bitplane16", - "bitplane17", - "bitplane18", - "bitplane19", - "bitplane20", - "bitplane21", - "bitplane22", - "bitplane23", - "bitplane24", - "bitplane25", - "bitplane26", - "bitplane27", - "bitplane28", - "bitplane29", - "bitplane30", - "bitplane31", - "bitplane32" - ] - }, - "continuousPhysics" : true, - "gravity" : - { - "x" : 0, - "y" : -10 - }, - "joint" : - [ - - { - "anchorA" : - { - "x" : 0.0003538504242897034, - "y" : 0.07107692956924438 - }, - "anchorB" : - { - "x" : 0.0003536641597747803, - "y" : -0.1459649801254272 - }, - "bodyA" : 3, - "bodyB" : 6, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : 0.01745329238474369, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint1", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 1.919862151145935 - }, - - { - "anchorA" : - { - "x" : -0.0007802955806255341, - "y" : -0.1484909951686859 - }, - "anchorB" : - { - "x" : -0.0007801018655300140, - "y" : 0.08614099025726318 - }, - "bodyA" : 8, - "bodyB" : 4, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : 0.01745329238474369, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint7", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 2.443460941314697 - }, - - { - "anchorA" : - { - "x" : -0.004979588091373444, - "y" : -0.1506859958171844 - }, - "anchorB" : - { - "x" : -0.005973689258098602, - "y" : 0.08482310175895691 - }, - "bodyA" : 7, - "bodyB" : 9, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : 0.01745329238474369, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint8", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 2.443460941314697 - }, - - { - "anchorA" : - { - "x" : -0.06799955666065216, - "y" : -0.3021813035011292 - }, - "anchorB" : - { - "x" : -0.02891255542635918, - "y" : 0.1648437976837158 - }, - "bodyA" : 1, - "bodyB" : 8, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -0.7853981852531433, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint6", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 1.570796370506287 - }, - - { - "anchorA" : - { - "x" : 0.06260262429714203, - "y" : -0.3029872477054596 - }, - "anchorB" : - { - "x" : 0.02294230461120605, - "y" : 0.1640380322933197 - }, - "bodyA" : 1, - "bodyB" : 7, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -0.7853981852531433, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint5", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 1.570796370506287 - }, - - { - "anchorA" : - { - "x" : 0.1179294362664223, - "y" : 0.2464744448661804 - }, - "anchorB" : - { - "x" : 0.0004089996218681335, - "y" : 0.1447530388832092 - }, - "bodyA" : 1, - "bodyB" : 6, - "enableLimit" : false, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -2.268928050994873, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint2", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 3.141592741012573 - }, - - { - "anchorA" : - { - "x" : -0.1188285648822784, - "y" : 0.2521644234657288 - }, - "anchorB" : - { - "x" : -0.001505002379417419, - "y" : 0.1504430174827576 - }, - "bodyA" : 1, - "bodyB" : 0, - "enableLimit" : false, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -2.268928050994873, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint3", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 3.141592741012573 - }, - - { - "anchorA" : - { - "x" : 0.0008554458618164062, - "y" : -0.1461489796638489 - }, - "anchorB" : - { - "x" : 0.0008557140827178955, - "y" : 0.07089227437973022 - }, - "bodyA" : 0, - "bodyB" : 5, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -1.919862151145935, - "maxMotorTorque" : 1, - "motorSpeed" : 0, - "name" : "joint4", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 0.01745329238474369 - }, - - { - "anchorA" : - { - "x" : 0.02210754156112671, - "y" : 0.4607425332069397 - }, - "anchorB" : - { - "x" : -0.02544101513922215, - "y" : -0.2591779232025146 - }, - "bodyA" : 1, - "bodyB" : 2, - "enableLimit" : true, - "enableMotor" : false, - "jointSpeed" : 0, - "lowerLimit" : -0.6981316804885864, - "maxMotorTorque" : 0, - "motorSpeed" : 0, - "name" : "joint9", - "refAngle" : 0, - "type" : "revolute", - "upperLimit" : 1.221730470657349 - } - ], - "positionIterations" : 3, - "stepsPerSecond" : 60.0, - "subStepping" : false, - "velocityIterations" : 8, - "warmStarting" : true -} diff --git a/app/Game/Channel/Channel.js b/app/Game/Channel/Channel.js index db3b3a6..094cef0 100755 --- a/app/Game/Channel/Channel.js +++ b/app/Game/Channel/Channel.js @@ -3,13 +3,11 @@ "Lib/Utilities/NotificationCenter", "Game/Channel/User", "Lib/Utilities/Protocol/Helper", - "Lib/Utilities/OptionsHelper", + "Lib/Utilities/Options", "Game/Config/Settings" ], - function (GameController, nc, User, ProtocolHelper, optionsHelper, Settings) { - - "use strict"; + function (GameController, Nc, User, ProtocolHelper, Options, Settings) { function Channel (pipeToServer, options) { @@ -19,25 +17,24 @@ this.users = {}; this.pipeToServer = pipeToServer; this.levelListIndex = -1; - this.gameController = null; - this.options = options = optionsHelper.merge(options, { + this.options = options = Options.merge(options, { levelUids: Settings.CHANNEL_DEFAULT_LEVELS }); // Notification Center - nc.on(nc.ns.channel.events.round.end, this.onEndRound, this); - nc.on(nc.ns.channel.events.controlCommand.channel, function (message) { + Nc.on(Nc.ns.channel.events.round.end, this.onEndRound, this); + Nc.on(Nc.ns.channel.events.controlCommand.channel, function (message) { ProtocolHelper.applyCommand(message.data, self); }); - nc.on(nc.ns.channel.to.client.gameCommand.broadcast, this.broadcastGameCommand, this); - nc.on(nc.ns.channel.to.client.controlCommand.broadcast, this.broadcastControlCommand, this); - //nc.on(nc.ns.channel.to.client.gameCommand.broadcastExcept, this.broadcastGameCommandExcept, this); - //nc.on(nc.ns.channel.to.client.controlCommand.broadcastExcept, this.broadcastControlCommandExcept, this); + Nc.on(Nc.ns.channel.to.client.gameCommand.broadcast, this.broadcastGameCommand, this); + Nc.on(Nc.ns.channel.to.client.controlCommand.broadcast, this.broadcastControlCommand, this); + //Nc.on(Nc.ns.channel.to.client.gameCommand.broadcastExcept, this.broadcastGameCommandExcept, this); + //Nc.on(Nc.ns.channel.to.client.controlCommand.broadcastExcept, this.broadcastControlCommandExcept, this); this.beginRound(); - console.checkpoint("channel " + this.name + " created"); + console.checkpoint('channel ' + this.name + ' created'); setTimeout(function() { if(Object.keys(self.users).length < 1) { @@ -56,7 +53,7 @@ if(this.gameController) { this.gameController.destroy(); - this.gameController = null; + delete this.gameController; } var gameControllerOptions = { @@ -82,7 +79,6 @@ Channel.prototype.onEndRound = function() { var self = this; - this.gameController.endRound(); this.broadcastControlCommand("endRound", true); console.checkpoint("End Round (" + this.name + ") - Begin Round in " + Settings.CHANNEL_END_ROUND_TIME + " seconds"); @@ -103,23 +99,23 @@ }; if(!this.gameController.level || !this.gameController.level.isLoaded) { - var token = nc.on(nc.ns.core.game.events.level.loaded, function() { + var token = Nc.on(Nc.ns.core.game.events.level.loaded, function() { self.sendJoinSuccess(options); - self.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); - nc.off(token); + this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); + Nc.off(token); }); } else { - this.sendJoinSuccess(options); + self.sendJoinSuccess(options); this.users[options.id].sendControlCommand("beginRound", clientGameControllerOptions); } - }; + } Channel.prototype.sendJoinSuccess = function(options) { var user = new User(options.id, options); var joinedUsers = []; for(var userId in this.users) { - joinedUsers.push(this.users[userId].options); + joinedUsers.push(this.users[userId].options) } var levelUid = null; @@ -129,22 +125,23 @@ this.users[user.id] = user; - options = { + var options = { user: user.options, joinedUsers: joinedUsers, levelUid: levelUid }; - //nc.trigger("user/" + user.id + "/joinSuccess", options); + //Nc.trigger('user/' + user.id + "/joinSuccess", options); user.sendControlCommand("joinSuccess", options); - nc.trigger(nc.ns.channel.events.user.joined, user); + Nc.trigger(Nc.ns.channel.events.user.joined, user); this.broadcastControlCommandExcept("userJoined", user.options, user); }; Channel.prototype.onReleaseUser = function (userId) { var self = this; - nc.trigger(nc.ns.channel.events.user.left, userId); + var user = this.users[userId]; + Nc.trigger(Nc.ns.channel.events.user.left, userId); delete this.users[userId]; this.broadcastControlCommand("userLeft", userId); @@ -161,7 +158,7 @@ } }, Settings.CHANNEL_DESTRUCTION_TIME * 1000); } - }; + } Channel.prototype.destroy = function() { console.checkpoint("channel (" + this.name + ") destroyed"); @@ -175,7 +172,7 @@ for(var id in this.users) { this.users[id].sendControlCommand(command, options); } - }; + } Channel.prototype.broadcastControlCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { @@ -183,13 +180,13 @@ this.users[id].sendControlCommand(command, options); } } - }; + } Channel.prototype.broadcastGameCommand = function (command, options) { for(var id in this.users) { this.users[id].sendGameCommand(command, options); } - }; + } Channel.prototype.broadcastGameCommandExcept = function (command, options, exceptUser) { for(var id in this.users) { @@ -197,7 +194,7 @@ this.users[id].sendGameCommand(command, options); } } - }; + } return Channel; diff --git a/app/Game/Channel/Collision/Detector.js b/app/Game/Channel/Collision/Detector.js index 4d81552..8576da9 100755 --- a/app/Game/Channel/Collision/Detector.js +++ b/app/Game/Channel/Collision/Detector.js @@ -4,8 +4,6 @@ define([ function (Parent) { - "use strict"; - function Detector () { Parent.call(this); } diff --git a/app/Game/Channel/Control/PlayerController.js b/app/Game/Channel/Control/PlayerController.js index c9e55d3..c8e5c6e 100755 --- a/app/Game/Channel/Control/PlayerController.js +++ b/app/Game/Channel/Control/PlayerController.js @@ -5,9 +5,7 @@ define([ "Game/Config/Settings" ], -function(Parent, nc, Parser, Settings) { - - "use strict"; +function(Parent, Nc, Parser, Settings) { function PlayerController(player) { @@ -35,34 +33,31 @@ function(Parent, nc, Parser, Settings) { }; PlayerController.prototype.handActionRequest = function(options) { - options.x = parseFloat(options.x) || 0.0; - options.y = parseFloat(options.y) || 0.0; - options.av = parseFloat(options.av) || 0.0; - if (options) this.player.handActionRequest(options); + if (options) this.player.handActionRequest(options.x, options.y); }; PlayerController.prototype.suicide = function() { this.player.suicide(); }; - PlayerController.prototype.mePositionStateOverride = function(update) { + PlayerController.prototype.mePositionStateUpdate = function(update) { - if(!this.player.isSpawned()) { - // if someone still falls but is dead on the server already - return; + if(!this.player.doll) { + console.warn('me state update, even though doll does not exist'); + return; } var difference = { x: Math.abs(update.p.x - this.player.doll.body.GetPosition().x), y: Math.abs(update.p.y - this.player.doll.body.GetPosition().y) - }; + } - if(difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS && - difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) { + if(difference.x < Settings.PUNKBUSTER_DIFFERENCE_METERS + && difference.y < Settings.PUNKBUSTER_DIFFERENCE_METERS) { this.player.doll.updatePositionState(update); } else { // HARD UPDATE FOR SELF - console.log(this.player.user.options.nickname + " is cheating."); + console.log(this.player.user.options.nickname + ' is cheating.') var body = this.player.doll.body; @@ -71,7 +66,7 @@ function(Parent, nc, Parser, Settings) { lv: body.GetLinearVelocity() }; - nc.trigger(nc.ns.channel.to.client.user.gameCommand.send + this.player.id, "positionStateReset", options); + Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + this.player.id, 'positionStateReset', options); } }; diff --git a/app/Game/Channel/GameController.js b/app/Game/Channel/GameController.js index 4f5f5b5..eb7e013 100755 --- a/app/Game/Channel/GameController.js +++ b/app/Game/Channel/GameController.js @@ -2,40 +2,39 @@ define([ "Game/Core/GameController", "Game/Channel/Physics/Engine", "Game/Config/Settings", + "Game/Channel/Control/PlayerController", "Lib/Utilities/RequestAnimFrame", "Lib/Utilities/NotificationCenter", "Lib/Vendor/Box2D", "Game/Channel/Player", "Game/Channel/GameObjects/GameObject", "Game/Channel/GameObjects/Doll", - "Game/Channel/GameObjects/Items/RubeDoll" + "Game/Channel/GameObjects/Items/RagDoll" ], -function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, GameObject, Doll, RubeDoll) { - - "use strict"; +function (Parent, PhysicsEngine, Settings, PlayerController, requestAnimFrame, Nc, Box2D, Player, GameObject, Doll, RagDoll) { function GameController (options) { this.animationTimeout = null; this.worldUpdateTimeout = null; this.spawnTimeouts = []; - this.roundHasEnded = false; Parent.call(this, options); this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.channel.events.user.joined, this.onUserJoined, this), - nc.on(nc.ns.channel.events.user.left, this.onUserLeft, this), - nc.on(nc.ns.channel.events.user.level.reset, this.onResetLevel, this), - nc.on(nc.ns.channel.events.user.client.ready, this.onClientReady, this), - nc.on(nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this), - nc.on(nc.ns.channel.events.game.player.killed, this.onPlayerKilled, this), + Nc.on(Nc.ns.channel.events.user.joined, this.onUserJoined, this), + Nc.on(Nc.ns.channel.events.user.left, this.onUserLeft, this), + Nc.on(Nc.ns.channel.events.user.level.reset, this.onResetLevel, this), + Nc.on(Nc.ns.channel.events.user.client.ready, this.onClientReady, this), + Nc.on(Nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this), + Nc.on(Nc.ns.channel.events.game.player.killed, this.onPlayerKilled, this), ]); console.checkpoint('starting game controller for channel (' + options.channelName + ')'); } + GameController.prototype = Object.create(Parent.prototype); GameController.prototype.update = function () { @@ -58,28 +57,15 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, this.createPlayer(user); } - GameController.prototype.onUserLeft = function (userId) { - var player = this.players[userId]; - this.clearItemsOfPlayerFingerPrints(player); - Parent.prototype.onUserLeft.call(this, userId); - }; - - GameController.prototype.clearItemsOfPlayerFingerPrints = function(player) { - nc.trigger(nc.ns.channel.events.game.player.clearFingerPrints, player); - }; - GameController.prototype.createPlayer = function(user) { - - var revealedGameController = { - isInBetweenRounds: this.isInBetweenRounds.bind(this) - }; - var player = Parent.prototype.createPlayer.call(this, user, revealedGameController); + var player = Parent.prototype.createPlayer.call(this, user); + player.setPlayerController(new PlayerController(player)) user.setPlayer(player); }; GameController.prototype.onPlayerKilled = function(player, killedByPlayer) { if(killedByPlayer.stats.score >= this.options.scoreLimit) { - nc.trigger(nc.ns.channel.events.round.end); + Nc.trigger(Nc.ns.channel.events.round.end); } else { this.spawnPlayer(player, Settings.RESPAWN_TIME); } @@ -95,6 +81,8 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, var spawnTimeout = setTimeout(function() { player.spawn(spawnPoint.x, spawnPoint.y); + // put it into + self.gameObjects.animated.push(player); var options = { id: player.id, @@ -102,7 +90,7 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, y: spawnPoint.y }; - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "spawnPlayer", options); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "spawnPlayer", options); var i = self.spawnTimeouts.indexOf(spawnTimeout); self.spawnTimeouts.splice(i, 1); @@ -117,18 +105,17 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, var update = this.getWorldUpdateObject(false); if(Object.getOwnPropertyNames(update).length > 0) { - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "worldUpdate", update); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, 'worldUpdate', update); } this.worldUpdateTimeout = setTimeout(this.updateWorld.bind(this), Settings.NETWORK_UPDATE_INTERVAL); - }; + } GameController.prototype.getWorldUpdateObject = function(getSleeping) { getSleeping = getSleeping || false; var update = {}; -/* var body = this.physicsEngine.world.GetBodyList(); do { if((getSleeping || body.IsAwake()) && body.GetType() === Box2D.Dynamics.b2Body.b2_dynamicBody) { @@ -136,33 +123,22 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, if (userData instanceof GameObject) { var gameObject = userData; - var updateData = gameObject.getUpdateData(); - - if (updateData) { - update[gameObject.uid] = updateData; + + update[gameObject.uid] = { + p: body.GetPosition(), + a: body.GetAngle(), + lv: body.GetLinearVelocity(), + av: body.GetAngularVelocity() + }; + + if(gameObject instanceof Doll) { + update[gameObject.uid].as = gameObject.getActionState(); + update[gameObject.uid].laxy = gameObject.lookAtXY; } } } } while (body = body.GetNext()); -*/ - - for (var uid in this.worldUpdateObjects) { - - var gameObject = this.worldUpdateObjects[uid]; - - if (!(gameObject instanceof GameObject)) { - console.warn('Cant find object ' + uid + ' in worldUpdateObjects pool (channel side), here is the object:'); - console.log(gameObject); - continue; - } - - var updateData = gameObject.getUpdateData(getSleeping); - - if (updateData) { - update[gameObject.uid] = updateData; - } - } return update; }; @@ -171,7 +147,7 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, var spawnedPlayers = []; for(var id in this.players) { var player = this.players[id]; - if(player.isSpawned()) { + if(player.isSpawned) { var options = { id: id, @@ -190,36 +166,23 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, return spawnedPlayers; }; - GameController.prototype._getRuntimeItems = function() { + GameController.prototype.getRuntimeItems = function() { + var objects = [] - var runtimeItems = []; - for (var uid in this.worldUpdateObjects) { - if(this.worldUpdateObjects[uid] instanceof RubeDoll) { - var object = this.worldUpdateObjects[uid]; - runtimeItems.push(object); + for (var i = 0; i < this.gameObjects.animated.length; i++) { + if(this.gameObjects.animated[i] instanceof RagDoll) { + var object = this.gameObjects.animated[i]; + var options = object.options; + options.x = object.getPosition().x; + options.y = object.getPosition().y; + objects.push({ + uid: object.uid, + options: object.options + }); } - } - return runtimeItems; - }; + }; - GameController.prototype.gatherRuntimeItemsForWorldUpdate = function() { - var infos = []; - var runtimeItems = this._getRuntimeItems(); - - // On the other side this is using the level.createItem mechanism to - // create the RubeDoll from its ItemSettings - for (var i = 0; i < runtimeItems.length; i++) { - var object = runtimeItems[i]; - var options = object.options; - options.x = object.getPosition().x; - options.y = object.getPosition().y; - infos.push({ - uid: object.uid, - options: object.options - }); - } - - return infos; + return objects; }; GameController.prototype.onClientReady = function(userId) { @@ -228,34 +191,21 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, var options = { spawnedPlayers: this.getSpawnedPlayersAndTheirPositions(), worldUpdate: this.getWorldUpdateObject(true), - runtimeItems: this.gatherRuntimeItemsForWorldUpdate(), + runtimeItems: this.getRuntimeItems(), userId: userId - }; + } - nc.trigger(nc.ns.channel.to.client.user.gameCommand.send + userId, "clientReadyResponse", options); + Nc.trigger(Nc.ns.channel.to.client.user.gameCommand.send + userId, "clientReadyResponse", options); this.spawnPlayer(player, 0); }; - GameController.prototype.endRound = function() { - this.roundHasEnded = true; - - for(var id in this.players) { - this.players[id].setInBetweenRounds(true); - } - }; - - GameController.prototype.isInBetweenRounds = function() { - return this.roundHasEnded; - }; - - // FIXME: remove this method GameController.prototype.onResetLevel = function(userId) { console.log('OH NO!!! ON RESET LEVEL IS CALLED AND RESPAWNES PLAYERS'); Parent.prototype.onResetLevel.call(this); - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "resetLevel", true); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "resetLevel", true); for (var key in this.players) { this.spawnPlayer(this.players[key]); } @@ -269,11 +219,6 @@ function (Parent, PhysicsEngine, Settings, requestAnimFrame, nc, Box2D, Player, clearTimeout(this.spawnTimeouts[i]); }; - var runtimeItems = this._getRuntimeItems(); - for (var i = 0; i < runtimeItems.length; i++) { - runtimeItems[i].destroy(); - } - Parent.prototype.destroy.call(this); }; diff --git a/app/Game/Channel/GameObjects/Doll.js b/app/Game/Channel/GameObjects/Doll.js index 572beac..ed5022b 100755 --- a/app/Game/Channel/GameObjects/Doll.js +++ b/app/Game/Channel/GameObjects/Doll.js @@ -2,13 +2,10 @@ define([ "Game/Core/GameObjects/Doll", "Game/Channel/GameObjects/Item", "Lib/Vendor/Box2D", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Item, Box2D, nc, Assert) { - - "use strict"; +function (Parent, Item, Box2D, Nc) { function Doll(physicsEngine, uid, player) { Parent.call(this, physicsEngine, uid, player); @@ -16,14 +13,12 @@ function (Parent, Item, Box2D, nc, Assert) { Doll.prototype = Object.create(Parent.prototype); - Doll.prototype.findCloseItem = function(x) { - - var self = this; + Doll.prototype.findCloseItem = function(x, y) { function findItem(array) { for (var i = 0; i < array.length; i++) { var item = array[i]; - if(item.isGrabbingAllowed(self.player)) { + if(item.isGrabbingAllowed(this.player)) { return item; } } @@ -34,7 +29,7 @@ function (Parent, Item, Box2D, nc, Assert) { } else { return findItem(this.reachableItems.right); } - }; + } Doll.prototype.onImpact = function(isColliding, fixture) { var self = this; @@ -47,73 +42,47 @@ function (Parent, Item, Box2D, nc, Assert) { var item = otherBody.GetUserData(); if(item instanceof Item) { var itemVelocity = item.body.GetLinearVelocity(); - //var itemMass = item.body.GetMass(); + var itemMass = item.body.GetMass(); var ownVelocity = this.body.GetLinearVelocity(); var b2Math = Box2D.Common.Math.b2Math; - var absItemVelocity = b2Math.AbsV(itemVelocity); - var min = 1; - var damage = 0; + + var absItemVelocity = b2Math.AbsV(itemVelocity) + var max = 1; - if(absItemVelocity.x > min || absItemVelocity.y > min) { + if(absItemVelocity.x > max || absItemVelocity.y > max) { if(item.lastMoved && item.lastMoved.player != this.player) { + var damageVector = b2Math.SubtractVV(itemVelocity, ownVelocity); + damageVector.Abs(); + damageVector.Multiply(0.7); + damageVector.Multiply(itemMass * 1.3); + var damage = damageVector.Length(); + damage *= item.options.danger ? item.options.danger : 1; - var collision = b2Math.SubtractVV(itemVelocity, ownVelocity); + var player = item.lastMoved.player; - // Tested max velocity banana: 50 - var velocityDamage = collision.Length() / 50; - - // Max weight of piano: 15 - var weightDamage = item.options.weight / 15; - - // Max danger of knife: 3 - var dangerDamage = item.options.danger / 3; - - // + 0.5 and / 2: offsetting for lower velocity impact - // * 300: tested imperically by throwing piano from deadly height - // * 80: tested imperically by throwing knife fast - damage = (velocityDamage + 0.5) * (weightDamage * 300 + dangerDamage * 80) / 2; - - var lastMovedPlayer = item.lastMoved.player; var callback = function() { - self.player.addDamage(damage, lastMovedPlayer, item); - }; + self.player.addDamage(damage, player); + } - nc.trigger(nc.ns.channel.engine.worldQueue.add, callback); + Nc.trigger(Nc.ns.channel.engine.worldQueue.add, callback) } } - // only set lastMovedBy if player wasn't hurt by collision - if (damage === 0) { - item.setLastMovedBy(this.player); - } + item.setLastMovedBy(this.player); } } } - }; + } Doll.prototype.updatePositionState = function(update) { if(!this.isAnotherPlayerNearby()) { - Assert.number(update.p.x, update.p.y); - Assert.number(update.lv.x, update.lv.y); this.body.SetAwake(true); this.body.SetPosition(update.p); this.body.SetLinearVelocity(update.lv); } }; - - Doll.prototype.getUpdateData = function(getSleeping) { - - var updateData = Parent.prototype.getUpdateData.call(this, getSleeping); - - if(updateData) { - updateData.as = this.getActionState(); - updateData.laxy = this.lookAtXY; - } - - return updateData; - }; return Doll; diff --git a/app/Game/Channel/GameObjects/GameObject.js b/app/Game/Channel/GameObjects/GameObject.js index 5d51afb..03b2a9b 100755 --- a/app/Game/Channel/GameObjects/GameObject.js +++ b/app/Game/Channel/GameObjects/GameObject.js @@ -1,39 +1,9 @@ define([ - "Game/Core/GameObjects/GameObject", - "Lib/Vendor/Box2D" + "Game/Core/GameObjects/GameObject" ], -function (Parent, Box2D) { +function(Parent) { - "use strict"; + return Parent; - function GameObject(physicsEngine, uid) { - Parent.call(this, physicsEngine, uid); - } - - GameObject.prototype = Object.create(Parent.prototype); - - GameObject.prototype.getUpdateData = function(getSleeping) { - - if (!this.body) { - return null; - } - - if (this.body.GetType() === Box2D.Dynamics.b2Body.b2_staticBody) { - return null; - } - - if (!getSleeping && !this.body.IsAwake()) { - return null; - } - - return { - p: this.body.GetPosition(), - a: this.body.GetAngle(), - lv: this.body.GetLinearVelocity(), - av: this.body.GetAngularVelocity() - }; - } - - return GameObject; }); \ No newline at end of file diff --git a/app/Game/Channel/GameObjects/Item.js b/app/Game/Channel/GameObjects/Item.js index 0bdb334..dcf28ef 100755 --- a/app/Game/Channel/GameObjects/Item.js +++ b/app/Game/Channel/GameObjects/Item.js @@ -1,27 +1,17 @@ define([ - "Game/Core/GameObjects/Item", - "Lib/Utilities/NotificationCenter", + "Game/Core/GameObjects/Item" ], -function (Parent, nc) { - - "use strict"; +function (Parent) { function Item(physicsEngine, uid, options) { Parent.call(this, physicsEngine, uid, options); this.heldByPlayers = []; this.lastMoved = null; - - this.ncTokens = (this.ncTokens || []).concat([ - nc.on(nc.ns.channel.events.game.player.clearFingerPrints, this.clearOfPlayerFingerPrints, this) - ]); } Item.prototype = Object.create(Parent.prototype); - Item.prototype.getLastMovedBy = function() { - return this.lastMoved; - } Item.prototype.setLastMovedBy = function(player) { @@ -29,14 +19,14 @@ function (Parent, nc) { this.lastMoved = { player: player, timestamp: new Date() - }; + } } else { this.lastMoved = null; } }; - Item.prototype.isGrabbingAllowed = function(player) { // jshint unused:false - return this.heldByPlayers.length === 0; + Item.prototype.isGrabbingAllowed = function(player) { + return this.heldByPlayers.length == 0; }; Item.prototype.beingGrabbed = function(player) { @@ -48,7 +38,7 @@ function (Parent, nc) { } }; - Item.prototype.isReleasingAllowed = function(player) { // jshint unused:false + Item.prototype.isReleasingAllowed = function(player) { return true; }; @@ -64,13 +54,6 @@ function (Parent, nc) { } }; - Item.prototype.clearOfPlayerFingerPrints = function(player) { - if (this.getLastMovedBy() && this.getLastMovedBy().player === player) { - console.checkpoint('Removing fingerprints from ' + this.options.image); - this.setLastMovedBy(null); - } - }; - Item.prototype.onCollisionChange = function(isColliding, fixture) { if(isColliding) { @@ -96,7 +79,8 @@ function (Parent, nc) { } } } - }; + } + return Item; diff --git a/app/Game/Channel/GameObjects/Items/RagDoll.js b/app/Game/Channel/GameObjects/Items/RagDoll.js index 1c02792..938e229 100644 --- a/app/Game/Channel/GameObjects/Items/RagDoll.js +++ b/app/Game/Channel/GameObjects/Items/RagDoll.js @@ -4,9 +4,7 @@ define([ "Lib/Utilities/NotificationCenter" ], -function (Parent, Settings, nc) { - - "use strict"; +function (Parent, Settings, Nc) { function RagDoll(physicsEngine, uid, options) { this.scheduledForDestruction = false; @@ -35,7 +33,7 @@ function (Parent, Settings, nc) { var self = this; this.scheduledForDestruction = true; this.destructionTimeout = setTimeout(function() { - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', { + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', { type: 'animated', uid: self.uid }); diff --git a/app/Game/Channel/GameObjects/Items/Rube.js b/app/Game/Channel/GameObjects/Items/Rube.js new file mode 100644 index 0000000..f663984 --- /dev/null +++ b/app/Game/Channel/GameObjects/Items/Rube.js @@ -0,0 +1,9 @@ +define([ + "Game/Core/GameObjects/Items/Rube" +], + +function (Parent) { + + return Parent; + +}); \ No newline at end of file diff --git a/app/Game/Channel/GameObjects/Items/RubeDoll.js b/app/Game/Channel/GameObjects/Items/RubeDoll.js deleted file mode 100644 index c03199e..0000000 --- a/app/Game/Channel/GameObjects/Items/RubeDoll.js +++ /dev/null @@ -1,79 +0,0 @@ -define([ - "Game/Core/GameObjects/Items/RubeDoll", - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter" -], - -function (Parent, Settings, nc) { - - "use strict"; - - function RubeDoll(physicsEngine, uid, options) { - this.scheduledForDestruction = false; - this.destructionTimeout = null; - - Parent.call(this, physicsEngine, uid, options); - } - - RubeDoll.prototype = Object.create(Parent.prototype); - - RubeDoll.prototype.beingGrabbed = function(player) { - Parent.prototype.beingGrabbed.call(this, player); - if(this.scheduledForDestruction) { - clearTimeout(this.destructionTimeout); - } - }; - - RubeDoll.prototype.beingReleased = function(player) { - Parent.prototype.beingReleased.call(this, player); - if(this.scheduledForDestruction) { - this.delayedDestroy(); - } - }; - - RubeDoll.prototype.delayedDestroy = function() { - var self = this; - this.scheduledForDestruction = true; - this.destructionTimeout = setTimeout(function() { - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, 'removeGameObject', { - type: 'animated', - uid: self.uid - }); - self.destroy(); - }, Settings.RAGDOLL_DESTRUCTION_TIME * 1000); - }; - - RubeDoll.prototype.getUpdateData = function(getSleeping) { - var updateData = Parent.prototype.getUpdateData.call(this, getSleeping); - - // if parent is asleep it sends null, to do no update - if(!updateData) { - return updateData; - } - - // adding limb update data - var limbUpdateData = {}; - - for(var name in this.limbs) { - limbUpdateData[name] = { - p: this.limbs[name].GetPosition(), - a: this.limbs[name].GetAngle(), - lv: this.limbs[name].GetLinearVelocity(), - av: this.limbs[name].GetAngularVelocity() - }; - } - updateData['limbs'] = limbUpdateData; - - return updateData; - } - - RubeDoll.prototype.destroy = function() { - if(this.scheduledForDestruction) { - clearTimeout(this.destructionTimeout); - } - Parent.prototype.destroy.call(this); - }; - - return RubeDoll; - -}); \ No newline at end of file diff --git a/app/Game/Channel/GameObjects/SpectatorDoll.js b/app/Game/Channel/GameObjects/SpectatorDoll.js index 058fca7..b89f262 100644 --- a/app/Game/Channel/GameObjects/SpectatorDoll.js +++ b/app/Game/Channel/GameObjects/SpectatorDoll.js @@ -4,8 +4,6 @@ define([ function (Parent) { - "use strict"; - return Parent; }); \ No newline at end of file diff --git a/app/Game/Channel/Loader/Level.js b/app/Game/Channel/Loader/Level.js index 4271cd3..f0c9818 100755 --- a/app/Game/Channel/Loader/Level.js +++ b/app/Game/Channel/Loader/Level.js @@ -4,12 +4,10 @@ define([ "fs" ], -function (Parent, Settings, FileSystem) { +function (Parent, Settings, fs) { - "use strict"; - - function Level (uid, engine) { - Parent.call(this, uid, engine); + function Level (uid, engine, gameObjects) { + Parent.call(this, uid, engine, gameObjects); } Level.prototype = Object.create(Parent.prototype); @@ -17,7 +15,7 @@ function (Parent, Settings, FileSystem) { Level.prototype.loadLevelDataFromPath = function (path, callback) { // overwriting parent - FileSystem.readFile(path, "utf8", function (err, data) { + fs.readFile(path, "utf8", function (err, data) { if (err) throw err; callback(JSON.parse(data)); }); diff --git a/app/Game/Channel/Loader/TiledLevel.js b/app/Game/Channel/Loader/TiledLevel.js index ad96bfd..e23fbd3 100644 --- a/app/Game/Channel/Loader/TiledLevel.js +++ b/app/Game/Channel/Loader/TiledLevel.js @@ -4,8 +4,6 @@ define([ function (Parent) { - "use strict"; - return Parent; }); \ No newline at end of file diff --git a/app/Game/Channel/PipeToServer.js b/app/Game/Channel/PipeToServer.js index c25e34d..2c007e5 100755 --- a/app/Game/Channel/PipeToServer.js +++ b/app/Game/Channel/PipeToServer.js @@ -1,147 +1,55 @@ define([ "Lib/Utilities/NotificationCenter", - "Game/Channel/Channel", - "Game/Config/Settings", - "fs" + "Game/Channel/Channel" ], -function (nc, Channel, Settings, fs) { - - "use strict"; +function (Nc, Channel) { function PipeToServer (process) { + + var self = this; + this.channel = null; this.process = process; - this.recordingFileName = null; - nc.on(nc.ns.channel.to.server.controlCommand.send, this.send, this); + Nc.on(Nc.ns.channel.to.server.controlCommand.send, this.send, this); - process.on("message", this.onProcessMessage.bind(this)); + process.on('message', function (message, handle) { + + if(message.data.hasOwnProperty('CREATE')) { + self.channel = new Channel(self, message.data.options); + } else if (message.data.hasOwnProperty('KILL')) { + self.channel.destroy(); + } else { + self.onMessage(message); + } + + }); } - PipeToServer.prototype.onProcessMessage = function (message, handle) { // jshint unused:false - - if(message.data.hasOwnProperty("CREATE")) { - this.channel = new Channel(this, message.data.options); - - message.data.options.playingFileName = Settings.CHANNEL_PLAY_RECORDING; - - if(message.data.options.playingFileName) { - var self = this; - setTimeout(function() { - console.log(message.data.options.playingFileName); - self.play(message.data.options.playingFileName); - }, 2000); // giving channel time to set everything up - } - - if(Settings.CHANNEL_RECORD_SESSION) { - - this.recordingFileName = Settings.CHANNEL_RECORDING_PATH + - this.channel.name + - "-" + - (new Date()).toISOString() + - "-" + - message.data.options.levelUids.join("_") + - ".log"; - - if(!fs.existsSync(Settings.CHANNEL_RECORDING_PATH)) { - fs.mkdirSync(Settings.CHANNEL_RECORDING_PATH); - } - - setInterval(this.recordWorldUpdate.bind(this), 1000); - console.checkpoint("Started recording to: " + this.recordingFileName); - } - - } else if (message.data.hasOwnProperty("KILL")) { - this.channel.destroy(); - } else { - this.onMessage(message); - - if(Settings.CHANNEL_RECORD_SESSION && this.channel && this.channel.name) { - var m = JSON.stringify(message); - var timestamp = Date.now(); - var line = "m" + timestamp + m + "\n"; - - fs.appendFile(this.recordingFileName, line, function (err) { - if (err) throw err; - }); - } - } - - }; - PipeToServer.prototype.send = function (recipient, data) { var message = { recipient: recipient, data: data - }; + } this.process.send(message); }; PipeToServer.prototype.onMessage = function (message) { switch(message.recipient) { - case "channel": - nc.trigger(nc.ns.channel.events.controlCommand.channel, message); + case 'channel': + Nc.trigger(Nc.ns.channel.events.controlCommand.channel, message); break; default: - nc.trigger(nc.ns.channel.events.controlCommand.user + message.recipient, message); + Nc.trigger(Nc.ns.channel.events.controlCommand.user + message.recipient, message); break; } - }; - - PipeToServer.prototype.play = function(playingFileName) { - var self = this; - var data = fs.readFileSync(Settings.CHANNEL_RECORDING_PATH + playingFileName); - var lines = data.toString().split("\n"); - var start = 0; - for (var i = 0; i < lines.length; i++) { - // bind message variable - (function() { - var line = lines[i]; - if(line.length > 0) { - var type = line.substring(0, 1); - var time = parseInt(line.substring(1, Date.now().toString().length + 1), 10); - if(i === 0) { - start = time; - } - time -= start; - - var jsonString = line.substring(Date.now().toString().length + 1); - var message = JSON.parse(jsonString); - - setTimeout(function() { - console.log(line); - - if(type == "m") { - self.onProcessMessage(message, null); - } else if(type == "w") { - if(self.channel.gameController) { - self.channel.gameController.onWorldUpdate(message); - } - } - }, time); - } - })(); - } - }; - - PipeToServer.prototype.recordWorldUpdate = function() { - if(this.channel.gameController) { - var update = this.channel.gameController.getWorldUpdateObject(true); - var worldUpdate = JSON.stringify(update); - var timestamp = Date.now(); - var line = "w" + timestamp + worldUpdate + "\n"; - - fs.appendFile(this.recordingFileName, line, function (err) { - if (err) throw err; - }); - } - }; + } PipeToServer.prototype.destroy = function() { - this.send("coordinator", {destroy:this.channel.name}); + this.send('coordinator', {destroy:this.channel.name}); this.process.exit(0); }; diff --git a/app/Game/Channel/Player.js b/app/Game/Channel/Player.js index 7c32014..00f806a 100755 --- a/app/Game/Channel/Player.js +++ b/app/Game/Channel/Player.js @@ -1,22 +1,17 @@ define([ "Game/Core/Player", - "Lib/Utilities/NotificationCenter", - "Game/Channel/Control/PlayerController" + "Lib/Utilities/NotificationCenter" ], -function (Parent, nc, PlayerController) { - - "use strict"; +function (Parent, Nc) { - function Player(id, physicsEngine, user, revealedGameController) { - Parent.call(this, id, physicsEngine, user, revealedGameController); - - this.playerController = new PlayerController(this); + function Player(id, physicsEngine, user) { + Parent.call(this, id, physicsEngine, user); } Player.prototype = Object.create(Parent.prototype); - Player.prototype.handActionRequest = function(options) { + Player.prototype.handActionRequest = function(x, y) { if(!this.doll) return false; var item = null; @@ -25,26 +20,30 @@ function (Parent, nc, PlayerController) { if (isHolding) { item = this.holdingItem; } else { - item = this.doll.findCloseItem(options.x); + item = this.doll.findCloseItem(x, y); } if(item) { - this.handAction(options, isHolding, item); + this.handAction(x, y, isHolding, item); } - }; + } - Player.prototype.handAction = function(options, isHolding, item) { + Player.prototype.handAction = function(x, y, isHolding, item) { - options.playerId = this.id; - options.itemUid = item.uid; + var options = { + playerId: this.id, + itemUid: item.uid + } if (isHolding) { // throw if(item.isReleasingAllowed()) { - this.throw(options, item); + this.throw(x, y, item); options.action = "throw"; - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); + options.x = x; + options.y = y; + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); } } else { // grab @@ -52,34 +51,26 @@ function (Parent, nc, PlayerController) { this.grab(item); options.action = "grab"; - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "handActionResponse", options); } } }; Player.prototype.suicide = function() { - if(this.isSpawned()) { - this.addDamage(100, this, null); - } + this.addDamage(100, this); }; - Player.prototype.addDamage = function(damage, enemy, byItem) { - - // Prevent stats change (kills) after round has ended - if (this.revealedGameController.isInBetweenRounds()) { - return; - } - + Player.prototype.addDamage = function(damage, enemy) { this.stats.health -= damage; if(this.stats.health < 0) this.stats.health = 0; - + if(this.stats.health <= 0) { if(enemy != this) enemy.score(); - this.kill(enemy, byItem); + this.kill(enemy); + } else { + this.broadcastStats(); } - - this.broadcastStats(enemy); }; Player.prototype.spawn = function(x, y) { @@ -88,19 +79,19 @@ function (Parent, nc, PlayerController) { this.broadcastStats(); }; - Player.prototype.kill = function(killedByPlayer, byItem) { + Player.prototype.kill = function(killedByPlayer) { this.stats.deaths++; var ragDollId = this.stats.deaths; Parent.prototype.kill.call(this, killedByPlayer, ragDollId); - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "playerKill", { + this.broadcastStats(); + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "playerKill", { playerId: this.id, killedByPlayerId: killedByPlayer.id, - ragDollId: ragDollId, - item: byItem ? byItem.options.name : "Suicide" + ragDollId: ragDollId }); - nc.trigger(nc.ns.channel.events.game.player.killed, this, killedByPlayer); // sends endround + Nc.trigger(Nc.ns.channel.events.game.player.killed, this, killedByPlayer); // sends endround if(this.ragDoll) { this.ragDoll.delayedDestroy(); @@ -109,21 +100,17 @@ function (Parent, nc, PlayerController) { Player.prototype.score = function() { this.stats.score++; + this.broadcastStats(); }; - Player.prototype.broadcastStats = function(enemy) { - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", { + Player.prototype.broadcastStats = function() { + Nc.trigger(Nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", { playerId: this.id, stats: this.stats }); - - if(enemy && enemy != this) { - nc.trigger(nc.ns.channel.to.client.gameCommand.broadcast, "updateStats", { - playerId: enemy.id, - stats: enemy.stats - }); - } }; + + return Player; diff --git a/app/Game/Channel/User.js b/app/Game/Channel/User.js index fe8b56e..1bc4b60 100755 --- a/app/Game/Channel/User.js +++ b/app/Game/Channel/User.js @@ -5,7 +5,7 @@ define([ "Lib/Utilities/Protocol/Parser", ], -function(Parent, nc, ProtocolHelper, ProtocolParser) { +function(Parent, Nc, ProtocolHelper, ProtocolParser) { function User(id, options) { Parent.call(this, id, options); @@ -14,15 +14,15 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) { this.isReady = false; var self = this; - nc.on(nc.ns.channel.to.client.user.controlCommand.joinSuccess + this.id, function(options) { + Nc.on(Nc.ns.channel.to.client.user.controlCommand.joinSuccess + this.id, function(options) { self.sendControlCommand("joinSuccess", options); }); - nc.on(nc.ns.channel.events.controlCommand.user + this.id, function(message) { + Nc.on(Nc.ns.channel.events.controlCommand.user + this.id, function(message) { ProtocolHelper.applyCommand(message.data, self); }); - nc.on(nc.ns.channel.to.client.user.gameCommand.send + this.id, function(command, options) { + Nc.on(Nc.ns.channel.to.client.user.gameCommand.send + this.id, function(command, options) { self.sendGameCommand(command, options); }); @@ -44,10 +44,10 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) { } // FIXME: move this to Protocol helper as a function if(command.hasOwnProperty("resetLevel")) { - nc.trigger(nc.ns.channel.events.user.level.reset, this.id); + Nc.trigger(Nc.ns.channel.events.user.level.reset, this.id); } else if(command.hasOwnProperty("clientReady")) { this.isReady = true; - nc.trigger(nc.ns.channel.events.user.client.ready, this.id); + Nc.trigger(Nc.ns.channel.events.user.client.ready, this.id); } else { this.player.playerController.applyCommand(command); } @@ -61,17 +61,7 @@ function(Parent, nc, ProtocolHelper, ProtocolParser) { var recipient = this.id; var data = ProtocolHelper.encodeCommand(command, options); - /** - * Listen for beginRound control command - * to set client to be unready again - * so it can load its new level without getting - * any gameCommands like worldUpdate - */ - if(command == "beginRound") { - this.isReady = false; - } - - nc.trigger(nc.ns.channel.to.server.controlCommand.send, recipient, data); + Nc.trigger(Nc.ns.channel.to.server.controlCommand.send, recipient, data); }; User.prototype.sendGameCommand = function(command, options) { diff --git a/app/Game/Client/AudioPlayer.js b/app/Game/Client/AudioPlayer.js deleted file mode 100644 index 851cbbb..0000000 --- a/app/Game/Client/AudioPlayer.js +++ /dev/null @@ -1,38 +0,0 @@ -define([ -], - -function () { - - "use strict"; - - function AudioPlayer(path) { - this.audio = new Audio(path); - this.audio.loop = true; - this.audio.volume = 0.1; - - this.audio.addEventListener('timeupdate', function(){ - var buffer = 1 - if(this.currentTime > this.duration - buffer) { - this.currentTime = 1 - this.play() - } - }, false); - } - - AudioPlayer.prototype.play = function() { - //this.audio.play(); - //this.doPlay = true; - } - - AudioPlayer.prototype.stop = function() { - //this.audio.stop(); - //this.doPlay = false; - }; - - AudioPlayer.prototype.destroy = function() { - this.stop(); - }; - - return AudioPlayer; - -}); \ No newline at end of file diff --git a/app/Game/Client/Collision/Detector.js b/app/Game/Client/Collision/Detector.js index ab540f2..20e16a4 100755 --- a/app/Game/Client/Collision/Detector.js +++ b/app/Game/Client/Collision/Detector.js @@ -4,8 +4,6 @@ define([ function (Parent) { - "use strict"; - function Detector () { Parent.call(this); } diff --git a/app/Game/Client/Control/Input.js b/app/Game/Client/Control/Input.js deleted file mode 100755 index b163541..0000000 --- a/app/Game/Client/Control/Input.js +++ /dev/null @@ -1,21 +0,0 @@ -define([ - "Lib/Utilities/NotificationCenter" -], - -function (nc) { - - function Input(playerController) { - this.playerController = playerController; - this.x = null; - this.y = null - } - - Input.prototype.onXyChange = function(x, y) { - this.x = x; - this.y = y; - this.playerController.setXY(this.x, this.y); - } - - return Input; - -}); \ No newline at end of file diff --git a/app/Game/Client/Control/Inputs/Gamepad.js b/app/Game/Client/Control/Input/GamepadInput.js similarity index 90% rename from app/Game/Client/Control/Inputs/Gamepad.js rename to app/Game/Client/Control/Input/GamepadInput.js index 9b10803..9ddef91 100644 --- a/app/Game/Client/Control/Inputs/Gamepad.js +++ b/app/Game/Client/Control/Input/GamepadInput.js @@ -1,11 +1,10 @@ define([ - "Game/Client/Control/Input", - "Game/Config/Settings" + "Game/Client/Control/Input/XyInput", + "Game/Config/Settings", + "Lib/Utilities/NotificationCenter" ], -function (Parent, Settings) { - - "use strict"; +function (Parent, Settings, Nc) { function GamepadInput(playerController) { this.playerController = playerController; @@ -37,7 +36,7 @@ function (Parent, Settings) { var y = -this.gamepad.axes[3]; // Looking direction - this.onXyChange(x, y); + this.playerController.xyInput.onXyChange(x, y); // Pointer finger holding item var holdingPressure = this.gamepad.axes[5]; diff --git a/app/Game/Client/Control/Input/MouseInput.js b/app/Game/Client/Control/Input/MouseInput.js new file mode 100755 index 0000000..ee66551 --- /dev/null +++ b/app/Game/Client/Control/Input/MouseInput.js @@ -0,0 +1,47 @@ +define([ + "Game/Client/Control/Input/XyInput", + "Game/Client/View/DomController", + "Game/Config/Settings", + "Lib/Utilities/NotificationCenter" +], + +function (Parent, DomController, Settings, Nc) { + + function MouseInput() { + Parent.call(this); + + this.init(); + } + + MouseInput.prototype = Object.create(Parent.prototype); + + MouseInput.prototype.init = function() { + + var canvas = null; + var self = this; + canvas = DomController.getCanvas(); + + canvas.onmousemove = function(e){ + + // -1 +1 +1 +1 xy scaling should + // -1 -1 +1 -1 be like this + + var x = (((e.clientX - this.offsetLeft) / Settings.STAGE_WIDTH) * 2) - 1; + var y = (((Settings.STAGE_HEIGHT - (e.clientY - this.offsetTop)) / Settings.STAGE_HEIGHT) * 2) -1; + + self.onXyChange(x, y); + } + + canvas.onmousedown = function(e) { + + var x = (((e.clientX - this.offsetLeft) / Settings.STAGE_WIDTH) * 2) - 1; + var y = (((Settings.STAGE_HEIGHT - (e.clientY - this.offsetTop)) / Settings.STAGE_HEIGHT) * 2) -1; + + Nc.trigger(Nc.ns.client.input.handAction.request, x, y); + } + }; + + + return MouseInput; + +}); diff --git a/app/Game/Client/Control/Input/XyInput.js b/app/Game/Client/Control/Input/XyInput.js new file mode 100755 index 0000000..47864d4 --- /dev/null +++ b/app/Game/Client/Control/Input/XyInput.js @@ -0,0 +1,20 @@ +define([ + "Lib/Utilities/NotificationCenter" +], + +function (Nc) { + + function XyInput() { + this.x = null; + this.y = null + } + + XyInput.prototype.onXyChange = function(x, y) { + this.x = x; + this.y = y; + Nc.trigger(Nc.ns.client.input.xy.change, x, y); + } + + return XyInput; + +}); \ No newline at end of file diff --git a/app/Game/Client/Control/Inputs/KeyboardAndMouse.js b/app/Game/Client/Control/Inputs/KeyboardAndMouse.js deleted file mode 100644 index 50af8a1..0000000 --- a/app/Game/Client/Control/Inputs/KeyboardAndMouse.js +++ /dev/null @@ -1,231 +0,0 @@ -define([ - "Game/Client/Control/Input", - "Game/Client/Control/KeyboardInput", - "Game/Client/View/DomController", - "Game/Config/Settings", - "Game/Client/Control/Swiper" -], - -function (Parent, KeyboardInput, domController, Settings, Swiper) { - - "use strict"; - - function KeyboardAndMouse(playerController) { - Parent.call(this); - - this.x = 0; - this.y = 0; - this.mousePosition = {x:0,y:0}; - this.modifier = false; - this.swiper = null; - this.lastLookDirection = 1; - - this.keys = { - w:87, - a:65, - s:83, - d:68, - - f:70, - g:71, - k:75, - - up: 38, - left: 37, - down: 40, - right: 39, - - space: 32, - tab: 9, - shift: 16, - - plus: 187, - plusfx: 171, - minus: 189, - minusfx: 173, - zero: 48 - }; - - this.playerController = playerController; - this.keyboardInit(); - this.mouseInit(); - } - - KeyboardAndMouse.prototype = Object.create(Parent.prototype); - - KeyboardAndMouse.prototype.keyboardInit = function() { - - this.keyboardInput = new KeyboardInput(); - var self = this; - - function bind2Pc(methodName) { - return self.playerController[methodName].bind(self.playerController); - } - - this.keyboardInput.registerKey(this.keys.a, this.moveLeft.bind(this), this.stop.bind(this)); - this.keyboardInput.registerKey(this.keys.left, this.moveLeft.bind(this), this.stop.bind(this)); - this.keyboardInput.registerKey(this.keys.d, this.moveRight.bind(this), this.stop.bind(this)); - this.keyboardInput.registerKey(this.keys.right, this.moveRight.bind(this), this.stop.bind(this)); - this.keyboardInput.registerKey(this.keys.w, bind2Pc('jump'), bind2Pc('jumpStop')); - this.keyboardInput.registerKey(this.keys.up, bind2Pc('jump'), bind2Pc('jumpStop')); - this.keyboardInput.registerKey(this.keys.space, bind2Pc('jump'), bind2Pc('jumpStop')); - this.keyboardInput.registerKey(this.keys.plus, bind2Pc('zoomIn')); - this.keyboardInput.registerKey(this.keys.plusfx, bind2Pc('zoomIn')); - this.keyboardInput.registerKey(this.keys.minus, bind2Pc('zoomOut')); - this.keyboardInput.registerKey(this.keys.minusfx, bind2Pc('zoomOut')); - this.keyboardInput.registerKey(this.keys.zero, bind2Pc('zoomReset')); - this.keyboardInput.registerKey(this.keys.tab, bind2Pc('showInfo'), bind2Pc('hideInfo')); - this.keyboardInput.registerKey(this.keys.k, bind2Pc('suicide')); - - this.keyboardInput.registerKey( - this.keys.shift, - this.activateModifier.bind(this), - this.deactivateModifier.bind(this) - ); - }; - - KeyboardAndMouse.prototype.moveLeft = function() { - if (!this.modifier) { - this.lastLookDirection = -1; - this.onXyChange(this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD, 0); - } - this.playerController.moveLeft(); - }; - - KeyboardAndMouse.prototype.moveRight = function() { - if (!this.modifier) { - this.lastLookDirection = 1; - this.onXyChange(this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD, 0); - } - this.playerController.moveRight(); - }; - - KeyboardAndMouse.prototype.stop = function(e) { - - var isMovingLeft = this.keyboardInput.getKeyByKeyCode(this.keys.a).getActive() - || this.keyboardInput.getKeyByKeyCode(this.keys.left).getActive(); - - var isMovingRight = this.keyboardInput.getKeyByKeyCode(this.keys.d).getActive() - || this.keyboardInput.getKeyByKeyCode(this.keys.right).getActive(); - - if (isMovingLeft) { - this.moveLeft(); - return; - } - - if (isMovingRight) { - this.moveRight(); - return; - } - - this.playerController.stop(); - }; - - KeyboardAndMouse.prototype.mouseInit = function() { - var canvas = domController.getCanvas(); - var self = this; - - canvas.onmousedown = function(e) { - self.mousePosition = {x:0,y:0}; - - if(!self.playerController.player.isHoldingSomething()) { - var options = { - x: self.x, - y: self.y, - av: 0 - }; - self.playerController.handActionRequest(options); - } else { - self.swiper = new Swiper(); - - self.draw({ - movementX: 0, - movementY: 0 - }); - } - } - - canvas.onmousemove = function(e) { - if (self.swiper) { - self.draw(e); - } else if(self.modifier) { - self.updateViewport(e); - } - } - - canvas.onmouseup = function(e) { - if(self.swiper) { - var options = self.swiper.swipeEnd(e.x, e.y); - self.playerController.handActionRequest(options); - self.swiper = null; - } - } - }; - - KeyboardAndMouse.prototype.updateViewport = function(e) { - // -1 +1 +1 +1 xy scaling should - // -1 -1 +1 -1 be like this - - var movementX = e.movementX || - e.mozMovementX || - e.webkitMovementX || - 0; - - var movementY = e.movementY || - e.mozMovementY || - e.webkitMovementY || - 0; - - this.x += movementX / Settings.VIEWPORT_SPEED_FACTOR; - if(this.x > 1) { - this.x = 1; - } - if(this.x < -1) { - this.x = -1; - }; - - this.y -= movementY / Settings.VIEWPORT_SPEED_FACTOR; - if(this.y > 1) { - this.y = 1; - } - if(this.y < -1) { - this.y = -1; - } - - this.lastLookDirection = this.x >= 0 ? 1 : -1; - - this.onXyChange(this.x, this.y); - }; - - KeyboardAndMouse.prototype.draw = function(e) { - var movementX = e.movementX || - e.mozMovementX || - e.webkitMovementX || - 0; - - var movementY = e.movementY || - e.mozMovementY || - e.webkitMovementY || - 0; - - this.mousePosition.x += movementX; - this.mousePosition.y += movementY; - - this.swiper.swipe(this.mousePosition.x, -this.mousePosition.y); - }; - - KeyboardAndMouse.prototype.activateModifier = function() { - this.modifier = true; - this.playerController.activateModifier(); - }; - - KeyboardAndMouse.prototype.deactivateModifier = function() { - this.modifier = false; - this.x = this.lastLookDirection * Settings.VIEWPORT_LOOK_AHEAD; - this.y = 0; - this.onXyChange(this.x, this.y); - this.playerController.deactivateModifier(); - }; - return KeyboardAndMouse; - -}); \ No newline at end of file diff --git a/app/Game/Client/Control/Key.js b/app/Game/Client/Control/Key.js index 724ea3d..2377406 100755 --- a/app/Game/Client/Control/Key.js +++ b/app/Game/Client/Control/Key.js @@ -1,9 +1,4 @@ -define([ -], - -function () { - - "use strict"; + define(function () { function Key () { this._active = false; diff --git a/app/Game/Client/Control/KeyboardInput.js b/app/Game/Client/Control/KeyboardInput.js index 3c95baf..665d1aa 100755 --- a/app/Game/Client/Control/KeyboardInput.js +++ b/app/Game/Client/Control/KeyboardInput.js @@ -4,47 +4,50 @@ define([ function (Key) { - function KeyboardInput () { - this.registry = {}; + function KeyboardInput (playerController) { + + this._registry = {}; + this._playerController = playerController; + this.init(); } KeyboardInput.prototype.init = function () { // Using window is ok here because it only runs in the browser - window.onkeydown = this.onKeyDown.bind(this); - window.onkeyup = this.onKeyUp.bind(this); + window.onkeydown = this._onKeyDown.bind(this); + window.onkeyup = this._onKeyUp.bind(this); } KeyboardInput.prototype.registerKey = function (keyCode, onKeyDown, onKeyUp) { var key = new Key(); if(onKeyDown) key.setKeyDownFunction(onKeyDown); if(onKeyUp) key.setKeyUpFunction(onKeyUp); - this.registry[keyCode] = key; + this._registry[keyCode] = key; } - KeyboardInput.prototype.getKeyByKeyCode = function (keyCode) { - return this.registry[keyCode]; + KeyboardInput.prototype._getKeyByKeyCode = function (keyCode) { + return this._registry[keyCode]; } - KeyboardInput.prototype.onKeyDown = function (e) { - var key = this.getKeyByKeyCode(e.keyCode); + KeyboardInput.prototype._onKeyDown = function (e) { + var key = this._getKeyByKeyCode(e.keyCode); if (key && !key.getActive()) { var callback = key.getKeyDownFunction(); + if(callback) this._playerController[callback](); key.setActive(true); - if(callback) callback(); } // Prevent tab from changing focus if(e.keyCode == 9) return false; } - KeyboardInput.prototype.onKeyUp = function (e) { - var key = this.getKeyByKeyCode(e.keyCode); + KeyboardInput.prototype._onKeyUp = function (e) { + var key = this._getKeyByKeyCode(e.keyCode); if (key && key.getActive()) { var callback = key.getKeyUpFunction(); + if(callback) this._playerController[callback](); key.setActive(false); - if(callback) callback(); } // Prevent tab from changing focus diff --git a/app/Game/Client/Control/PlayerController.js b/app/Game/Client/Control/PlayerController.js index 82db175..2125dfa 100755 --- a/app/Game/Client/Control/PlayerController.js +++ b/app/Game/Client/Control/PlayerController.js @@ -1,124 +1,137 @@ define([ "Game/Core/Control/PlayerController", + "Game/Client/Control/KeyboardInput", + "Game/Client/Control/Input/MouseInput", "Lib/Utilities/NotificationCenter", - "Game/Client/Control/Inputs/KeyboardAndMouse", - "Game/Client/Control/Inputs/Gamepad", - "Game/Client/PointerLockManager" + "Game/Client/Control/Input/GamepadInput", ], -function (Parent, nc, KeyboardAndMouse, Gamepad, pointerLockManager) { - - "use strict"; +function (Parent, KeyboardInput, MouseInput, Nc, GamepadInput) { function PlayerController (me) { Parent.call(this, me); - this.keyboardAndMouse = new KeyboardAndMouse(this); - this.gamepad = new Gamepad(this); + this.keyboardInput = new KeyboardInput(this); + this.xyInput = new MouseInput(this); + this.gamepadInput = new GamepadInput(this); + + this.ncTokens = [ + Nc.on(Nc.ns.client.input.xy.change, this.setXY, this), + Nc.on(Nc.ns.client.input.handAction.request, this.handActionRequest, this) + ]; + + var keys = { + w:87, + a:65, + s:83, + d:68, + + f:70, + g:71, + k:75, + + up: 38, + left: 37, + down: 40, + right: 39, + + space: 32, + + tab: 9 + } + + this.init(keys); } PlayerController.prototype = Object.create(Parent.prototype); PlayerController.prototype.update = function() { - Parent.prototype.update.call(this); - this.gamepad.update(); + this.gamepadInput.update(); }; + PlayerController.prototype.init = function (keys) { + + this.keyboardInput.registerKey(keys.a, 'moveLeft', 'stop'); + this.keyboardInput.registerKey(keys.left, 'moveLeft', 'stop'); + + this.keyboardInput.registerKey(keys.d, 'moveRight', 'stop'); + this.keyboardInput.registerKey(keys.right, 'moveRight', 'stop'); + + this.keyboardInput.registerKey(keys.w, 'jump', 'jumpStop'); + this.keyboardInput.registerKey(keys.up, 'jump', 'jumpStop'); + this.keyboardInput.registerKey(keys.space, 'jump', 'jumpStop'); + + this.keyboardInput.registerKey(keys.tab, 'showInfo', 'hideInfo'); + + this.keyboardInput.registerKey(keys.f, 'handActionLeft'); + this.keyboardInput.registerKey(keys.g, 'handActionRight'); + + this.keyboardInput.registerKey(keys.k, 'suicide'); + } + PlayerController.prototype.moveLeft = function () { - if (!this.isPlayerInputAllowed()) return; Parent.prototype.moveLeft.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveLeft'); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveLeft'); } PlayerController.prototype.moveRight = function () { - if (!this.isPlayerInputAllowed()) return; Parent.prototype.moveRight.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'moveRight'); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'moveRight'); } - // always allow to stop, to prevent endless running PlayerController.prototype.stop = function () { Parent.prototype.stop.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'stop'); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'stop'); } PlayerController.prototype.jump = function () { - if (!this.isPlayerInputAllowed()) return; Parent.prototype.jump.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jump'); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jump'); } - // always allow to stop. PlayerController.prototype.jumpStop = function () { Parent.prototype.jumpStop.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'jumpStop'); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'jumpStop'); } PlayerController.prototype.setXY = function(x, y) { - if (!this.isPlayerInputAllowed()) return; var options = {x:x, y:y}; Parent.prototype.lookAt.call(this, options); - nc.trigger(nc.ns.client.to.server.gameCommand.send, 'lookAt', options); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, 'lookAt', options); + }; + + PlayerController.prototype.handActionLeft = function() { + this.handActionRequest(-0.5, 0.5); + }; + + PlayerController.prototype.handActionRight = function() { + this.handActionRequest(0.5, 0.5); }; PlayerController.prototype.suicide = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.to.server.gameCommand.send, "suicide"); + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "suicide"); }; - PlayerController.prototype.handActionRequest = function(options) { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.to.server.gameCommand.send, "handActionRequest", options); + PlayerController.prototype.handActionRequest = function(x, y) { + var options = {x:x, y:y}; + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "handActionRequest", options); }; PlayerController.prototype.showInfo = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.game.gameStats.toggle, true); + Nc.trigger(Nc.ns.client.game.gameInfo.toggle, true); }; PlayerController.prototype.hideInfo = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.game.gameStats.toggle, false); + Nc.trigger(Nc.ns.client.game.gameInfo.toggle, false); }; - PlayerController.prototype.zoomIn = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.game.zoomIn, true); + PlayerController.prototype.destroy = function() { + Nc.offAll(this.ncTokens); + Parent.prototype.destroy.call(this); }; - PlayerController.prototype.zoomOut = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.game.zoomOut, false); - }; - PlayerController.prototype.zoomReset = function() { - if (!this.isPlayerInputAllowed()) return; - nc.trigger(nc.ns.client.game.zoomReset, false); - }; - - PlayerController.prototype.activateModifier = function() { - if (!this.isPlayerInputAllowed()) return; - Parent.prototype.activateModifier.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, "activateModifier"); - }; - - PlayerController.prototype.deactivateModifier = function() { - if (!this.isPlayerInputAllowed()) return; - Parent.prototype.deactivateModifier.call(this); - nc.trigger(nc.ns.client.to.server.gameCommand.send, "deactivateModifier"); - }; - - /* - * Client overwrite - allow player input if PointerLock is locked to canvas - * and is not in between games - */ - PlayerController.prototype.isPlayerInputAllowed = function() { - return pointerLockManager.isLocked() - && Parent.prototype.isPlayerInputAllowed.call(this); - }; - - return PlayerController; }); \ No newline at end of file diff --git a/app/Game/Client/Control/Swiper.js b/app/Game/Client/Control/Swiper.js deleted file mode 100644 index 7e0909f..0000000 --- a/app/Game/Client/Control/Swiper.js +++ /dev/null @@ -1,175 +0,0 @@ -define([ - "Lib/Utilities/NotificationCenter", -], - -function (nc) { - - var MAX_LENGTH = 200; - var MIN_LENGTH = 5; - - function Swiper() { - this.points = []; - this.angleSum = 0; - this.lengthSum = 0; - this.finished = false; - } - - Swiper.prototype.swipe = function(x, y) { - - if(this.finished) return; - - var points = this.points; - - // Check if swipe is long enough to count - if(points.length >= 1) { - var lastPoint = points[points.length-1]; - var a = Math.abs(x) - Math.abs(lastPoint.x); - var b = Math.abs(y) - Math.abs(lastPoint.y); - var currentLength = Math.sqrt(a * a + b * b); // Pythagoras -> hypotenuse - - if(currentLength < MIN_LENGTH) return; - } - - points.push({x:x, y:y}); - - if(points.length >= 2) { - - this.updateLengthSum(currentLength); - - if(this.points.length >= 3) { - this.updateAngleSum(currentLength); - } - } - - var i = points.length - 1; - nc.trigger(nc.ns.client.view.swiper.swipe, points[i].x, points[i].y); - } - - Swiper.prototype.updateLengthSum = function(currentLength) { - var points = this.points; - var i = points.length - 1; - - var lengthSum = this.lengthSum + Math.abs(currentLength); - if(lengthSum > MAX_LENGTH) { - - var diff = lengthSum - MAX_LENGTH; - var ratio = (currentLength - diff) / currentLength; - - // Offset triangle to origin - var x0 = points[i].x - points[i-1].x; - var y0 = points[i].y - points[i-1].y; - - // Multiply with ratio and offset back - var clippedX = x0 * ratio + points[i-1].x; - var clippedY = y0 * ratio + points[i-1].y; - - points[i].x = clippedX; - points[i].y = clippedY; - - this.finished = true; - - lengthSum = MAX_LENGTH; - } - - this.lengthSum = lengthSum; - }; - - Swiper.prototype.updateAngleSum = function(currentLength) { - - var points = this.points; - var i = points.length - 1; - - // last two lines - var vectors = [ - { - x: points[i].x - points[i-1].x, - y: points[i].y - points[i-1].y - }, - { - x: points[i-2].x - points[i-1].x, - y: points[i-2].y - points[i-1].y - } - ]; - - var yx = vectors[0].y * vectors[1].x; - var xy = vectors[0].x * vectors[1].y; - var direction = 0; - if(yx > xy) { - direction = -1; - } else if (yx < xy) { - direction = 1; - } - - var dotProduct = vectors[0].x - * vectors[1].x - + vectors[0].y - * vectors[1].y; - - var lastLength = Math.sqrt( - Math.pow(vectors[1].x, 2) - + Math.pow(vectors[1].y, 2) - ); - - var angle = 180 - (Math.acos((dotProduct / (currentLength * lastLength)) % 1) * 180 / Math.PI); - angle *= direction; - - if(!isNaN(parseFloat(angle)) && direction != 0) { - this.angleSum += angle; - } - }; - - Swiper.prototype.swipeEnd = function(x, y) { - var angularVelocity = this.angleSum; - var length = this.lengthSum; - - if (this.points.length < 1) { - return { - x: 0, - y: 0, - av: 0 - } - } - - var p0x = this.points[0].x; - var p0y = this.points[0].y; - var sumx = 0; - var sumy = 0; - - nc.trigger(nc.ns.client.view.swiper.end); - - for(var i=0, count = this.points.length; i < count; i++) { - var p = this.points[i]; - sumx += p.x - p0x; - sumy += p.y - p0y; - } - - var direction = { - x: sumx / count, - y: sumy / count - }; - - var larger = Math.abs(direction.x) > Math.abs(direction.y) ? direction.x : direction.y; - direction.x /= Math.abs(larger); - direction.y /= Math.abs(larger); - - this.angleSum = 0; - this.lengthSum = 0; - this.points = []; - this.finished = false; - - return { - x: direction.x * length / 100, - y: direction.y * length / 100, - av: angularVelocity / 100 - } - } - - Swiper.prototype.destroy = function() { - for (var i = 0; i < this.ncTokens.length; i++) { - nc.off(this.ncTokens[i]); - }; - }; - - return Swiper; - -}); \ No newline at end of file diff --git a/app/Game/Client/GameController.js b/app/Game/Client/GameController.js index 9d85885..9cb1ca6 100755 --- a/app/Game/Client/GameController.js +++ b/app/Game/Client/GameController.js @@ -11,16 +11,16 @@ define([ "Game/Client/GameObjects/Doll", "Game/Client/View/DomController", "Lib/Utilities/Protocol/Helper", - "Game/Client/Me", - "Game/Client/AudioPlayer", - "Game/Client/PointerLockManager", - "Lib/Utilities/Assert", - "Lib/Utilities/Exception" + "Game/Client/Me" ], -function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, requestAnimFrame, Settings, GameObject, Doll, domController, ProtocolHelper, Me, AudioPlayer, pointerLockManager, Assert, Exception) { +function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, Nc, requestAnimFrame, Settings, GameObject, Doll, DomController, ProtocolHelper, Me) { - "use strict"; + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } function GameController (options) { @@ -28,12 +28,11 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque this.view = ViewManager.createView(); this.me = null; this.animationRequestId = null; - this.audioPlayer = null; Parent.call(this, options); this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.game.gameStats.toggle, this.toggleGameStats, this) + Nc.on(Nc.ns.client.game.gameInfo.toggle, this.toggleInfo, this) ]); } @@ -41,52 +40,60 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque GameController.prototype.getMe = function () { return this.me; - }; + } GameController.prototype.update = function () { Parent.prototype.update.call(this); + DomController.statsBegin(); + this.animationRequestId = requestAnimFrame(this.update.bind(this)); + this.physicsEngine.update(); if(this.me) { this.me.update(); - this.mePositionStateOverride(); + this.mePositionStateUpdate(); } - nc.trigger(nc.ns.client.game.events.render); + for (var i = 0; i < this.gameObjects.animated.length; i++) { + this.gameObjects.animated[i].render(); + } this.view.render(); - domController.fpsStep(); - }; - GameController.prototype.mePositionStateOverride = function() { - if(this.me.isPositionStateOverrideNeeded()) { - nc.trigger( - nc.ns.client.to.server.gameCommand.send, - "mePositionStateOverride", - this.me.getPositionStateOverride() - ); + DomController.statsEnd(); + } + + GameController.prototype.mePositionStateUpdate = function() { + if(this.me.isPositionStateUpdateNeeded()) { + Nc.trigger(Nc.ns.client.to.server.gameCommand.send, "mePositionStateUpdate", this.me.getPositionStateUpdate()); } }; GameController.prototype.onClientReadyResponse = function(options) { - var i; + + if (options.worldUpdate) { + this.onWorldUpdate(options.worldUpdate); + } if (options.runtimeItems) { - for (i = 0; i < options.runtimeItems.length; i++) { - + for (var i = 0; i < options.runtimeItems.length; i++) { var itemDef = options.runtimeItems[i]; - if(!this.getItemByUid(itemDef.uid)) { - // When creating from synchronization we need to bring it into level format (px) - itemDef.options.x *= Settings.RATIO; - itemDef.options.y *= Settings.RATIO; - this.level.createItem(itemDef.uid, itemDef.options); - console.log("Creating runtime Item: ", itemDef.options.name, itemDef.uid) + var alreadyExists = false; + for (var i = 0; i < this.gameObjects.animated.length; i++) { + if(this.gameObjects.animated[i].uid == itemDef.uid) { + alreadyExists = true; + break; + } + }; + + if(!alreadyExists) { + var item = this.level.createItem(itemDef.uid, itemDef.options); } - } + }; } this.setMe(); @@ -94,51 +101,43 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque this.clientIsReady = true; // needs to stay before onSpawnPlayer if (options.spawnedPlayers) { - for(i = 0; i < options.spawnedPlayers.length; i++) { + for(var i = 0; i < options.spawnedPlayers.length; i++) { this.onSpawnPlayer(options.spawnedPlayers[i]); } } - - if (options.worldUpdate) { // needs to stay after onSpawnPlayer otherwise others doll will not be there - this.onWorldUpdate(options.worldUpdate); - } - - //this.audioPlayer = new AudioPlayer(Settings.AUDIO_PATH + "city.mp3"); - //this.audioPlayer.play(); }; + GameController.prototype.onWorldUpdate = function (updateData) { - /* + var body = this.physicsEngine.world.GetBodyList(); + do { + var userData = body.GetUserData(); + if (userData instanceof GameObject) { + var gameObject = userData; + if(updateData[gameObject.uid]) { + var update = updateData[gameObject.uid]; - TODO : - - remove this - - overwrite setUpdateData inside client / Me with an empty function + if (gameObject instanceof Doll) { + if(gameObject === this.me.doll) { + this.me.setLastServerPositionState(update); + if(!this.me.acceptPositionStateUpdateFromServer()) { + continue; // this is to ignore own doll updates from world update + } + } + gameObject.setActionState(update.as); + gameObject.lookAt(update.laxy.x, update.laxy.y); + } - GameController.prototype.onWorldUpdateGameObject = function(body, gameObject, update) { - if(gameObject === this.me.doll) { - this.me.setLastServerPositionState(update); - if(!this.me.acceptPositionStateUpdateFromServer()) { - return; // this is to ignore own doll updates from world update + body.SetAwake(true); + body.SetPosition(update.p); + body.SetAngle(update.a); + body.SetLinearVelocity(update.lv); + body.SetAngularVelocity(update.av); + } } - } + + } while (body = body.GetNext()); - Parent.prototype.onWorldUpdateGameObject.call(this, body, gameObject, update); - }; - */ - - GameController.prototype.onRemoveGameObject = function(options) { - - }; - - GameController.prototype.updateGameObject = function (gameObject, gameObjectUpdate) { - if(gameObject === this.me.doll) { - this.me.setLastServerPositionState(gameObjectUpdate); - if(!this.me.acceptPositionStateUpdateFromServer()) { - return; // this is to ignore own doll updates from world update - } - } - - Parent.prototype.updateGameObject.call(this, gameObject, gameObjectUpdate); } GameController.prototype.createMe = function(user) { @@ -147,8 +146,9 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque }; GameController.prototype.setMe = function() { + this.me.setPlayerController(new PlayerController(this.me)); this.view.setMe(this.me); - }; + } GameController.prototype.onGameCommand = function(message) { ProtocolHelper.applyCommand(message, this); @@ -174,35 +174,78 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque playerId: playerId }); } - }; + } GameController.prototype.onHandActionResponse = function(options) { var player = this.players[options.playerId]; - var item = this.getItemByUid(options.itemUid); + + var item = null; + for (var i = 0; i < this.gameObjects.animated.length; i++) { + var currentItem = this.gameObjects.animated[i]; + if(currentItem.uid == options.itemUid) { + item = currentItem; + break; + } + }; if(item) { if(options.action == "throw") { - player.throw(options, item); + player.throw(options.x, options.y, item); } else if(options.action == "grab") { player.grab(item); } } else { - console.warn("Item for joint can not be found locally. " + options.itemUid); + console.warn("Item for joint can not be found locally. " + options.itemUid) } }; GameController.prototype.onUpdateStats = function(options) { var player = this.players[options.playerId]; - if(!player) { - throw new Exception("No player with id: " + options.playerId); - } player.setStats(options.stats); + // FIXME: move to canvas later + if(player == this.me) { + DomController.setHealth(player.stats.health); + } + }; + + GameController.prototype.onPlayerKill = function(options) { + var player = this.players[options.playerId]; + var killedByPlayer = this.players[options.killedByPlayerId]; + player.kill(killedByPlayer, options.ragDollId); + }; + + GameController.prototype.onPositionStateReset = function(options) { + this.me.resetPositionState(options); + }; + + GameController.prototype.onRemoveGameObject = function(options) { + var object = null; + for (var i = 0; i < this.gameObjects[options.type].length; i++) { + if(this.gameObjects[options.type][i].uid == options.uid) { + object = this.gameObjects[options.type][i]; + break; + } + } + if(object) { + //this.onGameObjectRemove(options.type, object); + object.destroy(); + } else { + console.warn("GameObject for removal can not be found locally. " + options.uid); + } + }; + + GameController.prototype.loadLevel = function (path) { + Parent.prototype.loadLevel.call(this, path); + } + + GameController.prototype.toggleInfo = function(show) { + var playersArray = []; for (var key in this.players) { playersArray.push(this.players[key]); - } + }; var sortedPlayers = playersArray.sort(function(a,b) { if(a.stats.score > b.stats.score) return -1; @@ -214,66 +257,48 @@ function (Parent, Box2D, PhysicsEngine, ViewManager, PlayerController, nc, reque return 0; }); - nc.trigger(nc.ns.client.view.gameStats.update, sortedPlayers); - }; + function pad(string, max, alignLeft) { + string = string.substring(0, max - 1); - GameController.prototype.onPlayerKill = function(options) { - var player = this.players[options.playerId]; - var killedByPlayer = this.players[options.killedByPlayerId]; - player.kill(killedByPlayer, options.ragDollId); + var spaces = new Array( max - string.length + 1 ).join(" "); + if(alignLeft) { + return string + spaces; + } else { + return spaces + string; + } + } - nc.trigger(nc.ns.client.view.gameStats.kill, { - victim: { - name: player.user.options.nickname, - isMe: player === this.me - }, - killer: { - name: killedByPlayer.user.options.nickname, - isMe: killedByPlayer === this.me - }, - item: options.item - }); - }; + var string = "" + + pad("#", 2, false) + " " + + pad("Name", 12, true) + + pad("Score", 6, false) + + pad("Deaths", 7, false) + + pad("Health", 7, false) + + "\n-----------------------------------\n"; - GameController.prototype.onPositionStateReset = function(options) { - this.me.resetPositionState(options); - }; + var lines = []; + sortedPlayers.forEach(function(player, i) { + var name = player.getNickname(); + lines.push( + pad("" + (i + 1) + ".", 2, false) + " " + + pad(name, 12, true) + + pad("" + player.stats.score, 6, false) + + pad("" + player.stats.deaths, 7, false) + + pad("" + parseInt(player.stats.health, 10), 7, false) + ); + }, this); - GameController.prototype.loadLevel = function (path) { - Parent.prototype.loadLevel.call(this, path); - }; + string += lines.join("\n"); - GameController.prototype.onLevelLoaded = function () { - pointerLockManager.update(null, {start:true}); - }; - - GameController.prototype.toggleGameStats = function(show) { - nc.trigger(nc.ns.client.view.gameStats.toggle, show); - }; - - GameController.prototype.beginRound = function() { - this.me.setInBetweenRounds(false); - }; - - GameController.prototype.endRound = function() { - this.me.setInBetweenRounds(true); - this.toggleGameStats(true); + this.view.toggleInfo(show, string); }; GameController.prototype.destroy = function() { - if (!window.cancelAnimationFrame) { - window.cancelAnimationFrame = function(id) { - clearTimeout(id); - }; - } - cancelAnimationFrame(this.animationRequestId); Parent.prototype.destroy.call(this); - //this.audioPlayer.destroy(); - this.view.destroy(); }; diff --git a/app/Game/Client/GameObjects/Doll.js b/app/Game/Client/GameObjects/Doll.js index a5ea6b4..7671555 100755 --- a/app/Game/Client/GameObjects/Doll.js +++ b/app/Game/Client/GameObjects/Doll.js @@ -2,17 +2,12 @@ define([ "Game/Core/GameObjects/Doll", "Game/Config/Settings", "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Exception", - "Lib/Utilities/ColorConverter", - "Game/Client/View/Abstract/Layer", + "Lib/Utilities/Exception" ], -function (Parent, Settings, nc, Exception, ColorConverter, Layer) { - - "use strict"; +function (Parent, Settings, Nc, Exception) { - function Doll(physicsEngine, uid, player) { - this.layerId = Layer.ID.SPAWN; + function Doll(physicsEngine, uid, player) { this.animationDef = { "stand": [1,1], "walk": [2,28], @@ -25,71 +20,31 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) { "run": [104,126] } - this.lastStep = Date.now(); - - this.animatedMeshesContainer = { - withArms: {}, - withoutArms: {} - }; - this.animatedMeshes = this.animatedMeshesContainer.withArms; + this.animatedMeshes = {}; this.headMesh = null; - this.holdingArmMesh = null; - - var converter = new ColorConverter(); - this.primaryColor = converter.getColorByName(player.getNickname()); Parent.call(this, physicsEngine, uid, player); } Doll.prototype = Object.create(Parent.prototype); - Doll.prototype.setActionState = function(state, force) { + Doll.prototype.setActionState = function(state) { - if(!force && this.actionState == state) return; + if(this.actionState == state) return; if(!state) throw new Exception("action state is undefined"); if(this.animatedMeshes[this.actionState]) { - nc.trigger( - nc.ns.client.view.mesh.update, - this.layerId, - this.animatedMeshesContainer.withArms[this.actionState], - { visible: false } - ); - nc.trigger( - nc.ns.client.view.mesh.update, - this.layerId, - this.animatedMeshesContainer.withoutArms[this.actionState], - { visible: false } - ); + Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[this.actionState], { visible: false }); } Parent.prototype.setActionState.call(this, state); - nc.trigger( - nc.ns.client.view.mesh.update, - this.layerId, - this.animatedMeshes[this.actionState], - { - visible: true, - xScale: this.lookDirection - } - ); + Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[this.actionState], { visible: true }); } Doll.prototype.createMesh = function() { - var self = this; - - var setShirtColor = function (mesh) { - nc.trigger(nc.ns.client.view.mesh.addFilter, self.layerId, mesh, 'colorRangeReplace', { - minColor: 0x3b4a31, - maxColor: 0x657f54, - newColor: self.primaryColor, - brightnessOffset: 0.56 - }); - } - // Body var padF = function(n) { @@ -100,101 +55,53 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) { var self = this; - var arms = ["withArms", "withoutArms"]; - for (var j = 0; j < arms.length; j++) { - var arm = arms[j]; - for (var key in this.animationDef) { - var start = this.animationDef[key][0]; - var end = this.animationDef[key][1]; + for (var key in this.animationDef) { + var start = this.animationDef[key][0]; + var end = this.animationDef[key][1]; - var texturePaths = []; - for (var i = start; i <= end; i++) { - - /* - // Multiple File Animations - texturePaths.push( - Settings.GRAPHICS_PATH - + Settings.GRAPHICS_SUBPATH_CHARACTERS - + this.characterName - + "/Animation/" + arm.toUpperCaseFirstChar() + "/ChuckAnimations0" - + padF(i) - + ".png" - ); - */ - - // Single File Animations (animation names from chuck_sheet.json, use option fromFrame=true) - texturePaths.push( - "Chuck" + arm.toUpperCaseFirstChar() + "0" + padF(i) + ".png" - ); - } - - - var callback = function(mesh) { - self.animatedMeshesContainer[arm][key] = mesh; - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); - - setShirtColor(mesh); - }; - - nc.trigger(nc.ns.client.view.animatedMesh.create, this.layerId, texturePaths, callback, { - visible: false, - pivot: { - x: 0, - y: 40 * 4 - }, - xScale: 0.25, - yScale: 0.25, - anchor: { - x: 0.5, - y: 0 - }, - fromFrame: true - }); + var texturePaths = []; + for (var i = start; i <= end; i++) { + texturePaths.push( + Settings.GRAPHICS_PATH + + Settings.GRAPHICS_SUBPATH_CHARACTERS + + this.characterName + //+ "/Animation/WithoutArms/ChuckAnimationsWithoutArms0" + + "/Animation/WithArms/ChuckAnimations0" + + padF(i) + + ".png" + ); } - }; + var callback = function(mesh) { + self.animatedMeshes[key] = mesh; + Nc.trigger(Nc.ns.client.view.mesh.add, mesh); + }; + + Nc.trigger(Nc.ns.client.view.animatedMesh.create, texturePaths, callback, { + visible: false, + pivot: { + x: 35/2 * 4, + y: 40 * 4 + }, + width: 35, + height: 40 + }); + } // Head var texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/head.png"; var callback = function (mesh) { self.headMesh = mesh; - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); + Nc.trigger(Nc.ns.client.view.mesh.add, mesh); } - nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, { + Nc.trigger(Nc.ns.client.view.mesh.create, texturePath, callback, { pivot: { x: 5, y: 12 }, width: 10, - height: 12, - anchor: { - x: 0, - y: 0 - } - }); - - // Holding arm - - texturePath = Settings.GRAPHICS_PATH + "Characters/Chuck/holdingArm.png"; - var callback = function (mesh) { - self.holdingArmMesh = mesh; - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); - setShirtColor(mesh); - } - nc.trigger(nc.ns.client.view.mesh.create, this.layerId, texturePath, callback, { - visible: false, - pivot: { - //x: 35/2 * 4, - x: 0, - y: 40 * 4 - }, - width: 35, - height: 40, - anchor: { - x: 0.5, - y: 0 - } + height: 12 }); } @@ -206,28 +113,18 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) { if(oldLookDirection != this.lookDirection) { for(var key in this.animatedMeshes) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[key], { xScale: this.lookDirection } ); } - - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, - this.holdingArmMesh, - { - xScale: this.lookDirection - } - ); } var angle = Math.atan2(this.lookAtXY.x, this.lookAtXY.y) / 2 - 0.7855 * this.lookDirection; // 0.7855 = 45° - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.headMesh, { xScale: this.lookDirection, @@ -236,70 +133,35 @@ function (Parent, Settings, nc, Exception, ColorConverter, Layer) { ); } - Doll.prototype.grab = function(item) { - Parent.prototype.grab.call(this, item); - this.animatedMeshes = this.animatedMeshesContainer.withoutArms; - this.setActionState(this.actionState, true); - nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: true }); - }; - - Doll.prototype.throw = function(item, options) { - Parent.prototype.throw.call(this, item, options); - this.animatedMeshes = this.animatedMeshesContainer.withArms; - this.setActionState(this.actionState, true); - nc.trigger(nc.ns.client.view.mesh.update, this.layerId, this.holdingArmMesh, { visible: false }); - }; Doll.prototype.destroy = function () { for (var key in this.animatedMeshes) { - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.animatedMeshes[key]); + Nc.trigger(Nc.ns.client.view.mesh.remove, this.animatedMeshes[key]); } - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.headMesh); + Nc.trigger(Nc.ns.client.view.mesh.remove, this.headMesh); Parent.prototype.destroy.call(this); } Doll.prototype.render = function() { if(this.actionState) { - - var stepLength = (Date.now() - this.lastStep); - this.lastStep = Date.now(); - - // compare current framerate to wanted and get factor - // (stepLength / 60) * 2 - // * 2 to scale to flash fps - - var factor = stepLength / 30; - - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.animatedMeshes[this.actionState], { x: this.body.GetPosition().x * Settings.RATIO, y: this.body.GetPosition().y * Settings.RATIO, - animationSpeed: factor - //rotation: this.body.GetAngle() + rotation: this.body.GetAngle() } ); - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.headMesh, { x: this.body.GetPosition().x * Settings.RATIO, y: this.body.GetPosition().y * Settings.RATIO - this.height + this.headHeight } ) - - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, - this.holdingArmMesh, - { - x: this.body.GetPosition().x * Settings.RATIO, - y: this.body.GetPosition().y * Settings.RATIO - } - ) } } diff --git a/app/Game/Client/GameObjects/GameObject.js b/app/Game/Client/GameObjects/GameObject.js index f193bbc..577830d 100755 --- a/app/Game/Client/GameObjects/GameObject.js +++ b/app/Game/Client/GameObjects/GameObject.js @@ -4,9 +4,7 @@ define([ "Lib/Utilities/NotificationCenter" ], -function (Parent, Exception, nc) { - - "use strict"; +function (Parent, Exception, Nc) { function GameObject(physicsEngine, uid) { Parent.call(this, physicsEngine, uid); @@ -27,7 +25,7 @@ function (Parent, Exception, nc) { GameObject.prototype.createMesh = function() { throw new Exception('Abstract method GameObject.createMesh not overwritten'); }; - + return GameObject; }); \ No newline at end of file diff --git a/app/Game/Client/GameObjects/Item.js b/app/Game/Client/GameObjects/Item.js index f798416..71bc2e7 100755 --- a/app/Game/Client/GameObjects/Item.js +++ b/app/Game/Client/GameObjects/Item.js @@ -1,21 +1,13 @@ define([ "Game/Core/GameObjects/Item", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Game/Client/View/Abstract/Layer" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Settings, nc, Layer) { - - "use strict"; +function (Parent, Settings, Nc) { function Item(physicsEngine, uid, options) { - this.layerId = Layer.ID.ITEM; Parent.call(this, physicsEngine, uid, options); - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.game.events.render, this.render, this) - ]); } Item.prototype = Object.create(Parent.prototype); @@ -30,11 +22,10 @@ function (Parent, Settings, nc, Layer) { var callback = function(mesh) { self.mesh = mesh; - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); + Nc.trigger(Nc.ns.client.view.mesh.add, mesh); } - nc.trigger(nc.ns.client.view.mesh.create, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.create, texturePath, callback, { @@ -49,14 +40,13 @@ function (Parent, Settings, nc, Layer) { }; Item.prototype.destroy = function() { - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.mesh); + Nc.trigger(Nc.ns.client.view.mesh.remove, this.mesh); Parent.prototype.destroy.call(this); }; Item.prototype.render = function() { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.mesh, { x: this.body.GetPosition().x * Settings.RATIO, @@ -72,8 +62,7 @@ function (Parent, Settings, nc, Layer) { Parent.prototype.flip.call(this, direction); if(oldFlipDirection != direction) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.mesh, { xScale: direction diff --git a/app/Game/Client/GameObjects/Items/RagDoll.js b/app/Game/Client/GameObjects/Items/RagDoll.js index 73e0b83..70d4117 100644 --- a/app/Game/Client/GameObjects/Items/RagDoll.js +++ b/app/Game/Client/GameObjects/Items/RagDoll.js @@ -2,16 +2,12 @@ define([ "Game/Core/GameObjects/Items/RagDoll", "Game/Core/GameObjects/Item", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Game/Client/View/Abstract/Layer" + "Lib/Utilities/NotificationCenter" ], -function (Parent, CoreItem, Settings, nc, Layer) { - - "use strict"; +function (Parent, CoreItem, Settings, Nc) { function RagDoll(physicsEngine, uid, options) { - this.layerId = Layer.ID.SPAWN; this.limbMeshes = {}; this.baseMeshName = "chest"; this.characterName = "Chuck"; @@ -40,11 +36,10 @@ function (Parent, CoreItem, Settings, nc, Layer) { self.limbMeshes[name] = mesh; } - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); + Nc.trigger(Nc.ns.client.view.mesh.add, mesh); } - nc.trigger(nc.ns.client.view.mesh.create, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.create, texturePath + name + ".png", callback, { @@ -64,8 +59,7 @@ function (Parent, CoreItem, Settings, nc, Layer) { if(this.limbs) { for(var name in this.limbMeshes) { if(this.limbs[name]) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.limbMeshes[name], { x: this.limbs[name].GetPosition().x * Settings.RATIO, @@ -85,8 +79,7 @@ function (Parent, CoreItem, Settings, nc, Layer) { CoreItem.prototype.flip.call(this, direction); if(oldFlipDirection != direction) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.mesh, { xScale: direction @@ -94,8 +87,7 @@ function (Parent, CoreItem, Settings, nc, Layer) { ); for (var name in this.limbMeshes) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.limbMeshes[name], { xScale: direction @@ -108,7 +100,7 @@ function (Parent, CoreItem, Settings, nc, Layer) { RagDoll.prototype.destroy = function() { for (var name in this.limbMeshes) { - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.limbMeshes[name]); + Nc.trigger(Nc.ns.client.view.mesh.remove, this.limbMeshes[name]); }; Parent.prototype.destroy.call(this); diff --git a/app/Game/Client/GameObjects/Items/Rube.js b/app/Game/Client/GameObjects/Items/Rube.js new file mode 100644 index 0000000..e029668 --- /dev/null +++ b/app/Game/Client/GameObjects/Items/Rube.js @@ -0,0 +1,26 @@ +define([ + "Game/Core/GameObjects/Items/Rube" +], + +function (Parent) { + + function Rube(physicsEngine, uid, options) { + Parent.call(this, physicsEngine, uid, options); + } + + Rube.prototype = Object.create(Parent.prototype); + + Rube.prototype.createMesh = function() { + }; + + Rube.prototype.destroy = function() { + }; + + Rube.prototype.render = function() { + } + + Rube.prototype.flip = function(direction) { + }; + + return Rube; +}); \ No newline at end of file diff --git a/app/Game/Client/GameObjects/Items/RubeDoll.js b/app/Game/Client/GameObjects/Items/RubeDoll.js deleted file mode 100644 index 6c6034b..0000000 --- a/app/Game/Client/GameObjects/Items/RubeDoll.js +++ /dev/null @@ -1,254 +0,0 @@ -define([ - "Game/Core/GameObjects/Items/RubeDoll", - "Game/Client/View/Abstract/Layer", - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", -], - -function (Parent, Layer, Settings, nc) { - - "use strict"; - - function RubeDoll(physicsEngine, uid, options) { - - this.primaryColor = options.primaryColor; - - var limbOptions = {}; - - limbOptions.chest = { - width: 6, - height: 18, - x: 0, - y: 0 - }; - - limbOptions.head = { - width: 10, - height: 12, - x: 0, - y: - limbOptions.chest.height / 2 - 7 - }; - - limbOptions.upperLeftLeg = { - width: 5, - height: 8, - x: -2, - y: limbOptions.chest.height / 2 - }; - - limbOptions.upperRightLeg = { - width: 5, - height: 8, - x: 2, - y: limbOptions.chest.height / 2 - }; - - limbOptions.lowerLeftLeg = { - width: 5, - height: 4, - x: -2, - y: limbOptions.chest.height / 2 + limbOptions.upperLeftLeg.height - }; - - limbOptions.lowerRightLeg = { - width: 5, - height: 4, - x: 2, - y: limbOptions.chest.height / 2 + limbOptions.upperRightLeg.height - }; - - - - limbOptions.upperLeftArm = { - width: 4, - height: 8, - x: -2, - y: -limbOptions.chest.height / 2 - }; - - limbOptions.upperRightArm = { - width: 4, - height: 8, - x: 2, - y: -limbOptions.chest.height / 2 - }; - - limbOptions.lowerLeftArm = { - width: 4, - height: 5, - x: -2, - y: -limbOptions.chest.height / 2 + limbOptions.upperLeftArm.height - }; - - limbOptions.lowerRightArm = { - width: 4, - height: 5, - x: 2, - y: -limbOptions.chest.height / 2 + limbOptions.upperRightArm.height - }; - - this.limbOptions = limbOptions; - - this.layerId = Layer.ID.SPAWN; - this.limbMeshes = {}; - this.baseMeshName = "chest"; - this.characterName = "Chuck"; - this.lastFlipDirection = -options.direction || 1; - - Parent.call(this, physicsEngine, uid, options); - } - - RubeDoll.prototype = Object.create(Parent.prototype); - - RubeDoll.prototype.createMesh = function() { - - this.createLimbMesh("lowerRightLeg"); - this.createLimbMesh("upperRightLeg"); - this.createLimbMesh("lowerRightArm"); - this.createLimbMesh("upperRightArm"); - - this.createLimbMesh("chest"); - this.createLimbMesh("head"); - - this.createLimbMesh("lowerLeftLeg"); - this.createLimbMesh("upperLeftLeg"); - this.createLimbMesh("lowerLeftArm"); - this.createLimbMesh("upperLeftArm"); - - }; - - RubeDoll.prototype.createLimbMesh = function(name) { - var self = this; - var texturePath = Settings.GRAPHICS_PATH - + Settings.GRAPHICS_SUBPATH_CHARACTERS + "" - + this.characterName + '/'; - - - var callback = function(mesh) { - if(name == self.baseMeshName) { - self.mesh = mesh; - } - - self.limbMeshes[name] = mesh; - - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); - - // setting shirt color - nc.trigger(nc.ns.client.view.mesh.addFilter, self.layerId, mesh, "colorRangeReplace", { - minColor: 0x3b4a31, - maxColor: 0x6d855d, - newColor: self.primaryColor, - brightnessOffset: 0.56 - }); - }; - - nc.trigger(nc.ns.client.view.mesh.create, - this.layerId, - texturePath + name + ".png", - callback, - { - width: this.limbOptions[name].width, - height: this.limbOptions[name].height, - pivot: { - x: this.limbOptions[name].width / 2, - y: this.limbOptions[name].height / 2 - } - } - ); - }; - - RubeDoll.prototype.destroy = function() { - - for (var name in this.limbMeshes) { - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.limbMeshes[name]); - }; - - Parent.prototype.destroy.call(this); - }; - - RubeDoll.prototype.render = function() { - //Parent.prototype.render.call(this); - - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, - this.mesh, - { - x: this.body.GetPosition().x * Settings.RATIO, - y: this.body.GetPosition().y * Settings.RATIO, - rotation: this.body.GetAngle() - } - ); - - if(this.limbs) { - for(var name in this.limbMeshes) { - if(this.limbs[name]) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, - this.limbMeshes[name], - { - x: this.limbs[name].GetPosition().x * Settings.RATIO, - y: this.limbs[name].GetPosition().y * Settings.RATIO, - rotation: this.limbs[name].GetAngle() - } - ); - } - } - } - }; - - RubeDoll.prototype.flip = function(direction) { - - Parent.prototype.flip.call(this, direction); - - // flipping depth of right body side arm/leg images with left - if (this.lastFlipDirection != direction) { // FIXME : this is a bit broken. - - this.lastFlipDirection = direction; - - nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes, - this.layerId, - this.limbMeshes["lowerRightLeg"], - this.limbMeshes["lowerLeftLeg"] - ); - nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes, - this.layerId, - this.limbMeshes["upperRightLeg"], - this.limbMeshes["upperLeftLeg"] - ); - nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes, - this.layerId, - this.limbMeshes["lowerRightArm"], - this.limbMeshes["lowerLeftArm"] - ); - nc.trigger(nc.ns.client.view.mesh.swapMeshIndexes, - this.layerId, - this.limbMeshes["upperRightArm"], - this.limbMeshes["upperLeftArm"] - ); - - // swap short images - nc.trigger(nc.ns.client.view.mesh.swapMeshes, - this.layerId, - this.limbMeshes["upperRightLeg"], - this.limbMeshes["upperLeftLeg"] - ); - } - - // x flipping has to happen after (see swapMeshes) - if(this.limbs) { - for(var name in this.limbMeshes) { - if(this.limbs[name]) { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, - this.limbMeshes[name], - { - xScale: direction, - } - ); - } - } - } - }; - - return RubeDoll; -}); \ No newline at end of file diff --git a/app/Game/Client/GameObjects/SpectatorDoll.js b/app/Game/Client/GameObjects/SpectatorDoll.js index 4d1fbb1..faf141a 100644 --- a/app/Game/Client/GameObjects/SpectatorDoll.js +++ b/app/Game/Client/GameObjects/SpectatorDoll.js @@ -3,8 +3,6 @@ define([ ], function (Parent) { - - "use strict"; function SpectatorDoll(physicsEngine, uid) { Parent.call(this, physicsEngine, uid); diff --git a/app/Game/Client/GameObjects/Tile.js b/app/Game/Client/GameObjects/Tile.js index 1ca9984..4319c4d 100755 --- a/app/Game/Client/GameObjects/Tile.js +++ b/app/Game/Client/GameObjects/Tile.js @@ -1,16 +1,12 @@ define([ "Game/Core/GameObjects/Tile", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Game/Client/View/Abstract/Layer" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Settings, nc, Layer) { - - "use strict"; +function (Parent, Settings, Nc) { function Tile(physicsEngine, uid, options) { - this.layerId = Layer.ID.TILE; Parent.call(this, physicsEngine, uid, options); } @@ -31,11 +27,10 @@ function (Parent, Settings, nc, Layer) { var callback = function(mesh) { self.mesh = mesh; - nc.trigger(nc.ns.client.view.mesh.add, self.layerId, mesh); + Nc.trigger(Nc.ns.client.view.mesh.add, mesh); } - nc.trigger(nc.ns.client.view.mesh.create, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.create, texturePath, callback, { @@ -50,14 +45,13 @@ function (Parent, Settings, nc, Layer) { }; Tile.prototype.destroy = function() { - nc.trigger(nc.ns.client.view.mesh.remove, this.layerId, this.mesh); + Nc.trigger(Nc.ns.client.view.mesh.remove, this.mesh); Parent.prototype.destroy.call(this); }; Tile.prototype.render = function() { - nc.trigger(nc.ns.client.view.mesh.update, - this.layerId, + Nc.trigger(Nc.ns.client.view.mesh.update, this.mesh, { x: this.body.GetPosition().x * Settings.RATIO, diff --git a/app/Game/Client/Loader/Level.js b/app/Game/Client/Loader/Level.js index 832d9f0..f732196 100755 --- a/app/Game/Client/Loader/Level.js +++ b/app/Game/Client/Loader/Level.js @@ -2,20 +2,13 @@ define([ "Game/Core/Loader/Level", "Game/Config/Settings", "Lib/Utilities/NotificationCenter", - "Lib/Vendor/Pixi", - "Game/Client/View/Abstract/Layer" + "Lib/Vendor/Pixi" ], -function (Parent, Settings, nc, PIXI, AbstractLayer) { - - "use strict"; +function (Parent, Settings, Nc, PIXI) { function Level (uid, engine, gameObjects) { Parent.call(this, uid, engine, gameObjects); - this.levelSize = { - width: 0, - height: 0 - } } Level.prototype = Object.create(Parent.prototype); @@ -24,13 +17,13 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) { var self = this; var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { - if(xhr.readyState == 4) { - if(xhr.status == 200) { - self.loadAssets(JSON.parse(xhr.responseText), callback); - } else { - console.error("Ajax error: " + xhr.status + " " + xhr.statusText) + if(xhr.readyState == 4) { + if(xhr.status == 200) { + self.loadAssets(JSON.parse(xhr.responseText), callback); + } else { + console.error("Ajax error: " + xhr.status + " " + xhr.statusText) + } } - } } xhr.open("GET", path, true); xhr.send(null); @@ -46,7 +39,7 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) { loader.onComplete = function() { callback(levelData); }; loader.onProgress = function() { var progress = parseInt(100 / numPaths * ++count, 10) + 1; - nc.trigger(nc.ns.client.view.preloadBar.update, progress); + Nc.trigger(Nc.ns.client.view.preloadBar.update, progress); } loader.load(); }; @@ -62,42 +55,28 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) { return n; } - /* - // Single File Animations Preloading - var animationSets = ["WithArms", "WithoutArms"]; + var characterNames = ["Chuck"]; + var animationSets = ["WithArms"];//, "WithArms"]; var addition = ""; - for (var i = 0; i < characterNames.length; i++) { var characterName = characterNames[i]; for (var j = 1; j <= 126; j++) { for (var k = 0; k < animationSets.length; k++) { var animationSet = animationSets[k]; + addition = animationSet == "WithoutArms" ? "WithoutArms" : ""; paths.push( Settings.GRAPHICS_PATH + Settings.GRAPHICS_SUBPATH_CHARACTERS + characterName + "/Animation/" + animationSet - + "/ChuckAnimations0" + + "/ChuckAnimations" + addition + "0" + padF(j) + ".png" ); }; }; }; - */ - - var characterNames = ["Chuck"]; - var characterName = characterNames[0]; - - paths.push( - Settings.GRAPHICS_PATH - + Settings.GRAPHICS_SUBPATH_CHARACTERS - + characterName - + "/Animation/" - + "/TexturePacker" - + "/chuck_sheet.json" - ); paths.push( Settings.GRAPHICS_PATH @@ -109,24 +88,5 @@ function (Parent, Settings, nc, PIXI, AbstractLayer) { return paths; }; - Level.prototype.setupLayer = function(options, behind, referenceId) { - - Parent.prototype.setupLayer.call(this, options, behind, referenceId); - var parallaxSpeed = 0.0; // default parallax - if (options.properties && options.properties.parallaxSpeed) { - parallaxSpeed = parseFloat(options.properties.parallaxSpeed); - } - nc.trigger( - nc.ns.client.view.layer.createAndInsert, - options.layerId, - { - parallaxSpeed: parallaxSpeed, - levelSize: this.levelSize - }, - behind, - referenceId - ); - }; - return Level; }); \ No newline at end of file diff --git a/app/Game/Client/Loader/TiledLevel.js b/app/Game/Client/Loader/TiledLevel.js index df451d8..d5cff31 100644 --- a/app/Game/Client/Loader/TiledLevel.js +++ b/app/Game/Client/Loader/TiledLevel.js @@ -1,32 +1,16 @@ define([ "Game/Core/Loader/TiledLevel", - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", + "Game/Config/Settings" ], -function (Parent, Settings, nc) { - - "use strict"; +function (Parent, Settings) { - function TiledLevel(uid, engine) { - this.layerId = "background"; - Parent.call(this, uid, engine); + function TiledLevel(uid, engine, gameObjects) { + Parent.call(this, uid, engine, gameObjects); } TiledLevel.prototype = Object.create(Parent.prototype); - - TiledLevel.prototype.setup = function(levelData) { - var tilesLayerData = this.getLayer(levelData, "tiles"); - this.levelSize = { - width: tilesLayerData.width * Settings.TILE_SIZE, - height: tilesLayerData.height * Settings.TILE_SIZE - }; - - nc.trigger(nc.ns.client.view.layer.levelSizeUpdate, this.levelSize); - - Parent.prototype.setup.call(this, levelData); - }; - + TiledLevel.prototype.getAssetPaths = function(levelData) { var paths = Parent.prototype.getAssetPaths.call(this, levelData); @@ -56,100 +40,12 @@ function (Parent, Settings, nc) { paths.push(texturePath); }; - for (var i = 0; i < levelData.layers.length; i++) { - var layer = levelData.layers[i]; - if (layer.type == "imagelayer") { - paths.push(Settings.MAPS_PATH + layer.image); - } - }; + // FIXME: Get background image return paths; + } - - TiledLevel.prototype.setupLayer = function(options, behind, referenceId) { - - var self = this; - - Parent.prototype.setupLayer.call(this, options, behind, referenceId); - - // So far only one image per layer is possible because of Tiled editor - if (options.type == "imagelayer") { - - var texturePath = Settings.MAPS_PATH + options.image; - - var callback = function(mesh) { - nc.trigger(nc.ns.client.view.mesh.add, options.layerId, mesh); - nc.trigger(nc.ns.client.view.mesh.update, options.layerId, mesh, { - x: 0,//self.levelData.width * Settings.TILE_SIZE / 2, - y: 0,//self.levelData.height * Settings.TILE_SIZE / 2, - pivot: { - x: mesh.texture.width / 2, - y: mesh.texture.height / 2 - }, - xScale: 1, - yScale: 1 - }); - } - - nc.trigger(nc.ns.client.view.mesh.create, - options.layerId, - texturePath, - callback, - { - alpha: options.opacity - } - ); - } - - // Adding tiles without collision - else if (options.type == "tilelayer" && options.name != "tiles") { - this.createNonCollidingTiles(options); - } - - }; - - - TiledLevel.prototype.createNonCollidingTiles = function(options) { - - var data = options.data; - var tilesOptions = []; - for (var i = 0; i < data.length; i++) { - - var gid = data[i]; - if(gid === 0) continue; - - var imagePath = this.getTileImagePath(gid); - var parts = imagePath.split("/"); - var tileType = parts[parts.length - 1].split(".")[0].split("") - - var callback = function(mesh) { - nc.trigger(nc.ns.client.view.mesh.add, options.layerId, mesh); - } - - nc.trigger(nc.ns.client.view.mesh.create, - options.layerId, - Settings.MAPS_PATH + imagePath, - callback, - { - width: Settings.TILE_SIZE, - height: Settings.TILE_SIZE, - x: (i % options.width) * Settings.TILE_SIZE, - y: parseInt(i / options.width , 10) * Settings.TILE_SIZE, - } - ); - } - } - - TiledLevel.prototype.getLayer = function(levelData, name) { - for (var i = 0; i < levelData.layers.length; i++) { - if(levelData.layers[i].name === name) { - return levelData.layers[i]; - } - } - - throw "Layer '" + name + "' not found."; - }; - + return TiledLevel; }); \ No newline at end of file diff --git a/app/Game/Client/Me.js b/app/Game/Client/Me.js index a904c04..e0555ae 100644 --- a/app/Game/Client/Me.js +++ b/app/Game/Client/Me.js @@ -1,60 +1,28 @@ define([ "Game/Client/Player", - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert", - "Game/Client/Control/PlayerController", + "Game/Config/Settings" ], -function (Parent, Settings, nc, Assert, PlayerController) { - - "use strict"; +function (Parent, Settings) { function Me(id, physicsEngine, user) { Parent.call(this, id, physicsEngine, user); - // View uses this to calculate center position - this.lookAtXY = { - x: Settings.VIEWPORT_LOOK_AHEAD, - y: 0 - }; - this.lastServerPositionState = { p: { x: 0, y: 0 } }; - - this.arrowMesh = null; - this.createAndAddArrow(); - this.playerController = new PlayerController(this); } Me.prototype = Object.create(Parent.prototype); - - Me.prototype.lookAt = function(x, y) { - this.lookAtXY = { - x: x, - y: y - }; - - Parent.prototype.lookAt.call(this, x, y); - }; - - Me.prototype.getLookAt = function() { - return { - x: this.lookAtXY.x, - y: this.lookAtXY.y - }; - }; Me.prototype.setLastServerPositionState = function(update) { this.lastServerPositionState = update; }; - // Checks if client should send out its position to server - Me.prototype.isPositionStateOverrideNeeded = function() { + Me.prototype.isPositionStateUpdateNeeded = function() { if(!this.doll) { return false; @@ -67,20 +35,20 @@ function (Parent, Settings, nc, Assert, PlayerController) { var difference = { x: Math.abs(this.lastServerPositionState.p.x - this.doll.body.GetPosition().x), y: Math.abs(this.lastServerPositionState.p.y - this.doll.body.GetPosition().y) - }; + } - if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS || - difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) { + if(difference.x > Settings.ME_STATE_MAX_DIFFERENCE_METERS + || difference.y > Settings.ME_STATE_MAX_DIFFERENCE_METERS) { return true; } return false; }; - Me.prototype.getPositionStateOverride = function() { + Me.prototype.getPositionStateUpdate = function() { return { p: this.doll.body.GetPosition().Copy(), lv: this.doll.body.GetLinearVelocity().Copy() - }; + } }; Me.prototype.acceptPositionStateUpdateFromServer = function() { @@ -89,39 +57,10 @@ function (Parent, Settings, nc, Assert, PlayerController) { }; Me.prototype.resetPositionState = function(options) { - Assert.number(options.p.x, options.p.y); - Assert.number(options.lv.x, options.lv.y); this.doll.body.SetPosition(options.p); this.doll.body.SetLinearVelocity(options.lv); }; - Me.prototype.createAndAddArrow = function() { - var self = this; - - var position = this.getPosition(); - - var options = { - x: position.x * Settings.RATIO, - y: position.y * Settings.RATIO, - }; - - var callback = function(arrowMesh) { - self.arrowMesh = arrowMesh; - }; - nc.trigger(nc.ns.client.view.playerArrow.createAndAdd, callback, options); - }; - - Me.prototype.render = function() { - - Parent.prototype.render.call(this); - - var position = this.getPosition(); - var options = { - x: position.x * Settings.RATIO, - y: position.y * Settings.RATIO, - }; - nc.trigger(nc.ns.client.view.playerArrow.update, this.arrowMesh, options); - }; - return Me; + }); \ No newline at end of file diff --git a/app/Game/Client/Networker.js b/app/Game/Client/Networker.js index 4e27382..c45448d 100755 --- a/app/Game/Client/Networker.js +++ b/app/Game/Client/Networker.js @@ -7,14 +7,9 @@ define([ "Game/Client/View/DomController" ], -function (ProtocolHelper, GameController, User, nc, Settings, domController) { +function (ProtocolHelper, GameController, User, Nc, Settings, DomController) { - "use strict"; - - function Networker (socketLink, channelName, nickname) { - - this.channelName = channelName; - this.nickname = nickname; + function Networker (socketLink) { this.socketLink = socketLink; this.gameController = null; this.users = {}; @@ -25,47 +20,33 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { var self = this; this.socketLink.on('message', function (message) { var m = JSON.parse(message) - if(Settings.NETWORK_LOG_INCOMING) { - var shouldBeFiltered = false; - var keyword; - for (var i = 0; i < Settings.NETWORK_LOG_FILTER.length; i++) { - keyword = Settings.NETWORK_LOG_FILTER[i]; - if(message.search(keyword) != -1) { - shouldBeFiltered = true; - break; - } - }; - - if(!shouldBeFiltered) { + if (message.indexOf('worldUpdate') == -1 && message.indexOf('pong') == -1) { console.log('INCOMING', message); } + } - - ProtocolHelper.applyCommand(message, self); }); - nc.on(nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this); - nc.on(nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this); - - domController.setNick(nickname); + Nc.on(Nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this); + Nc.on(Nc.ns.core.game.events.level.loaded, this.onLevelLoaded, this); } // Socket callbacks Networker.prototype.onConnect = function () { console.log('connected.') - if(this.channelName) { + var channel = JSON.parse(localStorage["channel"]); + var player = JSON.parse(localStorage["player"]); + if(channel.name) { var options = { - channelName: this.channelName, - nickname: this.nickname + channelName: channel.name, + nickname: player.nickname } this.sendCommand('join', options); - domController.setConnected(true); } else { - alert("Error: no channel name"); window.location.href = "/"; } } @@ -74,7 +55,7 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { //if(this.gameController) this.gameController.destruct(); //this.gameController = null; console.log('disconnected. game destroyed. no auto-reconnect'); - domController.setConnected(false); + document.body.style.backgroundColor = '#aaaaaa'; } Networker.prototype.onJoinSuccess = function (options) { @@ -93,21 +74,18 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { } Networker.prototype.onJoinError = function(options) { - alert(options.message); + // alert(options.message); window.location.href = "/"; }; Networker.prototype.onLevelLoaded = function() { - /* this.gameController.createMe(this.users[this.meUserId]); for (var userId in this.users) { if(this.meUserId != userId) { this.gameController.createPlayer(this.users[userId]); } - }*/ - - this.gameController.onLevelLoaded(); + } this.sendGameCommand("clientReady"); }; @@ -129,18 +107,23 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { this.socketLink.send(message); if(Settings.NETWORK_LOG_OUTGOING) { - var shouldBeFiltered = false; - var keyword; + if(Settings.NETWORK_LOG_FILTER.length > 0) { - for (var i = 0; i < Settings.NETWORK_LOG_FILTER.length; i++) { - keyword = Settings.NETWORK_LOG_FILTER[i]; - if(message.search(keyword) != -1) { - shouldBeFiltered = true; - break; + var shouldBeFiltered = false; + var keyword; + + for (var i = 0; i < Settings.NETWORK_LOG_FILTER.length; i++) { + keyword = Settings.NETWORK_LOG_FILTER[i]; + if(message.search(keyword) != -1) { + shouldBeFiltered = true; + break; + } + }; + + if(!shouldBeFiltered) { + console.log('OUTGOING', message); } - }; - - if(!shouldBeFiltered) { + } else { console.log('OUTGOING', message); } } @@ -174,16 +157,12 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { } Networker.prototype.onGameCommand = function(message) { - if (this.gameController) { - this.gameController.onGameCommand(message); - } else { - console.warn("Networker.onGameCommand: this.gameController is undefined", message); - } + this.gameController.onGameCommand(message); } Networker.prototype.onPong = function(timestamp) { var ping = (Date.now() - parseInt(timestamp, 10)); - domController.setPing(ping); + DomController.setPing(ping); setTimeout(this.ping.bind(this), 1000); }; @@ -191,23 +170,14 @@ function (ProtocolHelper, GameController, User, nc, Settings, domController) { if(this.gameController) { this.gameController.destroy(); + delete this.gameController; } this.gameController = new GameController(options); - - this.gameController.createMe(this.users[this.meUserId]); - - for (var userId in this.users) { - if(this.meUserId != userId) { - this.gameController.createPlayer(this.users[userId]); - } - } - - this.gameController.beginRound(); }; Networker.prototype.onEndRound = function() { - this.gameController.endRound(); + this.gameController.toggleInfo(true); }; return Networker; diff --git a/app/Game/Client/Physics/Engine.js b/app/Game/Client/Physics/Engine.js index 6e93609..b368571 100755 --- a/app/Game/Client/Physics/Engine.js +++ b/app/Game/Client/Physics/Engine.js @@ -3,21 +3,17 @@ define([ "Game/Config/Settings", "Game/Client/View/DomController", "Lib/Vendor/Box2D", - "Lib/Utilities/NotificationCenter", - "Game/Client/View/Pixi/DebugDraw", - "Game/Client/View/Pixi/Layers/Debug" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) { - - "use strict"; +function (Parent, Settings, DomController, Box2D, Nc) { function Engine () { Parent.call(this); this.debugMode = false; - nc.on(nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this); + Nc.on(Nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this); } Engine.prototype = Object.create(Parent.prototype); @@ -25,19 +21,19 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) { Engine.prototype.onToggleDebugMode = function(debugMode) { this.debugMode = debugMode; - if(!this.debugDraw) { + if(this.debugMode && !this.debugDraw) { this.setupDebugDraw(); } - - debugLayer.container.visible = this.debugMode; }; Engine.prototype.setupDebugDraw = function () { - // set debug draw - this.debugDraw = new DebugDraw(); + var debugSprite = DomController.getDebugCanvas().getContext("2d"); - this.debugDraw.SetSprite(debugLayer.graphics); + // set debug draw + this.debugDraw = new Box2D.Dynamics.b2DebugDraw(); + + this.debugDraw.SetSprite(debugSprite); this.debugDraw.SetDrawScale(Settings.RATIO); this.debugDraw.SetFillAlpha(0.5); this.debugDraw.SetLineThickness(1.0); @@ -53,7 +49,7 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) { ); this.world.SetDebugDraw(this.debugDraw); - }; + } Engine.prototype.update = function () { Parent.prototype.update.call(this); @@ -61,7 +57,7 @@ function (Parent, Settings, domController, Box2D, nc, DebugDraw, debugLayer) { if(this.debugMode) { this.world.DrawDebugData(); } - }; + } return Engine; -}); \ No newline at end of file +}) \ No newline at end of file diff --git a/app/Game/Client/Player.js b/app/Game/Client/Player.js index f7484cc..5fb7ce7 100755 --- a/app/Game/Client/Player.js +++ b/app/Game/Client/Player.js @@ -4,21 +4,15 @@ define([ "Game/Config/Settings" ], -function (Parent, nc, Settings) { - - "use strict"; +function (Parent, Nc, Settings) { - function Player(id, physicsEngine, user, isMe) { + function Player(id, physicsEngine, user) { Parent.call(this, id, physicsEngine, user); - this.healthBarView = null; - this.healthBarViewVisibleTimeout = null; - this.healthBarViewVisible = false; + this.playerInfoView = null; + this.playerInfoViewVisibleTimeout = null; + this.playerInfoViewVisible = false; this.initHealthBar(); - - this.ncTokens = (this.ncTokens || []).concat([ - nc.on(nc.ns.client.game.events.render, this.render, this) - ]); } Player.prototype = Object.create(Parent.prototype); @@ -35,36 +29,36 @@ function (Parent, nc, Settings) { Player.prototype.initHealthBar = function() { var self = this; - this.healthBarViewVisible = false; + this.playerInfoViewVisible = false; var options = { x: 100, y: 100, healthFactor: this.stats.health / 100, - visible: this.healthBarViewVisible + visible: this.playerInfoViewVisible }; - var callback = function(healthBarView) { - self.healthBarView = healthBarView; + var callback = function(playerInfoView) { + self.playerInfoView = playerInfoView; } - nc.trigger(nc.ns.client.view.healthBar.createAndAdd, callback, options); + Nc.trigger(Nc.ns.client.view.playerInfo.createAndAdd, callback, options); }; Player.prototype.onHealthChange = function() { if(this.stats.health != 100) { - this.setHealthBarVisible(true); + this.setPlayerInfoVisible(true); } }; Player.prototype.spawn = function(x, y) { Parent.prototype.spawn.call(this, x, y); - this.setHealthBarVisible(false); + this.setPlayerInfoVisible(false); }; - Player.prototype.setHealthBarVisible = function(visible) { + Player.prototype.setPlayerInfoVisible = function(visible) { var self = this; - this.healthBarViewVisible = visible; - if(this.healthBarViewVisibleTimeout) clearTimeout(this.healthBarViewVisibleTimeout); + this.playerInfoViewVisible = visible; + if(this.playerInfoViewVisibleTimeout) clearTimeout(this.playerInfoViewVisibleTimeout); if(visible) { var position = this.getPosition(); @@ -73,45 +67,44 @@ function (Parent, nc, Settings) { x: position.x * Settings.RATIO, y: position.y * Settings.RATIO, healthFactor: this.stats.health / 100, - visible: this.healthBarViewVisible + visible: this.playerInfoViewVisible }; - nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, options); + Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, options); - this.healthBarViewVisibleTimeout = setTimeout(function() { - self.healthBarViewVisible = false; - nc.trigger(nc.ns.client.view.healthBar.update, self.healthBarView, {visible: self.healthBarViewVisible}); + this.playerInfoViewVisibleTimeout = setTimeout(function() { + self.playerInfoViewVisible = false; + Nc.trigger(Nc.ns.client.view.playerInfo.update, self.playerInfoView, {visible: self.playerInfoViewVisible}); }, Settings.HEALTH_DISPLAY_TIME * 1000); } else { - nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, {visible: this.healthBarViewVisible}); + Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, {visible: this.playerInfoViewVisible}); } }; + Player.prototype.getNickname = function() { + return this.user.options.nickname; + }; + Player.prototype.render = function() { if(this.doll) { this.doll.render(); } - if(this.healthBarViewVisible) { + if(this.playerInfoViewVisible) { var position = this.getPosition(); var options = { healthFactor: this.stats.health / 100, x: position.x * Settings.RATIO, y: position.y * Settings.RATIO, } - nc.trigger(nc.ns.client.view.healthBar.update, this.healthBarView, options); + Nc.trigger(Nc.ns.client.view.playerInfo.update, this.playerInfoView, options); } }; - Player.prototype.isHoldingSomething = function() { - return !!this.holdingItem; - }; - Player.prototype.destroy = function() { - clearTimeout(this.healthBarViewVisibleTimeout); - nc.trigger(nc.ns.client.view.healthBar.remove, this.healthBarView); - nc.off(this.ncTokens); + clearTimeout(this.playerInfoViewVisibleTimeout); + Nc.trigger(Nc.ns.client.view.playerInfo.remove, this.playerInfoView); Parent.prototype.destroy.call(this); }; diff --git a/app/Game/Client/PointerLockManager.js b/app/Game/Client/PointerLockManager.js deleted file mode 100644 index ff0ac96..0000000 --- a/app/Game/Client/PointerLockManager.js +++ /dev/null @@ -1,53 +0,0 @@ -define([ - "Lib/Utilities/QuerySelector", - "Lib/Utilities/NotificationCenter" -], - -function (qs, nc) { - - "use strict"; - - function PointerLockManager() { - this.canvas = qs.$("#canvas"); - - this.listeners = []; - - if (!document) { - throw new Error("Using PointerLockManager, but window.document is not defined."); - } - - document.addEventListener('pointerlockchange', this.update.bind(this), false); - document.addEventListener('mozpointerlockchange', this.update.bind(this), false); - document.addEventListener('webkitpointerlockchange', this.update.bind(this), false); - - this.ncTokens = [ - nc.on(nc.ns.client.pointerLock.request, this.request, this) - ]; - } - - PointerLockManager.prototype.request = function() { - - var canvas = this.canvas; - - canvas.requestPointerLock = canvas.requestPointerLock || - canvas.mozRequestPointerLock || - canvas.webkitRequestPointerLock; - - // Ask the browser to lock the pointer - canvas.requestPointerLock(); - } - - // called by the browser event and others - PointerLockManager.prototype.update = function(e, options) { - options = options ? options : {}; - nc.trigger(nc.ns.client.pointerLock.change, this.isLocked(), options); - }; - - PointerLockManager.prototype.isLocked = function() { - return document.pointerLockElement === this.canvas || - document.mozPointerLockElement === this.canvas || - document.webkitPointerLockElement === this.canvas; - }; - - return new PointerLockManager(); -}); \ No newline at end of file diff --git a/app/Game/Client/View/Abstract/Layer.js b/app/Game/Client/View/Abstract/Layer.js deleted file mode 100644 index 5e1521e..0000000 --- a/app/Game/Client/View/Abstract/Layer.js +++ /dev/null @@ -1,67 +0,0 @@ -define([ - "Lib/Utilities/Abstract", - "Lib/Utilities/NotificationCenter" -], - -function (Abstract, nc) { - - "use strict"; - - function Layer(name, options) { - this.name = name; - this.parallaxSpeed = options.parallaxSpeed || 0; - this.zoom = { - current: window.innerWidth / 600, - target: window.innerWidth / 600 - }; - this.position = { - current: { x: 0, y: 0}, - target: { x: 0, y: 0} - }; - - if(options.levelSize) { - this.position.current.x = -options.levelSize.width / 2; - this.position.current.y = -options.levelSize.height / 2; - } - - this.ncTokens = []; - } - - Object.defineProperty(Layer, 'ID', { - value: { - TILE: 'tile', - ITEM: 'item', - SPAWN: 'spawnpoints' - } - }); - - Abstract.prototype.addMethod.call(Layer, 'show'); - Abstract.prototype.addMethod.call(Layer, 'hide'); - Abstract.prototype.addMethod.call(Layer, 'createMesh', ['texturePath', 'callback', 'options']); - Abstract.prototype.addMethod.call(Layer, 'createAnimatedMesh', ['texturePaths', 'callback', 'options']); - Abstract.prototype.addMethod.call(Layer, 'addMesh', ['mesh']); - Abstract.prototype.addMethod.call(Layer, 'removeMesh', ['mesh']); - Abstract.prototype.addMethod.call(Layer, 'updateMesh', ['mesh', 'options']); - Abstract.prototype.addMethod.call(Layer, 'render', ['centerPosition']); - - Layer.prototype.getName = function() { - return this.name; - }; - - Layer.prototype.setPosition = function(centerPosition) { - this.position.target.x = centerPosition.x; - this.position.target.y = centerPosition.y; - }; - - Layer.prototype.setZoom = function(z) { - this.zoom.target = z; - }; - - Layer.prototype.destroy = function() { - for (var i = 0; i < this.ncTokens.length; i++) { - nc.off(this.ncTokens[i]); - }; - }; - - return Layer; -}); \ No newline at end of file diff --git a/app/Game/Client/View/Abstract/View.js b/app/Game/Client/View/Abstract/View.js deleted file mode 100755 index a226801..0000000 --- a/app/Game/Client/View/Abstract/View.js +++ /dev/null @@ -1,106 +0,0 @@ -define([ - "Lib/Utilities/Abstract", - "Game/Client/View/DomController", - "Game/Config/Settings", - "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter" -], - -function (Abstract, domController, Settings, Exception, nc) { - - "use strict"; - - function AbstractView () { - this.me = null; - this.canvas = null; - this.debugMode = false; - - this.ncTokens = [ - nc.on(nc.ns.client.view.display.change, this.onDisplaySizeChange, this), - nc.on(nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this), - - nc.on(nc.ns.client.game.zoomIn, this.onZoomIn, this), - nc.on(nc.ns.client.game.zoomOut, this.onZoomOut, this), - nc.on(nc.ns.client.game.zoomReset, this.onZoomReset, this), - - nc.on(nc.ns.client.view.preloadBar.update, this.onUpdateLoader, this), - ]; - } - - Abstract.prototype.addMethod.call(AbstractView, 'render'); - Abstract.prototype.addMethod.call(AbstractView, 'addFilter', ['mesh', 'options']); - Abstract.prototype.addMethod.call(AbstractView, 'removeFilter', ['mesh', 'options']); - Abstract.prototype.addMethod.call(AbstractView, 'setCameraPosition', ['x', 'y']); - Abstract.prototype.addMethod.call(AbstractView, 'onZoomIn'); - Abstract.prototype.addMethod.call(AbstractView, 'onZoomOut'); - Abstract.prototype.addMethod.call(AbstractView, 'onZoomReset'); - Abstract.prototype.addMethod.call(AbstractView, 'toggleInfo', ['show', 'string']); - Abstract.prototype.addMethod.call(AbstractView, 'onUpdateLoader', ['progress']); - - AbstractView.prototype.isWebGlEnabled = function () { - try { - return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); - } catch(e) { - return false; - } - } - - AbstractView.prototype.initCanvas = function (canvas) { - this.canvas = canvas; - domController.initCanvas(canvas); - } - - AbstractView.prototype.setMe = function(player) { - this.me = player; - }; -/* - AbstractView.prototype.calculateCameraPosition = function() { - var reference = this.me.getPosition(); - var pos = {}; - - pos.x = reference.x; - pos.y = reference.y; - - pos.x = pos.x * Settings.RATIO; - pos.y = -(pos.y * Settings.RATIO); - - pos.x += this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4; - pos.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4; - - return pos; - }; -*/ - AbstractView.prototype.onDisplaySizeChange = function(isFullScreen) { - -/* - if (!isFullScreen) { - Settings.STAGE_WIDTH = 600; - Settings.STAGE_HEIGHT = 400; - } else { - // FIXME: Create FIXME meme (dumb and dumber) - // FIXME: don't overwrite Settings - Settings.STAGE_WIDTH = window.innerWidth; - Settings.STAGE_HEIGHT = window.innerHeight; - } - */ - - Settings.STAGE_WIDTH = window.innerWidth; - Settings.STAGE_HEIGHT = window.innerHeight; - }; - - AbstractView.prototype.onToggleDebugMode = function(debugMode) { - if(debugMode) { - //this.setCameraPosition(-Settings.STAGE_WIDTH / 2, -Settings.STAGE_HEIGHT / 2); - } - - this.debugMode = debugMode; - }; - - AbstractView.prototype.destroy = function() { - for (var i = 0; i < this.ncTokens.length; i++) { - nc.off(this.ncTokens[i]); - }; - }; - - return AbstractView; -}); \ No newline at end of file diff --git a/app/Game/Client/View/DomController.js b/app/Game/Client/View/DomController.js index 90d5f52..89fb78e 100755 --- a/app/Game/Client/View/DomController.js +++ b/app/Game/Client/View/DomController.js @@ -1,168 +1,91 @@ define([ - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Lib/Vendor/Screenfull", - "Game/Client/View/Graph", - "Game/Client/PointerLockManager" + 'Game/Config/Settings', + 'Lib/Utilities/NotificationCenter', + "Lib/Vendor/Stats", + "Lib/Vendor/Screenfull" ], -function (Settings, nc, Screenfull, Graph, pointerLockManager) { - - "use strict"; +function (Settings, Nc, Stats, Screenfull) { function DomController() { - this.canvas = null; + this.canvas = document.getElementById("canvas"); + this.debugCanvas = null; this.stats = null; this.ping = null; - this.nickContainer = null; - this.fpsContainer = null; - this.devToolsContainer = null; - this.frames = 0; - this.canvas = document.getElementById("canvas"); - - this.initDevTools(); + Nc.on(Nc.ns.client.view.events.ready, this.initDevTools, this); } DomController.prototype.initDevTools = function() { + var self = this; - var li, button, label; - - this.devToolsContainer = document.getElementById("menuBar"); - - // create back to menu button - li = document.createElement("li"); - li.id = "back-to-menu"; - button = document.createElement("button"); - button.innerHTML = "Menu"; - button.onclick = function() { - window.location.href="/"; - }; - li.appendChild(button); - this.devToolsContainer.appendChild(li); - - // create user name - li = document.createElement("li"); - label = document.createElement("label"); - label.appendChild(document.createTextNode("?")); - li.appendChild(label); - this.devToolsContainer.appendChild(li); - this.nickContainer = label; - - - // create fps label with updater - li = document.createElement("li"); - label = document.createElement("label"); - label.id = "label-fps"; - li.appendChild(label); - this.devToolsContainer.appendChild(li); - this.fpsContainer = label; - -/* - // create new fps meter - li = document.createElement("li"); - var fpsCanvas = document.createElement("canvas"); - fpsCanvas.id = "graph-fps"; - fpsCanvas.width = "100"; - fpsCanvas.height = "27"; - li.appendChild(fpsCanvas); - this.devToolsContainer.appendChild(li); - - this.fpsGraph = new Graph(fpsCanvas.getContext("2d"), true); - - this.fpsGraph.onUpdate(function(value){ - self.fpsContainer.innerHTML = "FPS:" + value; - - var color, - alpha = 0.8; - - if (value >= 50) { - color = "rgba(136, 209, 018, " + alpha + ")"; - } else if (value > 25) { - color = "rgba(204, 114, 018, " + alpha + ")"; - } else { - color = "rgba(224, 018, 018, " + 1 + ")"; - } - - return color; - }); - - // create new ping meter - li = document.createElement("li"); - var pingCanvas = document.createElement("canvas"); - pingCanvas.id = "graph-fps"; - pingCanvas.width = "100"; - pingCanvas.height = "27"; - li.appendChild(pingCanvas); - this.devToolsContainer.appendChild(li); - - this.pingGraph = new Graph(pingCanvas.getContext("2d"), false, { - scaleOverride: false, - scaleStartValue: 0, - scaleStepWidth: 0, - scaleSteps: 0 - }); -*/ - - setInterval(function() { - self.fpsContainer.innerHTML = "FPS:" + self.frames; - self.frames = 0; - }, 1000); - - // create Ping: container - li = document.createElement("li"); - this.ping = document.createElement("label"); - li.appendChild(this.ping); - this.devToolsContainer.appendChild(li); - - - // create debug mode - li = document.createElement("li"); - label = document.createElement("label"); - var checkbox = document.createElement("input"); - checkbox.type = "checkbox"; - checkbox.onclick = function(e) { - nc.trigger(nc.ns.client.view.debugMode.toggle, e.target.checked); - }; - label.appendChild(checkbox); - label.appendChild(document.createTextNode("Debug")); - li.appendChild(label); - this.devToolsContainer.appendChild(li); + // create dev tools container + this.devToolsContainer = document.createElement("div"); + this.devToolsContainer.id = "devtools"; + document.body.appendChild(this.devToolsContainer); // create Fullscreen - li = document.createElement("li"); - li.id = "fullscreen"; - button = document.createElement("button"); + var p = document.createElement("p"); + var button = document.createElement("button"); button.innerHTML = "Fullscreen"; button.onclick = function() { if(Screenfull.enabled) { - pointerLockManager.request(); Screenfull.request(self.canvas); } - }; - li.appendChild(button); - this.devToolsContainer.appendChild(li); + } + p.appendChild(button); + this.devToolsContainer.appendChild(p); - - // FIXME : isn't this a weird place for this? window.onresize = function() { - nc.trigger(nc.ns.client.view.display.change); - }; + if(Screenfull.enabled) { + Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen); + } + } + + // create Ping: container + this.ping = document.createElement("span"); + this.devToolsContainer.appendChild(this.ping); + + // create FPS stats + this.stats = new Stats(); + this.stats.setMode(0); + this.devToolsContainer.appendChild(this.stats.domElement); + + // create debug mode + var label = document.createElement("label"); + var checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + checkbox.onclick = function(e) { + Nc.trigger(Nc.ns.client.view.debugMode.toggle, e.target.checked); + self.getDebugCanvas().style.display = e.target.checked ? "" : "none"; + } + label.appendChild(checkbox); + label.appendChild(document.createTextNode("Debug")); + this.devToolsContainer.appendChild(label); + + // create health + this.health = document.createElement("span"); + this.health.innerHTML = "Health: 100"; + p = document.createElement("p"); + p.appendChild(this.health); + this.devToolsContainer.appendChild(p); }; - DomController.prototype.setNick = function (nick) { - this.nickContainer.innerHTML = nick; + DomController.prototype.statsBegin = function() { + if(this.stats) { + this.stats.begin(); + } }; - DomController.prototype.fpsStep = function() { - this.frames++; - // this.fpsGraph.step(); + DomController.prototype.statsEnd = function() { + if(this.stats) { + this.stats.end(); + } }; DomController.prototype.setPing = function(ping) { - this.ping.innerHTML = "Ping:" + ping; - // this.pingGraph.addValue(ping); + this.ping.innerHTML = "Ping: " + ping; }; DomController.prototype.getCanvasContainer = function () { @@ -173,32 +96,31 @@ function (Settings, nc, Screenfull, Graph, pointerLockManager) { } else { throw 'Canvas Container missing: #' + Settings.CANVAS_DOM_ID; } - }; + } DomController.prototype.getCanvas = function () { return this.canvas; - }; + } DomController.prototype.initCanvas = function (canvas) { - nc.trigger(nc.ns.client.view.display.change, Screenfull.isFullscreen); - }; + Nc.trigger(Nc.ns.client.view.fullscreen.change, Screenfull.isFullscreen); + } - DomController.prototype.setConnected = function(connected) { - if(connected) { - document.body.style.backgroundColor = ''; - } else { - document.body.style.backgroundColor = '#aaaaaa'; - this.ping.innerHTML = "Disconnected. ".replace(/ /g, ' '); - this.ping.style.color = "#ff0000"; - /* - self = this; - setTimeout(function(){self.ping.innerHTML = "Reload Page...".replace(/ /g, ' ');}, 3000); - setTimeout(function(){self.ping.innerHTML = "Reload in 3...".replace(/ /g, ' ');}, 6000); - setTimeout(function(){self.ping.innerHTML = "Reload in 2...".replace(/ /g, ' ');}, 7000); - setTimeout(function(){self.ping.innerHTML = "Reload in 1...".replace(/ /g, ' ');}, 8000); - setTimeout(function(){self.ping.innerHTML = "Reload now. ".replace(/ /g, ' '); location.reload(); }, 9000); - */ + DomController.prototype.getDebugCanvas = function () { + + if(!this.debugCanvas) { + var canvas = document.createElement('canvas'); + canvas.width = Settings.STAGE_WIDTH; + canvas.height = Settings.STAGE_HEIGHT; + this.debugCanvas = canvas; + this.getCanvasContainer().appendChild(canvas); } + + return this.debugCanvas; + } + + DomController.prototype.setHealth = function(health) { + this.health.innerHTML = "Health: " + parseInt(health, 10); }; diff --git a/app/Game/Client/View/Graph.js b/app/Game/Client/View/Graph.js deleted file mode 100644 index 28edb30..0000000 --- a/app/Game/Client/View/Graph.js +++ /dev/null @@ -1,99 +0,0 @@ -define([ - "Lib/Vendor/Chart" -], - -function (Chart) { - - "use strict"; - - function Graph(ctx, isStepCounter, newOptions) { - - var numberOfGraphBars = 25; - - var empty = new Array(numberOfGraphBars); - for (var i = empty.length - 1; i >= 0; i--) empty[i] = -1; - - var data = { - labels: empty, - datasets: [ - { - label: "no label", - fillColor: "rgba(220,220,220,1)", - strokeColor: "rgba(220,220,220,1)", - highlightFill: "rgba(220,220,220,1)", - data: empty - }, - ]}; - - var options = { - showScale: false, - scaleShowLabels: false, - showTooltips: false, - animation: false, - scaleBeginAtZero : true, - scaleShowGridLines : false, - scaleShowHorizontalLines: true, - scaleShowVerticalLines: true, - barShowStroke : false, - barStrokeWidth : 0, - barValueSpacing : 0, - barDatasetSpacing : 0, - responsive: false, - scaleBackdropPaddingY : 10, - scaleOverride: true, - scaleStartValue: 0, - scaleStepWidth: 1, - scaleSteps: 60 - } - - if (newOptions) { - if (newOptions.scaleOverride) options.scaleOverride = newOptions.scaleOverride; - if (newOptions.scaleStartValue) options.scaleStartValue = newOptions.scaleStartValue; - if (newOptions.scaleSteps) options.scaleSteps = newOptions.scaleSteps; - if (newOptions.scaleStepWidth) options.scaleStepWidth = newOptions.scaleStepWidth; - } - - this.chart = new Chart(ctx).Bar(data, options); - this.stepCounter = 0; - this.currentValue = 0; - this.updateFunction = function(value){}; - - var self = this; - - if (isStepCounter) { - setInterval(function(){ - self.addValue(null); - }, 1000); - } - - } - - Graph.prototype.addValue = function (value) { - - value = value ? value : this.stepCounter; - - this.chart.addData( [value], "" ); - this.currentValue = value; - this.stepCounter = 0; - var color = this.updateFunction(this.currentValue); - color = color ? color : "rgba(136, 209, 018, 1)"; // green - this.chart.datasets[0].bars[this.chart.datasets[0].bars.length-1].fillColor = color; - this.chart.removeData(); - this.chart.update(); - } - - Graph.prototype.step = function() { - this.stepCounter++; - }; - - Graph.prototype.getCurrentValue = function() { - return this.currentValue; - }; - - Graph.prototype.onUpdate = function(f) { - this.updateFunction = f; - }; - - return Graph; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/LayerManager.js b/app/Game/Client/View/LayerManager.js deleted file mode 100644 index 2e2d34f..0000000 --- a/app/Game/Client/View/LayerManager.js +++ /dev/null @@ -1,183 +0,0 @@ -define([ - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Exception", - "Game/Client/View/Pixi/Layer" -], - -function (nc, Exception, Layer) { - - "use strict"; - - function LayerManager(container, me) { - this.layers = []; - this.container = container; - - this.ncTokens = [ - nc.on(nc.ns.client.view.layer.createAndInsert, this.createAndInsert, this), - nc.on(nc.ns.client.view.mesh.create, this.createMesh, this), - nc.on(nc.ns.client.view.animatedMesh.create, this.createAnimatedMesh, this), - nc.on(nc.ns.client.view.mesh.add, this.addMesh, this), - nc.on(nc.ns.client.view.mesh.remove, this.removeMesh, this), - nc.on(nc.ns.client.view.mesh.update, this.updateMesh, this), - nc.on(nc.ns.client.view.mesh.addFilter, this.addFilter, this), - nc.on(nc.ns.client.view.mesh.removeFilter, this.removeFilter, this), - nc.on(nc.ns.client.view.mesh.swapMeshIndexes, this.swapMeshIndexes, this), - nc.on(nc.ns.client.view.mesh.swapMeshes, this.swapMeshes, this) - ]; - } - - - LayerManager.prototype.render = function(centerPosition, zoom) { - for (var i = 0; i < this.layers.length; i++) { - var layer = this.layers[i]; - layer.render(centerPosition, zoom); - } - }; - - /* - * If no referenceId is given, the layer is inserted in the far background (behind=true) - * or in the foreground (behind=false/null) - */ - LayerManager.prototype.createAndInsert = function(id, options, behind, referenceId) { - var layer = new Layer(id, options); - this.insert(layer, behind, referenceId); - }; - - LayerManager.prototype.insert = function(newlayer, behind, referenceId) { - var referenceIndex = -1; - behind = !!behind; - - if (referenceId) { - for(var i = 0; i < this.layers.length; i++) { - var layer = this.layers[i]; - - if (layer.getName() === referenceId) { - referenceIndex = i; - break; - } - } - if (referenceIndex === -1) { - throw new Exception('Reference Layer (' + referenceId + ') could not be found'); - } - } else { - referenceIndex = behind ? 0 : this.container.children.length; - } - - var layerIndex = behind ? referenceIndex : referenceIndex + 1; - - this.layers.splice(layerIndex, 0, newlayer); - - this.rearrangeLayers(); - }; - - LayerManager.prototype.rearrangeLayers = function() { - - var layer; - - for (var i = this.layers.length - 1; i >= 0; i--) { - layer = this.layers[i]; - if (this.container.children.indexOf(layer.getContainer()) !== -1) { - this.container.removeChild(layer.getContainer()); - } - }; - - if (this.container.children.length !== 0) { - console.warn('Unmanaged stuff in container... ', this.container.children); - //throw new Exception('Unmanaged dirt in container... '); - } - - for (var i = 0; i < this.layers.length; i++) { - layer = this.layers[i]; - this.container.addChildAt(layer.getContainer(), i); - }; - }; - - LayerManager.prototype.getLayerById = function(id) { - for (var i = 0; i < this.layers.length; i++) { - var layer = this.layers[i]; - if (layer.getName() === id) { - return layer; - } - }; - return null; - }; - - - - - /* Delegate methods */ - - LayerManager.prototype.delegate = function() { - var methodName = arguments[0]; - var layerId = arguments[1]; - var layer = this.getLayerById(layerId); - - if (!layer) { - throw new Exception('Layer (' + layerId + ') does not exist.'); - } - - var args = arguments; - Array.prototype.splice.call(args, 0, 2); - - layer[methodName].apply(layer, args); - }; - - LayerManager.prototype.createMesh = function() { - var args = arguments; - Array.prototype.splice.call(args, 0, 0, 'createMesh') - - this.delegate.apply(this, args); - }; - - LayerManager.prototype.createAnimatedMesh = function() { - Array.prototype.splice.call(arguments, 0, 0, 'createAnimatedMesh') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.addMesh = function() { - Array.prototype.splice.call(arguments, 0, 0, 'addMesh') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.removeMesh = function() { - Array.prototype.splice.call(arguments, 0, 0, 'removeMesh') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.updateMesh = function() { - Array.prototype.splice.call(arguments, 0, 0, 'updateMesh') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.addFilter = function() { - Array.prototype.splice.call(arguments, 0, 0, 'addFilter') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.removeFilter = function() { - Array.prototype.splice.call(arguments, 0, 0, 'removeFilter') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.swapMeshIndexes = function() { - Array.prototype.splice.call(arguments, 0, 0, 'swapMeshIndexes') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.swapMeshes = function() { - Array.prototype.splice.call(arguments, 0, 0, 'swapMeshes') - this.delegate.apply(this, arguments); - }; - - LayerManager.prototype.destroy = function() { - for (var i = 0; i < this.ncTokens.length; i++) { - nc.off(this.ncTokens[i]); - }; - for (var i = this.layers.length - 1; i >= 0; i--) { - var layer = this.layers[i]; - layer.destroy(); - }; - }; - - return LayerManager; -}); \ No newline at end of file diff --git a/app/Game/Client/View/Mesh.js b/app/Game/Client/View/Mesh.js deleted file mode 100644 index 9290593..0000000 --- a/app/Game/Client/View/Mesh.js +++ /dev/null @@ -1,22 +0,0 @@ -define([ - 'Game/Config/Settings', - 'Lib/Utilities/NotificationCenter', - "Lib/Vendor/Stats", - "Lib/Vendor/Screenfull" -], - -function (Settings, nc, Stats, Screenfull) { - - "use strict"; - - function Mesh() { - - } - - Mesh.prototype.render = function() { - - }; - - return Mesh; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/ColorRangeReplaceFilter.js b/app/Game/Client/View/Pixi/ColorRangeReplaceFilter.js deleted file mode 100644 index 70045ea..0000000 --- a/app/Game/Client/View/Pixi/ColorRangeReplaceFilter.js +++ /dev/null @@ -1,91 +0,0 @@ -define([ - "Lib/Vendor/Pixi" -], - -function (PIXI) { - - "use strict"; - - var Parent = PIXI.AbstractFilter; - - function ColorRangeReplaceFilter() { - Parent.call(this); - - this.passes = [this]; - - // set the uniforms - - this.uniforms = { - minColor: {type: '3fv', value: [0,0,0]}, - maxColor: {type: '3fv', value: [0,0,0]}, - newColor: {type: '3fv', value: [0,0,0]}, - brightnessOffset: {type: '1f', value: 0} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'uniform vec3 minColor;', - 'uniform vec3 maxColor;', - 'uniform vec3 newColor;', - 'uniform float brightnessOffset;', - - 'void main(void) {', - ' vec4 pixel = texture2D(uSampler, vTextureCoord);', - ' if(pixel.x >= minColor.x && pixel.y >= minColor.y && pixel.z >= minColor.z', - ' && pixel.w == 1.0', - ' && pixel.x <= maxColor.x && pixel.y <= maxColor.y && pixel.z <= maxColor.z) {', - - ' pixel.rgb = mix(pixel.rgb, vec3(0.2126*pixel.r + 0.7152*pixel.g + 0.0722*pixel.b), 1.0);', // desaturate to gray - ' pixel.rgb += brightnessOffset;', - ' pixel.rgb *= newColor;', - ' }', - ' gl_FragColor = pixel;', - '}' - ]; - } - - ColorRangeReplaceFilter.prototype = Object.create(Parent.prototype); - ColorRangeReplaceFilter.prototype.constructor = ColorRangeReplaceFilter; - - - Object.defineProperty(ColorRangeReplaceFilter.prototype, 'minColor', { - get: function() { - return PIXI.rgb2hex(this.uniforms.minColor.value); - }, - set: function(value) { - this.uniforms.minColor.value = PIXI.hex2rgb(value); - } - }); - - Object.defineProperty(ColorRangeReplaceFilter.prototype, 'maxColor', { - get: function() { - return PIXI.rgb2hex(this.uniforms.maxColor.value); - }, - set: function(value) { - this.uniforms.maxColor.value = PIXI.hex2rgb(value); - } - }); - - Object.defineProperty(ColorRangeReplaceFilter.prototype, 'newColor', { - get: function() { - return PIXI.rgb2hex(this.uniforms.newColor.value); - }, - set: function(value) { - this.uniforms.newColor.value = PIXI.hex2rgb(value); - } - }); - - Object.defineProperty(ColorRangeReplaceFilter.prototype, 'brightnessOffset', { - get: function() { - return this.uniforms.brightnessOffset.value; - }, - set: function(value) { - this.uniforms.brightnessOffset.value = value; - } - }); - - return ColorRangeReplaceFilter; -}); diff --git a/app/Game/Client/View/Pixi/DebugDraw.js b/app/Game/Client/View/Pixi/DebugDraw.js deleted file mode 100644 index a45a621..0000000 --- a/app/Game/Client/View/Pixi/DebugDraw.js +++ /dev/null @@ -1,179 +0,0 @@ -define([ - "Lib/Vendor/Box2D" -], - -function (Box2D) { - - "use strict"; - - var Parent = Box2D.Dynamics.b2DebugDraw; - - function DebugDraw() { - Parent.call(this); - this.m_drawScale = 1; - } - - DebugDraw.prototype = Object.create(Parent.prototype); - - DebugDraw.prototype.setColor = function(color) { - this.m_ctx.debugColor = color.color; - this.m_ctx.debugFillAlpha = this.m_fillAlpha; - this.m_ctx.lineStyle(1, this.m_ctx.debugColor, this.m_alpha); - }; - - DebugDraw.prototype.SetSprite = function(sprite) { - this.m_ctx = sprite; - - this.m_sprite = { - graphics: { - clear: function () { - sprite.clear(); - sprite.lineStyle(1, 0xffffff, 0.8); - } - } - }; - - this.m_ctx.beginPath = function() { - this.beginFill(this.debugColor, this.debugFillAlpha); - }; - - this.m_ctx.closePath = function() { - this.endFill(); - }; - - this.m_ctx.fill = function() { - this.endFill(); - }; - - this.m_ctx.stroke = function() { - // do nothing - }; - - this.m_ctx.arc = function(x, y, radius, startingAngle, endingAngle, counterClockwise) { - this.drawCircle(x, y, radius); - } - - }; - - DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - this.setColor(color); - Parent.prototype.DrawPolygon.call(this, arguments); - }; - - DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - this.setColor(color); - Parent.prototype.DrawSolidPolygon.apply(this, arguments); - }; - - DebugDraw.prototype.DrawCircle = function (center, radius, color) { - this.setColor(color); - Parent.prototype.DrawCircle.apply(this, arguments); - }; - - DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - this.setColor(color); - Parent.prototype.DrawSolidCircle.apply(this, arguments); - }; - - DebugDraw.prototype.DrawSegment = function (p1, p2, color) { - this.setColor(color); - Parent.prototype.DrawSegment.apply(this, arguments); - }; - - DebugDraw.prototype.DrawTransform = function (xf) { - this.setColor(0xff0000); - Parent.prototype.DrawTransform.apply(this, arguments); - }; - - -/* - DebugDraw.prototype.DrawPolygon = function (vertices, vertexCount, color) { - if (!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.stroke(); - }; - - DebugDraw.prototype.DrawSolidPolygon = function (vertices, vertexCount, color) { - if (!vertexCount) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.moveTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - for (var i = 1; i < vertexCount; i++) { - s.lineTo(vertices[i].x * drawScale, vertices[i].y * drawScale); - } - s.lineTo(vertices[0].x * drawScale, vertices[0].y * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - - DebugDraw.prototype.DrawCircle = function (center, radius, color) { - if (!radius) return; - var s = this.m_ctx; - var drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.arc(center.x * drawScale, center.y * drawScale, radius * drawScale, 0, Math.PI * 2, true); - s.closePath(); - s.stroke(); - }; - - DebugDraw.prototype.DrawSolidCircle = function (center, radius, axis, color) { - if (!radius) return; - var s = this.m_ctx, - drawScale = this.m_drawScale, - cx = center.x * drawScale, - cy = center.y * drawScale; - s.moveTo(0, 0); - s.beginPath(); - s.strokeStyle = this._color(color.color, this.m_alpha); - s.fillStyle = this._color(color.color, this.m_fillAlpha); - s.arc(cx, cy, radius * drawScale, 0, Math.PI * 2, true); - s.moveTo(cx, cy); - s.lineTo((center.x + axis.x * radius) * drawScale, (center.y + axis.y * radius) * drawScale); - s.closePath(); - s.fill(); - s.stroke(); - }; - - DebugDraw.prototype.DrawSegment = function (p1, p2, color) { - var s = this.m_ctx, - drawScale = this.m_drawScale; - s.strokeStyle = this._color(color.color, this.m_alpha); - s.beginPath(); - s.moveTo(p1.x * drawScale, p1.y * drawScale); - s.lineTo(p2.x * drawScale, p2.y * drawScale); - s.closePath(); - s.stroke(); - }; - - DebugDraw.prototype.DrawTransform = function (xf) { - var s = this.m_ctx, - drawScale = this.m_drawScale; - s.beginPath(); - s.strokeStyle = this._color(0xff0000, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col1.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col1.y) * drawScale); - - s.strokeStyle = this._color(0xff00, this.m_alpha); - s.moveTo(xf.position.x * drawScale, xf.position.y * drawScale); - s.lineTo((xf.position.x + this.m_xformScale * xf.R.col2.x) * drawScale, (xf.position.y + this.m_xformScale * xf.R.col2.y) * drawScale); - s.closePath(); - s.stroke(); - }; -*/ - return DebugDraw; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/GameStats.js b/app/Game/Client/View/Pixi/GameStats.js deleted file mode 100644 index 55d520c..0000000 --- a/app/Game/Client/View/Pixi/GameStats.js +++ /dev/null @@ -1,206 +0,0 @@ -define([ - "Lib/Vendor/Pixi", - "Lib/Utilities/NotificationCenter", - "Game/Config/Settings", - "Lib/Utilities/ColorConverter" -], - -function (PIXI, nc, Settings, ColorConverter) { - - "use strict"; - - function GameStats(view) { - - this.style = { - borderWidth: 3, - padding: 20, - colors: { - background: 0x000000, - text: "red", - headline: "#880000", - border: 0xAA0000 - }, - line: { - height: 16, - spacing: 5 - }, - fontSize: 12 - }; - - this.view = view; - - this.container = new PIXI.DisplayObjectContainer(); - - var blurFilter = new PIXI.BlurFilter(); - blurFilter.blurX = 12; - blurFilter.blurY = 12; - var grayFilter = new PIXI.GrayFilter(); - grayFilter.gray = 0.85; - this.filters = [blurFilter, grayFilter]; - - this.background = new PIXI.Graphics(); - this.background.alpha = 0.7; - this.container.addChild(this.background); - - this.dialog = new PIXI.DisplayObjectContainer(); - this.container.addChild(this.dialog); - - this.graphics = new PIXI.Graphics(); - - /* - gameContainer - filters - container - background - dialog - graphics - playerColor - headline - line - */ - - this.container.visible = false; - this.sortedPlayers = []; - - this.ncTokens = [ - nc.on(nc.ns.client.view.gameStats.toggle, this.toggle, this), - nc.on(nc.ns.client.view.gameStats.update, this.update, this) - ]; - } - - GameStats.prototype.getInfoContainer = function() { - return this.container; - }; - - GameStats.prototype.toggle = function(show) { - if(show) { - this.redraw(); - // show stats with filters - this.container.visible = true; - - this.view.addFilters(this.filters); - this.filters.forEach(function(filter) { filter.dirty = true; }); - } else { - this.container.visible = false; - this.view.removeFilters(this.filters); - } - } - - GameStats.prototype.update = function(sortedPlayers) { - this.sortedPlayers = sortedPlayers; - this.redraw(); - }; - - GameStats.prototype.redraw = function() { - this.background.clear(); - this.graphics.clear(); - this.dialog.removeChildren(); - - // redraw background - this.background.beginFill(this.style.colors.background); - this.background.drawRect(0, 0, Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT); - this.background.endFill(); - - // redraw text and graphics - - var string = "" + - " #".pad(7, true) + " " + - "Name".pad(12, true) + - "Score".pad(6, false) + - "Deaths".pad(7, false) + - "Health".pad(9, false) + " "; - - var line = new PIXI.Text(string, { - font: "normal " + this.style.fontSize + "px 'Joystix'", - fill: this.style.colors.headline - }); - - line.position = new PIXI.Point(0, 0); - this.dialog.addChild(line); - - this.drawPlayers(this.sortedPlayers); - - var x = Settings.STAGE_WIDTH / 2 - this.dialog.getBounds().width / 2, - y = Settings.STAGE_HEIGHT / 2 - (this.sortedPlayers.length + 1) * (this.style.line.height + this.style.line.spacing) / 2; - this.dialog.position = new PIXI.Point(x, y); - - this.dialog.addChild(this.graphics); - }; - - GameStats.prototype.drawPlayers = function(sortedPlayers) { - sortedPlayers.forEach(function(player, i) { - - this.drawPlayer(player, i + 1); - this.drawPlayerGraphics(player, i + 1) - - }, this); - }; - - GameStats.prototype.drawPlayer = function(player, i) { - var string = (i + ". ").pad(7, false) + " " + - player.getNickname().pad(12, true) + - ("" + player.stats.score).pad(6, false) + - ("" + player.stats.deaths).pad(7, false) + - ("" /* + parseInt(player.stats.health, 10)*/).pad(9, false) + " "; - - var line = new PIXI.Text(string, { - font: "normal " + this.style.fontSize + "px 'Joystix'", - fill: this.style.colors.text - }); - - line.position = new PIXI.Point( - 0, - i * (this.style.line.height + this.style.line.spacing) - ); - - this.dialog.addChild(line); - }; - - GameStats.prototype.drawPlayerGraphics = function(player, i) { - var converter = new ColorConverter(); - - // draw shirt color - this.graphics.beginFill(converter.getColorByName(player.getNickname())); - this.graphics.drawRect( - 50, - i * (this.style.line.height + this.style.line.spacing), - this.style.line.height, - this.style.line.height - ); - - // draw health bar - var height = this.style.line.height / 2, - width = height * 7, - borderWidth = 2, - offsetX = 360, - offsetY = (i * (this.style.line.height + this.style.line.spacing)) + ((this.style.line.height - height) / 2); - - this.graphics.beginFill(0x000000); - this.graphics.drawRect(offsetX, offsetY, width, height); - this.graphics.endFill(); - - if(player.stats.health > 0) { - var color = player.stats.health / 100 < Settings.CRITICAL_HEALTH_THRESHOLD - ? 0xFF0000 - : 0x00FF00; - - this.graphics.beginFill(color); - this.graphics.drawRect( - offsetX + borderWidth, - offsetY + borderWidth, - width * player.stats.health / 100 - 2 * borderWidth, - height - 2 * borderWidth - ); - this.graphics.endFill(); - } - }; - - GameStats.prototype.destroy = function() { - for (var i = 0; i < this.ncTokens.length; i++) { - nc.off(this.ncTokens[i]); - }; - }; - - return GameStats; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layer.js b/app/Game/Client/View/Pixi/Layer.js deleted file mode 100644 index 5a44988..0000000 --- a/app/Game/Client/View/Pixi/Layer.js +++ /dev/null @@ -1,322 +0,0 @@ -define([ - "Game/Client/View/Abstract/Layer", - "Lib/Vendor/Pixi", - "Game/Client/View/Pixi/ColorRangeReplaceFilter", - "Game/Config/Settings", - "Lib/Utilities/ColorConverter", - "Lib/Utilities/NotificationCenter" -], - -function (Parent, PIXI, ColorRangeReplaceFilter, Settings, ColorConverter, nc) { - - "use strict"; - - function Layer (name, options) { - Parent.call(this, name, options); - this.container = new PIXI.DisplayObjectContainer(); - this.container.x = 0; - this.container.y = 0; - this.static = false; - this.levelSize = { - width: 0, - height: 0 - } - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.view.layer.levelSizeUpdate, this.onLevelSizeUpdate, this) - ]); - - if (Settings.SHOW_LAYER_INFO) { - - var self = this; - var g = new PIXI.Graphics(); - var converter = new ColorConverter(); - var c = converter.getColorByName(name); - var fontSize = 12; - var textOptions = { - font: "normal " + fontSize + "px 'Joystix'", - fill: "#" + c.toString(16), - }; - - var t = new PIXI.Text(name, textOptions); - - var y = 0; - switch (name) { - case "ghost": y++; - case "item": y++; - case "tile": y++; - case "spawn": y=y; - } - - t.position = new PIXI.Point(0, fontSize * y); - - g.lineStyle (1, c, 1); - g.drawRect (0, 0, 100 + y, 100 + y); - - setTimeout(function(){ - self.container.addChild(t); - self.container.addChild(g); - }, 500); - } - } - - Layer.prototype = Object.create(Parent.prototype); - - Layer.prototype.onLevelSizeUpdate = function(levelSize) { - this.levelSize = levelSize; - }; - - Layer.prototype.getAvailableMeshFilters = function() { - return { - "blur": PIXI.BlurFilter, - "desaturate": PIXI.GrayFilter, - "pixelate": PIXI.PixelateFilter, - "colorRangeReplace": ColorRangeReplaceFilter, - }; - }; - - Layer.prototype.getContainer = function() { - return this.container; - }; - - Layer.prototype.show = function() { - this.container.visible = true; - }; - - Layer.prototype.hide = function() { - this.container.visible = false; - }; - - Layer.prototype.addMesh = function(mesh) { - this.container.addChild(mesh); - }; - - Layer.prototype.removeMesh = function(mesh) { - this.container.removeChild(mesh); - }; - - Layer.prototype.swapMeshIndexes = function(meshA, meshB) { - var indexA = this.container.getChildIndex(meshA); - var indexB = this.container.getChildIndex(meshB); - - this.container.setChildIndex(meshA, indexB); - this.container.setChildIndex(meshB, indexA); - }; - - Layer.prototype.swapMeshes = function(meshA, meshB) { - var textureA = meshA.texture; - var textureB = meshB.texture; - - meshA.setTexture(textureB); - meshA.onTextureUpdate(); - meshA.scale.x = 1; - meshA.scale.y = 1; - - meshB.setTexture(textureA); - meshB.onTextureUpdate(); - meshB.scale.x = 1; - meshB.scale.y = 1; - - }; - - Layer.prototype.createMesh = function (texturePath, callback, options) { - - var texture = (options && options.fromFrame) - ? PIXI.Texture.fromFrame(texturePath) - : PIXI.Texture.fromImage(texturePath); - - - var mesh = new PIXI.Sprite(texture); - - if(options) this.updateMesh(mesh, options); - - callback(mesh); - }; - - Layer.prototype.createAnimatedMesh = function (texturePaths, callback, options) { - var textures = []; - for (var i = 0; i < texturePaths.length; i++) { - - var texture = (options && options.fromFrame) - ? PIXI.Texture.fromFrame(texturePaths[i]) - : PIXI.Texture.fromImage(texturePaths[i]); - - texture.width = options.width; - texture.height = options.height; - //PIXI.texturesToUpdate.push(texture); - textures.push(texture); - } - - var mesh = new PIXI.MovieClip(textures); - if(options) this.updateMesh(mesh, options); - - mesh.animationSpeed = 0.5; - - mesh.play(); - - callback(mesh); - } - - Layer.prototype.updateMesh = function(mesh, options) { - if (options.x) mesh.position.x = options.x; - if (options.y) mesh.position.y = options.y; - if (options.rotation) mesh.rotation = options.rotation; - if (options.alpha) mesh.alpha = options.alpha; - if (options.width) mesh.width = options.width; - if (options.height) mesh.height = options.height; - if (options.xScale) mesh.width = Math.abs(mesh.width) * options.xScale; - if (options.yScale) mesh.scale.y = options.yScale; - if (options.visible === true || options.visible === false) mesh.visible = options.visible; - if (options.pivot) mesh.pivot = new PIXI.Point(options.pivot.x, options.pivot.y); - if (options.anchor) mesh.anchor = options.anchor; - if (options.animationSpeed) mesh.animationSpeed = options.animationSpeed; - }; - - Layer.prototype.addFilter = function(mesh, filterName, options) { - - // use game container if mesh null - if(mesh === null) { - - } - - if (!this.getAvailableMeshFilters().hasOwnProperty(filterName)) { - throw new Exception('Filter ' + filterName + ' is not available'); - } - - var MeshFilter = this.getAvailableMeshFilters()[filterName]; - var filter = new MeshFilter(); - - switch (filterName) { - case 'desaturate': - if (options.amount) filter.gray = options.amount; - break; - - case 'blur': - if (options.blurX) filter.blurX = options.blurX; - if (options.blurY) filter.blurY = options.blurY; - break; - - case 'colorRangeReplace': - if (options.minColor) filter.minColor = options.minColor; - if (options.maxColor) filter.maxColor = options.maxColor; - if (options.newColor) filter.newColor = options.newColor; - if (options.brightnessOffset) filter.brightnessOffset = options.brightnessOffset; - break; - - case 'pixelate': - if (options.sizeX) filter.size.x = options.sizeX; - if (options.sizeY) filter.size.y = options.sizeY; - break; - - default: - break; - } - - var filters = mesh.filters; - - if(!filters) { - filters = []; - } else { - // ensure uniqueness of filter by name - this.removeFilter(mesh, filterName); - } - - filters.push(filter); - mesh.filters = filters; - }; - - Layer.prototype.removeFilter = function(mesh, filterName) { - - var filters = mesh.filters; - - if(!filters) { - return; - } - - // FIXME this should throw an error i think since "options" is not defined here - // maybe we never actually call this method? - var MeshFilter = this.getAvailableMeshFilters()[options.filter]; - - filters = filters.filter(function(filter){ - return !filter instanceof MeshFilter; - }); - - mesh.filters = filter; - }; - - Layer.prototype.render = function(centerPosition, zoom) { - this.setPosition(centerPosition); - - this.setZoom(zoom); - - // Zoom - var zoomStep = (this.zoom.target - this.zoom.current) * Settings.CAMERA_GLIDE / 100; - this.zoom.current += zoomStep; - this.container.scale.x = this.zoom.current; - this.container.scale.y = this.container.scale.x; - - - /* - // we would need another zoom state, - // to separate fixed zooming (by window size) - // and user zoom by +/-/0 keys - - // this snippet would zoom the layers by its parallax - // so further away layers would not zoom as much. - - var zoomParallax = this.parallaxSpeed == 0 - ? 1 - : this.parallaxSpeed < 0 - ? (1 + this.parallaxSpeed) - : this.parallaxSpeed + 1000; - - var newZoomTarget = 1 + Math.log(this.zoom.target+2) * (zoomParallax) - console.log(newZoomTarget) - - this.container.scale.x = newZoomTarget; - this.container.scale.y = newZoomTarget; - - // Later, this would need to be added as well: - this.container.x *= newZoomTarget; - this.container.y *= newZoomTarget; - */ - - - // Position - - if (!this.static) { - var posXStep = (this.position.target.x - this.position.current.x) * Settings.CAMERA_GLIDE / 100; - this.position.current.x += posXStep; - - var posYStep = (this.position.target.y - this.position.current.y) * Settings.CAMERA_GLIDE / 100; - this.position.current.y += posYStep; - - // Add here to set 0,0 not in the center of the map but the level origin in the top left - // FIXME: use a different kind of flag than "name" - if (this.name == "spawn" - || this.name == "tile" - || this.name == "item" - || this.name == "ghost" - || this.name == "swiper" - || this.parallaxSpeed == 0) { - - this.container.x = this.position.current.x; - this.container.y = this.position.current.y; - - } else { - var x = this.position.current.x + this.levelSize.width / 2; - this.container.x = x - x * -this.parallaxSpeed; - var y = this.position.current.y + this.levelSize.height / 2; - this.container.y = y - y * -this.parallaxSpeed; - } - - this.container.x *= this.zoom.current; - this.container.y *= this.zoom.current; - - this.container.x += Settings.STAGE_WIDTH / 2; - this.container.y += Settings.STAGE_HEIGHT / 2; - } - }; - - return Layer; -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layers/Debug.js b/app/Game/Client/View/Pixi/Layers/Debug.js deleted file mode 100644 index c5b650e..0000000 --- a/app/Game/Client/View/Pixi/Layers/Debug.js +++ /dev/null @@ -1,20 +0,0 @@ -define([ - "Game/Client/View/Pixi/Layer", - "Lib/Vendor/Pixi", -], - -function (Parent, PIXI) { - - "use strict"; - - function Debug() { - Parent.call(this, "debug", 0.00000001); - - this.graphics = new PIXI.Graphics(); - this.container.addChild(this.graphics); - } - - Debug.prototype = Object.create(Parent.prototype); - - return new Debug(); -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layers/Ghost.js b/app/Game/Client/View/Pixi/Layers/Ghost.js deleted file mode 100644 index 8260f6f..0000000 --- a/app/Game/Client/View/Pixi/Layers/Ghost.js +++ /dev/null @@ -1,119 +0,0 @@ -define([ - "Game/Client/View/Pixi/Layer", - "Lib/Vendor/Pixi", - "Lib/Utilities/NotificationCenter", - "Game/Config/Settings" -], - -function (Parent, PIXI, nc, Settings) { - - "use strict"; - - function Ghost() { - Parent.call(this, "ghost", {parallaxSpeed: 0}); - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.view.layer.levelSizeUpdate, this.onLevelSizeUpdate, this), - nc.on(nc.ns.client.view.playerArrow.createAndAdd, this.onCreateAndAddPlayerArrow, this), - nc.on(nc.ns.client.view.playerArrow.update, this.onUpdatePlayerArrow, this), - nc.on(nc.ns.client.view.healthBar.createAndAdd, this.onCreateAndAddHealthBar, this), - nc.on(nc.ns.client.view.healthBar.update, this.onUpdateHealthBar, this), - nc.on(nc.ns.client.view.healthBar.remove, this.onRemoveHealthBar, this), - ]); - - } - - Ghost.prototype = Object.create(Parent.prototype); - - Ghost.prototype.onLevelSizeUpdate = function(levelSize) { - this.position.current.x = -levelSize.width / 2; - this.position.current.y = -levelSize.height / 2; - }; - - Ghost.prototype.onCreateAndAddPlayerArrow = function(callback, options) { - - var arrow = new PIXI.Graphics(); - arrow.visible = false; - this.container.addChild(arrow); - - var width = 10, - height = 10; - - arrow.beginFill(0xffffff, 0.4); - arrow.lineStyle(0, 0x000000); - arrow.moveTo(0, 0); - arrow.lineTo(width, 0); - arrow.lineTo(width / 2, height); - arrow.endFill(); - arrow.pivot = new PIXI.Point(width/2, height/2); - arrow.visible = true; - - this.onUpdatePlayerArrow(arrow, options); - - callback(arrow); - }; - - Ghost.prototype.onUpdatePlayerArrow = function(arrow, options) { - - var offsetX = 0, - offsetY = -55, - x = offsetX + options.x, - y = offsetY + options.y; - - var target = new PIXI.Point(x, y); - - arrow.position.x += (target.x -arrow.position.x) * Settings.ARROW_GLIDE / 1.5 / 100; - arrow.position.y += (target.y -arrow.position.y) * Settings.ARROW_GLIDE / 100; - - var angle = -Math.atan2(arrow.position.x - x, arrow.position.y - options.y); - angle += 0.785398163 * 4; - - arrow.rotation = angle; - }; - - // Player Info - - Ghost.prototype.onCreateAndAddHealthBar = function(callback, options) { - var healthBar = new PIXI.Graphics(); - this.container.addChild(healthBar); - - this.onUpdateHealthBar(healthBar, options); - callback(healthBar); - }; - - Ghost.prototype.onUpdateHealthBar = function(healthBar, options) { - var width = 14, - height = 2, - borderWidth = 1, - offsetX = -8, - offsetY = -52; - - if(typeof options.healthFactor != 'undefined') { - healthBar.clear(); - - healthBar.beginFill(0x000000); - healthBar.lineStyle(borderWidth, 0x000000); - healthBar.drawRect(0, 0, width, height); - healthBar.endFill(); - - if(options.healthFactor > 0) { - var color = 0x00FF00; - if(options.healthFactor < Settings.CRITICAL_HEALTH_THRESHOLD) color = 0xFF0000; - healthBar.beginFill(color); - healthBar.lineStyle(0, 0x000000); - healthBar.drawRect(borderWidth, borderWidth, width * options.healthFactor, height); - healthBar.endFill(); - } - } - - if (options.x && options.y) healthBar.position = new PIXI.Point(offsetX + options.x, offsetY + options.y); - if (options.visible === true || options.visible === false) healthBar.visible = options.visible; - }; - - Ghost.prototype.onRemoveHealthBar = function(healthBar) { - this.container.removeChild(healthBar); - }; - - return Ghost; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layers/Messages.js b/app/Game/Client/View/Pixi/Layers/Messages.js deleted file mode 100644 index a9a547c..0000000 --- a/app/Game/Client/View/Pixi/Layers/Messages.js +++ /dev/null @@ -1,63 +0,0 @@ -define([ - "Game/Client/View/Pixi/Layer", - "Lib/Vendor/Pixi", - "Lib/Utilities/NotificationCenter", - "Game/Config/Settings" -], - -function (Parent, PIXI, nc, Settings) { - - "use strict"; - - function Messages() { - Parent.call(this, "messages", {parallaxSpeed:-1}); - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.view.gameStats.kill, this.onKill, this) - ]); - - this.mainTextOptions = { - font: "normal 22px 'Joystix'", - fill: "#cc0000", - stroke: "rgba(0,0,0,0.8)", - strokeThickness: 6 - }; - - this.mainText = new PIXI.Text("", this.mainTextOptions); - this.container.addChild(this.mainText); - this.mainText.visible = false; - } - - Messages.prototype = Object.create(Parent.prototype); - - Messages.prototype.onKill = function(options) { - - var killer = options.killer.isMe ? "You" : options.killer.name; - - var victim = options.victim.isMe - ? options.killer.isMe - ? "Yourself" - : "You" - : options.victim.name; - - var text = killer + " killed " + victim + " with " + options.item; - - this.mainText.setText(text); - this.mainText.setStyle(this.mainTextOptions); - this.mainText.position = new PIXI.Point(-this.mainText.width / 2, (Settings.STAGE_HEIGHT / 4) -this.mainText.height / 2); - this.mainText.visible = true; - - var self = this; - setTimeout(function(){ - self.mainText.visible = false; - }, Settings.SCORE_MESSAGE_TIMEOUT); - - } - - Messages.prototype.render = function(centerPosition, zoom) { - Parent.prototype.render.call(this, centerPosition, 1); - } - - return Messages; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/Layers/Swiper.js b/app/Game/Client/View/Pixi/Layers/Swiper.js deleted file mode 100644 index 9c89d95..0000000 --- a/app/Game/Client/View/Pixi/Layers/Swiper.js +++ /dev/null @@ -1,57 +0,0 @@ -define([ - "Game/Client/View/Pixi/Layer", - "Lib/Vendor/Pixi", - "Lib/Utilities/NotificationCenter", - "Game/Config/Settings" -], - -function (Parent, PIXI, nc, Settings) { - - function Swiper() { - Parent.call(this, "swiper", {parallaxSpeed:0}); - - this.static = true; - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.view.swiper.swipe, this.swipe, this), - nc.on(nc.ns.client.view.swiper.end, this.end, this) - ]); - - this.sprite = new PIXI.Graphics(); - this.container.addChild(this.sprite); - - this.end(); - } - - Swiper.prototype = Object.create(Parent.prototype); - - Swiper.prototype.swipe = function(x, y) { - var offset = { - x: Settings.STAGE_WIDTH / 2 / this.zoom.current, - y: Settings.STAGE_HEIGHT / 2 / this.zoom.current, - } - - this.sprite.moveTo(offset.x + this.last.x, offset.y + this.last.y); - - this.last.x = x; - this.last.y = -y; - - this.sprite.lineTo(offset.x + this.last.x, offset.y + this.last.y); - }; - - Swiper.prototype.end = function(x, y) { - this.sprite.clear(); - - this.sprite.lineStyle(2, 0xffffff); - this.sprite.alpha = 0.5; - - this.last = { - x: 0, - y: 0 - } - }; - - - return Swiper; - -}); \ No newline at end of file diff --git a/app/Game/Client/View/Pixi/View.js b/app/Game/Client/View/Pixi/View.js deleted file mode 100755 index d7c7f11..0000000 --- a/app/Game/Client/View/Pixi/View.js +++ /dev/null @@ -1,317 +0,0 @@ -define([ - "Game/Client/View/Abstract/View", - "Game/Client/View/DomController", - "Lib/Vendor/Pixi", - "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Exception", - "Game/Client/View/Pixi/GameStats", - "Game/Client/View/LayerManager", - "Game/Client/View/Pixi/Layers/Ghost", - "Game/Client/View/Pixi/Layers/Swiper", - "Game/Client/PointerLockManager", - "Game/Client/View/Pixi/Layers/Debug", - "Game/Client/View/Pixi/Layers/Messages" -], - -function (Parent, domController, PIXI, Settings, nc, Exception, GameStats, LayerManager, Ghost, Swiper, pointerLockManager, Debug, Messages) { - - "use strict"; - - function PixiView () { - - Parent.call(this); - - this.xyz = Math.random() - - this.layerManager = null; - this.stage = null; - this.container = null; - this.infoContainer = null; - this.loader = null; - this.currentZoom = Settings.ZOOM_DEFAULT; - this.clickToEnable = null; - - this.init(); - - this.ncTokens = this.ncTokens.concat([ - nc.on(nc.ns.client.pointerLock.change, this.onPointerLockChange, this), - nc.on(nc.ns.core.game.events.level.loaded, this.showDefaultLayers, this) - ]); - - PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST; - } - - PixiView.prototype = Object.create(Parent.prototype); - - PixiView.prototype.init = function () { - - var rendererOptions = { - view: domController.getCanvas(), - antialiasing: false, - transparent: false, - resolution: 1 - } - - if(Settings.USE_WEBGL) { - - PIXI.WebGLRenderer.glContextId = 0; - this.renderer = new PIXI.WebGLRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, rendererOptions); - console.log('WebGLRenderer'); - - } else { - - this.renderer = new PIXI.CanvasRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, rendererOptions); - console.warn('CanvasRenderer - not using WebGL!'); - - } - - this.onDisplaySizeChange(false); - - this.stage = new PIXI.Stage(0x333333); - - this.container = new PIXI.DisplayObjectContainer(); - this.stage.addChild(this.container); - - this.layerManager = new LayerManager(this.container, this.me); - - this.initLoader(); - - this.initCanvas(this.renderer.view); - - this.initPointerLockView(); - - // Tab Overlay (not using layer manager, cause of filters) - this.gameStats = new GameStats(this); - this.stage.addChild(this.gameStats.getInfoContainer()); - - this.ghostLayer = new Ghost(); - this.ghostLayer.hide(); - this.layerManager.insert(this.ghostLayer, false); - - this.swiperLayer = new Swiper(); - this.swiperLayer.hide() - this.layerManager.insert(this.swiperLayer, false); - - this.debugLayer = Debug; - this.debugLayer.hide(); - this.layerManager.insert(this.debugLayer, false); - - this.messagesLayer = new Messages(); - this.messagesLayer.hide(); - this.layerManager.insert(this.messagesLayer, false); - - this.render(); - } - - PixiView.prototype.showDefaultLayers = function() { - this.ghostLayer.show(); - this.swiperLayer.show() - this.debugLayer.show(); - this.messagesLayer.show(); - }; - - PixiView.prototype.render = function () { - - if (this.me) { - this.layerManager.render(this.calculateCenterPosition(), this.currentZoom); - } - - this.renderer.render(this.stage); - } - - PixiView.prototype.initPointerLockView = function() { - if (!Settings.ENABLE_POINTER_LOCK_FILTER) return; - - var blurFilter = new PIXI.BlurFilter(); - blurFilter.blurX = 42 * this.currentZoom; - blurFilter.blurY = 42 * this.currentZoom; - - var pixelFilter = new PIXI.PixelateFilter(); - pixelFilter.pixelSize = 10 * this.currentZoom ; - - var grayFilter = new PIXI.GrayFilter(); - grayFilter.gray = 0.99; - this.pointerLockFilters = [pixelFilter, grayFilter]; - - this.clickToEnable = new PIXI.Text("Click to start playing."); - this.clickToEnable.visible = false; - this.stage.addChild(this.clickToEnable) - }; - - PixiView.prototype.onPointerLockChange = function(isLocked, options) { - if (!Settings.ENABLE_POINTER_LOCK_FILTER) return; - - if(isLocked) { - this.removeFilters(this.pointerLockFilters); - - this.clickToEnable.visible = false; - this.onZoomReset(); - } else { - - if(!options || options.start !== true) { - this.clickToEnable.setText("Click to continue playing."); - } - - this.clickToEnable.setStyle({ - font: "normal " + (14 * this.currentZoom) + "px 'Joystix'", - fill: "#ffffff", - stroke: "rgba(0,0,0,0.8)", - strokeThickness: 6 * this.currentZoom - }); - - this.addFilters(this.pointerLockFilters); - this.pointerLockFilters.forEach(function(filter) { filter.dirty = true; }); - - this.clickToEnable.position = new PIXI.Point(Settings.STAGE_WIDTH / 2 - this.clickToEnable.width / 2, Settings.STAGE_HEIGHT / 2 - this.clickToEnable.height / 2) - this.clickToEnable.visible = true; - - this.onZoomReset(); - this.currentZoom *= 0.9; - } - }; - - PixiView.prototype.removeFilters = function(filters) { - - if(this.container && this.container.filters && this.container.filters.length) { - for (var i = this.container.filters.length - 1; i >= 0; i--) { - - for (var j = filters.length - 1; j >= 0; j--) { - if (filters[j] === this.container.filters[i]) { - this.container.filters.splice(i, 1); - } - } - } - - // weird bug, filters.length cant be 0, must be set to null - if(this.container.filters.length < 1) { - this.container.filters = null; - } - } - - }; - - PixiView.prototype.addFilters = function(filters) { - if (filters.length < 1) return; - if (!this.container) { - return; - } - - if (!this.container.filters) { - /* - * slice does a copy, which is important here - - * otherwise this.pointerLockFilters will be manipulated too on remove. - */ - this.container.filters = filters.slice(); - return; - } - - for (var i = 0; i < filters.length; i++) { - this.container.filters.push(filters[i]); - } - }; - - PixiView.prototype.calculateCenterPosition = function() { - var target = this.me.getHeadPosition(); - - var centerPosition = {x: target.x, y: target.y}; - centerPosition.x *= Settings.RATIO * -1; - centerPosition.y *= Settings.RATIO * -1; - - var lookAt = this.me.getLookAt(); - centerPosition.x -= lookAt.x * 600 / 4; - centerPosition.y += lookAt.y * 400 / 4; - - return centerPosition; - }; - - PixiView.prototype.onDisplaySizeChange = function(isFullScreen) { - Parent.prototype.onDisplaySizeChange.call(this, isFullScreen); - - this.renderer.resize(window.innerWidth, window.innerHeight); - this.currentZoom = window.innerWidth / 600; - - pointerLockManager.update(null, {}); // only to reposition clickToEnable text - }; - - PixiView.prototype.initLoader = function() { - this.loader = new PIXI.Graphics(); - this.stage.addChild(this.loader); - this.onUpdateLoader(0); - }; - - PixiView.prototype.onUpdateLoader = function(progress) { - var width = 200, - height = 5, - borderWidth = 1; - - if(progress < 100) { - this.loader.clear(); - - this.loader.beginFill(0x000000); - this.loader.lineStyle(borderWidth, 0x000000); - this.loader.drawRect(0, 0, width, height); - this.loader.endFill(); - - if(progress > 0) { - var color = 0xFF0FA3; - this.loader.beginFill(color); - this.loader.lineStyle(0, 0x000000); - this.loader.drawRect(borderWidth, borderWidth, width * progress / 100, height); - this.loader.endFill(); - } - - this.loader.position = new PIXI.Point( - Settings.STAGE_WIDTH / 2 - width / 2 - borderWidth, - Settings.STAGE_HEIGHT / 2 - height / 2 - borderWidth - ); - } - - this.loader.visible = progress < 100; - }; - - PixiView.prototype.onZoomIn = function() { - if(this.currentZoom + Settings.ZOOM_FACTOR <= Settings.ZOOM_MAX) { - this.currentZoom += Settings.ZOOM_FACTOR; - } - }; - - PixiView.prototype.onZoomOut = function() { - //if(this.currentZoom - Settings.ZOOM_FACTOR > window.innerWidth / 600) { - this.currentZoom -= Settings.ZOOM_FACTOR; - //} - }; - - PixiView.prototype.onZoomReset = function() { - this.currentZoom = window.innerWidth / 600; - }; - - PixiView.prototype.getTexturesFromFrame = function(textureNames) { - - var textures = []; - - for (var i = 0; i < textureNames.length; i++) { - textures.push(PIXI.Texture.fromFrame(textureNames[i])); - }; - - return textures; - }; - - PixiView.prototype.destroy = function() { - - this.layerManager.destroy(); // also calls all layers destroy - - for (var i = 0; i < this.stage.children.length; i++) { - this.stage.removeChild(this.stage.children[i]); - } - - this.renderer.render(this.stage); - - this.renderer.destroy(); - delete this.renderer; - - Parent.prototype.destroy.call(this); - }; - - return PixiView; -}); diff --git a/app/Game/Client/View/ViewManager.js b/app/Game/Client/View/ViewManager.js index f935357..3e3da85 100755 --- a/app/Game/Client/View/ViewManager.js +++ b/app/Game/Client/View/ViewManager.js @@ -1,24 +1,22 @@ define([ "Game/Config/Settings", "Lib/Utilities/Exception", - "Game/Client/View/Abstract/View", - //"Game/Client/View/Three/View", - "Game/Client/View/Pixi/View", + "Game/Client/View/Views/AbstractView", + //"Game/Client/View/Views/ThreeView", + "Game/Client/View/Views/PixiView", "Lib/Utilities/NotificationCenter" ], -function (Settings, Exception, AbstractView, PixiView, nc) { - - "use strict"; +function (Settings, Exception, AbstractView, PixiView, Nc) { var ViewManager = {}; ViewManager.createView = function() { var view = null switch(Settings.VIEW_CONTROLLER) { - //case 'Three': - // view = new ThreeView(); - // break; + case 'Three': + view = new ThreeView(); + break; case 'Pixi': view = new PixiView(); break; @@ -38,6 +36,8 @@ function (Settings, Exception, AbstractView, PixiView, nc) { throw new Exception("In the view", Settings.VIEW_CONTROLLER + 'View', "this.setCanvas(canvas) has not been called with a valid HTMLCanvasElement!"); } + Nc.trigger(Nc.ns.client.view.events.ready, view); + return view; } diff --git a/app/Game/Client/View/Views/AbstractView.js b/app/Game/Client/View/Views/AbstractView.js new file mode 100755 index 0000000..8afb1ba --- /dev/null +++ b/app/Game/Client/View/Views/AbstractView.js @@ -0,0 +1,165 @@ +define([ + "Game/Client/View/DomController", + "Game/Config/Settings", + "Lib/Utilities/Exception", + "Lib/Utilities/NotificationCenter" +], + +function (DomController, Settings, Exception, Nc) { + + function AbstractView () { + this.me = null; + this.canvas = null; + this.debugMode = false; + + this.ncTokens = [ + Nc.on(Nc.ns.client.view.mesh.create, this.createMesh, this), + Nc.on(Nc.ns.client.view.animatedMesh.create, this.createAnimatedMesh, this), + Nc.on(Nc.ns.client.view.mesh.add, this.addMesh, this), + Nc.on(Nc.ns.client.view.mesh.remove, this.removeMesh, this), + Nc.on(Nc.ns.client.view.mesh.update, this.updateMesh, this), + + Nc.on(Nc.ns.client.view.fullscreen.change, this.onFullscreenChange, this), + Nc.on(Nc.ns.client.view.debugMode.toggle, this.onToggleDebugMode, this), + + Nc.on(Nc.ns.client.view.playerInfo.createAndAdd, this.onCreateAndAddPlayerInfo, this), + Nc.on(Nc.ns.client.view.playerInfo.update, this.onUpdatePlayerInfo, this), + Nc.on(Nc.ns.client.view.playerInfo.remove, this.onRemovePlayerInfo, this), + + Nc.on(Nc.ns.client.view.preloadBar.update, this.onUpdateLoader, this), + ]; + + + } + + AbstractView.prototype.isWebGlEnabled = function () { + try { + return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); + } catch(e) { + return false; + } + } + + AbstractView.prototype.initCanvas = function (canvas) { + + this.canvas = canvas; + DomController.initCanvas(canvas); + } + + AbstractView.prototype.loadPlayerMesh = function(player) { + throw new Exception('Abstract Function loadPlayerMesh not overwritten'); + }; + + AbstractView.prototype.loadMeshes = function(objects) { + throw new Exception('Abstract Function loadMeshes not overwritten'); + }; + + AbstractView.prototype.render = function () { + throw new Exception('Abstract Function render not overwritten'); + } + + AbstractView.prototype.createMesh = function (texturePath, callback, options) { + throw new Exception('Abstract Function createMesh not overwritten'); + } + + AbstractView.prototype.createAnimatedMesh = function (texturePaths, callback, options) { + throw new Exception('Abstract Function createAnimatedMesh not overwritten'); + } + + AbstractView.prototype.addMesh = function(mesh) { + throw new Exception('Abstract Function addMesh not overwritten'); + }; + + AbstractView.prototype.removeMesh = function(mesh) { + throw new Exception('Abstract Function removeMesh not overwritten'); + }; + + AbstractView.prototype.updateMesh = function(mesh, options) { + throw new Exception('Abstract Function updateMesh not overwritten'); + }; + + AbstractView.prototype.setMe = function(player) { + this.me = player; + }; + + AbstractView.prototype.addPlayer = function(player) { + throw new Exception('Abstract Function addPlayer not overwritten'); + }; + + AbstractView.prototype.removPlayer = function(player) { + throw new Exception('Abstract Function removPlayer not overwritten'); + }; + + AbstractView.prototype.setCameraPosition = function (x, y) { + throw new Exception('Abstract Function setCameraPosition not overwritten'); + } + + AbstractView.prototype.calculateCameraPosition = function() { + var reference = this.me.getPosition(); + var pos = {}; + + pos.x = reference.x; + pos.y = reference.y; + + pos.x = pos.x * Settings.RATIO; + pos.y = -(pos.y * Settings.RATIO); + + pos.x += this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4; + pos.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4; + + return pos; + }; + + AbstractView.prototype.setCameraZoom = function (z) { + throw new Exception('Abstract Function setCameraZoom not overwritten'); + }; + + AbstractView.prototype.onFullscreenChange = function(isFullScreen) { + + if (!isFullScreen) { + Settings.STAGE_WIDTH = 600; + Settings.STAGE_HEIGHT = 400; + } else { + // FIXME: Create FIXME meme (dumb and dumber) + // FIXME: don't overwrite Settings + Settings.STAGE_WIDTH = window.innerWidth; + Settings.STAGE_HEIGHT = window.innerHeight; + } + }; + + AbstractView.prototype.onToggleDebugMode = function(debugMode) { + if(debugMode) { + this.setCameraPosition(-Settings.STAGE_WIDTH / 2, -Settings.STAGE_HEIGHT / 2); + } + + this.debugMode = debugMode; + }; + + AbstractView.prototype.toggleInfo = function(show, string) { + throw new Exception('Abstract Function showInfo not overwritten'); + }; + + AbstractView.prototype.onCreateAndAddPlayerInfo = function(options) { + throw new Exception('Abstract Function onCreateAndAddPlayerInfo not overwritten'); + }; + + AbstractView.prototype.onUpdatePlayerInfo = function(playerInfo, options) { + throw new Exception('Abstract Function onUpdatePlayerInfo not overwritten'); + }; + + AbstractView.prototype.onRemovePlayerInfo = function(playerInfo) { + throw new Exception('Abstract Function onRemovePlayerInfo not overwritten'); + }; + + AbstractView.prototype.onUpdateLoader = function(progress) { + throw new Exception('Abstract Function onUpdateLoader not overwritten'); + }; + + AbstractView.prototype.destroy = function() { + for (var i = 0; i < this.ncTokens.length; i++) { + Nc.off(this.ncTokens[i]); + }; + }; + + return AbstractView; +}); \ No newline at end of file diff --git a/app/Game/Client/View/Views/PixiView.js b/app/Game/Client/View/Views/PixiView.js new file mode 100755 index 0000000..d35b18a --- /dev/null +++ b/app/Game/Client/View/Views/PixiView.js @@ -0,0 +1,320 @@ +define([ + "Game/Client/View/Views/AbstractView", + "Game/Client/View/DomController", + "Lib/Vendor/Pixi", + "Game/Config/Settings", + "Lib/Utilities/NotificationCenter" +], + +function (Parent, DomController, PIXI, Settings, Nc) { + + function PixiView () { + + Parent.call(this); + + this.movableObjects = []; + this.stage = null; + this.container = null; + this.infoContainer = null; + this.infoFilters = []; + this.infoBox = null; + this.loader = null; + this.init(); + this.pixi = PIXI; + + PIXI.scaleModes.DEFAULT = PIXI.scaleModes.NEAREST; + } + + + PixiView.prototype = Object.create(Parent.prototype); + + PixiView.prototype.init = function () { + + var transparent = false; + var antialias = true; + var canvas = DomController.getCanvas(); + + if(Settings.USE_WEBGL) { + this.renderer = new PIXI.WebGLRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, canvas, transparent, antialias); + console.log('WebGLRenderer') + } else { + this.renderer = new PIXI.CanvasRenderer(Settings.STAGE_WIDTH, Settings.STAGE_HEIGHT, canvas, transparent, antialias); + console.log('CanvasRenderer - not using WebGL!') + } + + this.stage = new PIXI.Stage(0x333333); + + this.initCamera(); + this.initInfo(); + this.initLoader(); + + this.initCanvas(this.renderer.view); + } + + PixiView.prototype.render = function () { + if(this.me) { + var pos = this.calculateCameraPosition(); + this.setCameraPosition(pos.x, pos.y); + } + + this.renderer.render(this.stage); + } + + // Meshes + + PixiView.prototype.addMesh = function(mesh) { + this.container.addChild(mesh); + }; + + PixiView.prototype.removeMesh = function(mesh) { + this.container.removeChild(mesh); + }; + + PixiView.prototype.createMesh = function (texturePath, callback, options) { + + var texture = PIXI.Texture.fromImage(texturePath); + + var mesh = new PIXI.Sprite(texture); + + if(options) this.updateMesh(mesh, options); + + callback(mesh); + } + + PixiView.prototype.createAnimatedMesh = function (texturePaths, callback, options) { + var textures = []; + for (var i = 0; i < texturePaths.length; i++) { + var texture = PIXI.Texture.fromImage(texturePaths[i]); + texture.width = options.width; + texture.height = options.height; + PIXI.texturesToUpdate.push(texture); + textures.push(texture); + } + + var mesh = new PIXI.MovieClip(textures); + if(options) this.updateMesh(mesh, options); + + mesh.animationSpeed = 0.5; + + mesh.play(); + + callback(mesh); + } + + PixiView.prototype.updateMesh = function(mesh, options) { + if (options.x) mesh.position.x = options.x; + if (options.y) mesh.position.y = options.y; + if (options.rotation) mesh.rotation = options.rotation; + if (options.width) mesh.width = options.width; + if (options.height) mesh.height = options.height; + if (options.xScale) mesh.width = Math.abs(mesh.width) * options.xScale; + if (options.yScale) mesh.scale.y = options.yScale; + if (options.visible === true || options.visible === false) mesh.visible = options.visible; + if (options.pivot) mesh.pivot = new PIXI.Point(options.pivot.x, options.pivot.y); + } + + // Camera + + PixiView.prototype.initCamera = function () { + this.container = new PIXI.DisplayObjectContainer(); + this.stage.addChild(this.container); + } + + PixiView.prototype.calculateCameraPosition = function() { + var zoom = this.container.scale.x; + + var target = this.me.getHeadPosition(); + target.x *= -Settings.RATIO * zoom; + target.y *= -Settings.RATIO * zoom; + + target.x -= this.me.playerController.xyInput.x * Settings.STAGE_WIDTH / 4; + target.y += this.me.playerController.xyInput.y * Settings.STAGE_HEIGHT / 4; + + var pos = this.getCameraPosition(); + + pos.x += (target.x -pos.x) * Settings.CAMERA_GLIDE / 100; + pos.y += (target.y -pos.y) * Settings.CAMERA_GLIDE / 100; + + return pos; + }; + + PixiView.prototype.setCameraPosition = function (x, y) { + if(!this.debugMode) { + this.container.position.x = x + Settings.STAGE_WIDTH / 2; + this.container.position.y = y + Settings.STAGE_HEIGHT / 2; + } + }; + + PixiView.prototype.getCameraPosition = function () { + var pos = this.container.position; + + pos.x = pos.x - Settings.STAGE_WIDTH / 2; + pos.y = pos.y - Settings.STAGE_HEIGHT / 2; + + return pos; + }; + + PixiView.prototype.setCameraZoom = function (z) { + this.container.scale.x = z; + this.container.scale.y = z; + + }; + + PixiView.prototype.onFullscreenChange = function(isFullScreen) { + Parent.prototype.onFullscreenChange.call(this, isFullScreen); + + if(isFullScreen) { + this.renderer.resize(window.innerWidth, window.innerHeight); + this.setCameraZoom(window.innerWidth / 600); + } else { + this.renderer.resize(600, 400); + this.setCameraZoom(1); + } + }; + + // Info Overlay + + PixiView.prototype.initInfo = function() { + this.infoContainer = new PIXI.DisplayObjectContainer(); + this.stage.addChild(this.infoContainer); + + var blurFilter = new PIXI.BlurFilter(); + blurFilter.blurX = 12; + blurFilter.blurY = 12; + var grayFilter = new PIXI.GrayFilter(); + grayFilter.gray = 0.85; + this.infoFilters = [blurFilter, grayFilter]; + + this.infoText = new PIXI.Text("", {font: "normal 20px monospace", fill: "red", align: "center"}); + this.infoBox = new PIXI.Graphics(); + this.infoBox.alpha = 0.7; + + this.infoContainer.addChild(this.infoBox); + this.infoContainer.addChild(this.infoText); + + this.infoContainer.visible = false; + }; + + PixiView.prototype.toggleInfo = function(show, string) { + if(show) { + this.infoText.setText(string); + this.infoText.updateText(); + this.infoText.dirty = false; + + var x = Settings.STAGE_WIDTH / 2 - this.infoText.width / 2, + y = Settings.STAGE_HEIGHT / 2 - this.infoText.height / 2; + this.infoText.position = new PIXI.Point(x, y); + + var borderWidth = 3; + var padding = 20; + this.infoBox.clear(); + this.infoBox.beginFill(0x000000); + this.infoBox.lineStyle(borderWidth, 0xAA0000); + this.infoBox.drawRect(0, 0, this.infoText.width - borderWidth + 2 * padding * 2, this.infoText.height - borderWidth + 2 * padding); + this.infoBox.endFill(); + this.infoBox.position.x = this.infoText.position.x + borderWidth/2 - padding * 2; + this.infoBox.position.y = this.infoText.position.y + borderWidth/2 - padding; + + this.infoContainer.visible = true; + this.container.filters = this.infoFilters; + this.infoFilters.forEach(function(filter) { filter.dirty = true; }); + } else { + this.infoText.setText("..."); + this.infoContainer.visible = false; + this.container.filters = null; + } + }; + + // Player Info + + PixiView.prototype.onCreateAndAddPlayerInfo = function(callback, options) { + var playerInfo = new PIXI.Graphics(); + this.container.addChild(playerInfo); + + this.onUpdatePlayerInfo(playerInfo, options); + + callback(playerInfo); + }; + + PixiView.prototype.onUpdatePlayerInfo = function(playerInfo, options) { + var width = 14, + height = 2, + borderWidth = 1, + offsetX = -8, + offsetY = -52; + + if(typeof options.healthFactor != 'undefined') { + playerInfo.clear(); + + playerInfo.beginFill(0x000000); + playerInfo.lineStyle(borderWidth, 0x000000); + playerInfo.drawRect(0, 0, width, height); + playerInfo.endFill(); + + if(options.healthFactor > 0) { + var color = 0x00FF00; + if(options.healthFactor < 0.30) color = 0xFF0000; + playerInfo.beginFill(color); + playerInfo.lineStyle(0, 0x000000); + playerInfo.drawRect(borderWidth, borderWidth, width * options.healthFactor, height); + playerInfo.endFill(); + } + } + + if (options.x && options.y) playerInfo.position = new PIXI.Point(offsetX + options.x, offsetY + options.y); + if (options.visible === true || options.visible === false) playerInfo.visible = options.visible; + }; + + PixiView.prototype.onRemovePlayerInfo = function(playerInfo) { + this.container.removeChild(playerInfo); + }; + + PixiView.prototype.initLoader = function() { + this.loader = new PIXI.Graphics(); + this.stage.addChild(this.loader); + this.onUpdateLoader(0); + }; + + PixiView.prototype.onUpdateLoader = function(progress) { + var width = 200, + height = 5, + borderWidth = 1; + + if(progress < 100) { + this.loader.clear(); + + this.loader.beginFill(0x000000); + this.loader.lineStyle(borderWidth, 0x000000); + this.loader.drawRect(0, 0, width, height); + this.loader.endFill(); + + if(progress > 0) { + var color = 0xFF0FA3; + this.loader.beginFill(color); + this.loader.lineStyle(0, 0x000000); + this.loader.drawRect(borderWidth, borderWidth, width * progress / 100, height); + this.loader.endFill(); + } + + this.loader.position = new PIXI.Point( + Settings.STAGE_WIDTH / 2 - width / 2 - borderWidth, + Settings.STAGE_HEIGHT / 2 - height / 2 - borderWidth + ); + } + + this.loader.visible = progress < 100; + }; + + PixiView.prototype.destroy = function() { + + for (var i = 0; i < this.stage.children.length; i++) { + this.stage.removeChild(this.stage.children[i]); + } + + this.renderer.render(this.stage); + + Parent.prototype.destroy.call(this); + }; + + return PixiView; +}); diff --git a/app/Game/Client/View/Three/View.js b/app/Game/Client/View/Views/ThreeView.js similarity index 94% rename from app/Game/Client/View/Three/View.js rename to app/Game/Client/View/Views/ThreeView.js index e653802..d24963f 100755 --- a/app/Game/Client/View/Three/View.js +++ b/app/Game/Client/View/Views/ThreeView.js @@ -1,12 +1,11 @@ define([ - "Game/Client/View/Abstract/View", + "Game/Client/View/Views/AbstractView", + "Game/Client/View/DomController", "Lib/Vendor/Three", "Game/Config/Settings" ], -function (Parent, Three, Settings) { - - "use strict"; +function (Parent, DomController, Three, Settings) { function ThreeView () { Parent.call(this); diff --git a/app/Game/Config/ItemSettings.js b/app/Game/Config/ItemSettings.js index 8724c0a..e01e953 100644 --- a/app/Game/Config/ItemSettings.js +++ b/app/Game/Config/ItemSettings.js @@ -1,14 +1,7 @@ -define([ -], - -function () { - - "use strict"; +define(function() { var ItemSettings = { - // weight is a number between 0.1 for very light and 10 for very heavy - "Default": { "category": "", @@ -22,7 +15,7 @@ function () { "rotation": "0", "bounce": "0", "grabAngle": "-1.5", - "danger": "0", + "danger": "1", "bodyType": "dynamic", }, @@ -32,7 +25,7 @@ function () { "image": "chest.png", "type": "ragdoll", - "weight": "7", + "weight": "5", "width": "6", "height": "12", @@ -207,7 +200,7 @@ function () { "category": "kitchen", "image": "fridge.gif", - "weight": "5", + "weight": "10", "width": "31", "height": "53", @@ -220,12 +213,11 @@ function () { "category": "kitchen", "image": "microwave.gif", - "weight": "4.6", + "weight": "3.6", "width": "19", "height": "12", "grabAngle": "-0.1", - "danger": "2", }, "Coffeemachine": @@ -248,24 +240,12 @@ function () { "height": "9", }, - "Table": - { - "category": "kitchen", - "image": "table.gif", - - "weight": "3.5", - "width": "60", - "height": "21", - - "grabAngle": "-0.2", - }, - "Banana": { "category": "kitchen", "image": "banana.gif", - "weight": "3", + "weight": "1", "width": "5", "height": "9", @@ -335,45 +315,6 @@ function () { "grabAngle": "-0.2", }, - "Couch": - { - "category": "livingroom", - "image": "couch.gif", - - "weight": "7", - "width": "50", - "height": "29", - "bounce": "3", - - "grabAngle": "-0.2", - }, - - "Cactus": - { - "category": "livingroom", - "image": "cactus.gif", - - "weight": "2.5", - "width": "17", - "height": "31", - - "danger": "1.9", - - "grabAngle": "-0.2", - }, - - "Piano": - { - "category": "livingroom", - "image": "piano.gif", - - "weight": "10", - "width": "66", - "height": "48", - - "grabAngle": "-0.2", - }, - "Bible": { "category": "livingroom", @@ -411,19 +352,21 @@ function () { }, - "RubeDoll": + + + "Rube": { "category": "kitchen", "image": "banana.gif", - - "weight": "3", - "width": "15", + + // "type": "rube", + "weight": "1", + "width": "5", "height": "9", - "type": "rubedoll", - "grabAngle": "0.001", // seems to be a bug, that 0 does not work! + "grabAngle": "0.5", } - }; + } return ItemSettings; }); \ No newline at end of file diff --git a/app/Game/Config/Settings.js b/app/Game/Config/Settings.js index 10cf76f..d856841 100755 --- a/app/Game/Config/Settings.js +++ b/app/Game/Config/Settings.js @@ -1,68 +1,50 @@ - define([ -], - -function () { - - "use strict"; +define(function() { var Settings = { STAGE_WIDTH: 600, STAGE_HEIGHT: 400, - ZOOM_FACTOR: 0.8, - ZOOM_DEFAULT: 1, - ZOOM_MAX: 10, // BOX2D INITIALATORS BOX2D_WORLD_AABB_SIZE: 3000, BOX2D_ALLOW_SLEEP: true, BOX2D_GRAVITY: 26, - BOX2D_VELOCITY_ITERATIONS: 20, - BOX2D_POSITION_ITERATIONS: 10, // 200/100 created problems (awful teleporting when repositioning joints) + BOX2D_VELOCITY_ITERATIONS: 5, + BOX2D_POSITION_ITERATIONS: 5, BOX2D_TIME_STEP: 1 / 60, // PATHS - GRAPHICS_PATH: "static/img/", - GRAPHICS_SUBPATH_ITEMS: "Items/", - GRAPHICS_SUBPATH_CHARACTERS: "Characters/", - GRAPHICS_SUBPATH_TILES: "Tiles/", - MAPS_PATH: "static/maps/tiled/", - AUDIO_PATH: "static/sounds/", - CHANNEL_RECORDING_PATH: "recordings/", - CHANNEL_PLAY_RECORDING: false, //"Varberg-2015-03-15T23:10:29.316Z-stones.log", + GRAPHICS_PATH: 'static/img/', + GRAPHICS_SUBPATH_ITEMS: 'Items/', + GRAPHICS_SUBPATH_CHARACTERS: 'Characters/', + GRAPHICS_SUBPATH_TILES: 'Tiles/', + MAPS_PATH: 'static/maps/tiled/', RATIO: 21, //35 // original tile size is 25 but we want it to resize to 20 ORIGINAL_TILE_SIZE: 25, TILE_SIZE: 20, CAMERA_IS_ORTHOGRAPHIC: true, - CAMERA_GLIDE: 6, // % of the way per frame - VIEW_CONTROLLER: 0 ? "Three" : "Pixi", - ARROW_GLIDE: 30, // % of the way per frame - SHOW_LAYER_INFO: false, - ENABLE_POINTER_LOCK_FILTER: true, + CAMERA_GLIDE: 12, // % of the way per frame + VIEW_CONTROLLER: 0 ? 'Three' : 'Pixi', // GAME PLAY WALK_SPEED: 4, RUN_SPEED: 8, FLY_SPEED: 6.2, - JUMP_SPEED: 16, - JUMP_STOP_DAMPING_FACTOR: 0.4, - MAX_THROW_FORCE: 28, - MAX_THROW_ANGULAR_VELOCITY: 3, + JUMP_SPEED: 20, + JUMP_STOP_DAMPING_FACTOR: 0.5, + MAX_THROW_FORCE: 18 * 3.5, + MAX_THROW_ANGULAR_VELOCITY: 0, MAX_RUNNING_WEIGHT: 9, RESPAWN_TIME: 5, HEALTH_DISPLAY_TIME: 2, - CRITICAL_HEALTH_THRESHOLD: 0.3, - RAGDOLL_DESTRUCTION_TIME: 10, - VIEWPORT_SPEED_FACTOR: 640, - VIEWPORT_LOOK_AHEAD: 0.1, - SCORE_MESSAGE_TIMEOUT: 3500, + RAGDOLL_DESTRUCTION_TIME: 20, // restitution: bouncyness, friction: rubbing, density: mass TILE_FRICTION: 0.99, TILE_RESTITUTION: 0.1, - PLAYER_DENSITY: 12.2, //3.68, + PLAYER_DENSITY: 3.68, PLAYER_FRICTION: 5, PLAYER_MOTION_FRICTION: 0.1, PLAYER_RESTITUTION: 0.0, @@ -74,29 +56,27 @@ function () { ITEM_LINEAR_DAMPING: 0.02, // BROWSER - CANVAS_DOM_ID: "canvasContainer", - IS_BROWSER_ENVIRONMENT: typeof window !== "undefined", + CANVAS_DOM_ID: 'canvasContainer', + IS_BROWSER_ENVIRONMENT: typeof window !== 'undefined', USE_WEBGL: true, // NETWORKING - NETWORK_UPDATE_INTERVAL: 70, // in milliseconds + NETWORK_UPDATE_INTERVAL: 70, + CHANNEL_DESTRUCTION_TIME: 30, NETWORK_LOG_INCOMING: false, NETWORK_LOG_OUTGOING: false, - NETWORK_LOG_FILTER: ["ping", "pong", "worldUpdate", "lookAt"], + NETWORK_LOG_FILTER: ['ping', 'pong', 'worldUpdate', 'lookAt'], // CHANNEL - CHANNEL_MAX_USERS: 20, - CHANNEL_DESTRUCTION_TIME: 0.5 * 60, - CHANNEL_END_ROUND_TIME: 20, //10, - CHANNEL_DEFAULT_MAX_USERS: 10, - CHANNEL_DEFAULT_SCORE_LIMIT: 5, - CHANNEL_DEFAULT_LEVELS: ["debug"], - CHANNEL_RECORD_SESSION: false, + CHANNEL_END_ROUND_TIME: 4, //10, + CHANNEL_DEFAULT_MAX_USERS: 40, + CHANNEL_DEFAULT_SCORE_LIMIT: 10, + CHANNEL_DEFAULT_LEVELS: ['stones2', 'debug', 'stones2', 'debug'], // ME STATE ME_STATE_MAX_DIFFERENCE_METERS: 1, PUNKBUSTER_DIFFERENCE_METERS: 1 - }; + } Settings.TILE_RATIO = Settings.ORIGINAL_TILE_SIZE / Settings.TILE_SIZE; diff --git a/app/Game/Core/Collision/Detector.js b/app/Game/Core/Collision/Detector.js index 3849541..e4994f5 100755 --- a/app/Game/Core/Collision/Detector.js +++ b/app/Game/Core/Collision/Detector.js @@ -4,8 +4,6 @@ define([ function (Box2D) { - "use strict"; - function Detector () { this.listener = new Box2D.Dynamics.b2ContactListener(); this.listener.BeginContact = this.beginContact.bind(this); diff --git a/app/Game/Core/Control/PlayerController.js b/app/Game/Core/Control/PlayerController.js index d264152..97189cb 100755 --- a/app/Game/Core/Control/PlayerController.js +++ b/app/Game/Core/Control/PlayerController.js @@ -1,21 +1,20 @@ -define([ -], - -function () { +define(function () { function PlayerController (player) { + this.player = player; + + this._shift; + this._isJumping; this._walkingDirectionStatus = 0; } PlayerController.prototype.moveLeft = function () { - if(!this.isPlayerInputAllowed()) return; this.player.move(-1); this._walkingDirectionStatus = -1; } PlayerController.prototype.moveRight = function () { - if(!this.isPlayerInputAllowed()) return; this.player.move(1); this._walkingDirectionStatus = 1; } @@ -26,7 +25,7 @@ function () { } PlayerController.prototype.jump = function () { - if(!this.isPlayerInputAllowed()) return; + this._isJumping = true; this.player.jump(); } @@ -35,31 +34,15 @@ function () { } PlayerController.prototype.lookAt = function (options) { - if(!this.isPlayerInputAllowed()) return; if(options) this.player.lookAt(options.x, options.y); } - PlayerController.prototype.activateModifier = function() { - if (!this.isPlayerInputAllowed()) return; - this.player.activateModifier(); - }; - - PlayerController.prototype.deactivateModifier = function() { - if (!this.isPlayerInputAllowed()) return; - this.player.deactivateModifier(); - }; - PlayerController.prototype.update = function () { if(this._walkingDirectionStatus != 0) { this.player.move(this._walkingDirectionStatus); } } - // Default behaviour - may be needed later? - PlayerController.prototype.isPlayerInputAllowed = function() { - return true; - }; - PlayerController.prototype.destroy = function() { // extend if necessary }; diff --git a/app/Game/Core/GameController.js b/app/Game/Core/GameController.js index caea9c3..e84747b 100755 --- a/app/Game/Core/GameController.js +++ b/app/Game/Core/GameController.js @@ -4,28 +4,24 @@ define([ "Game/" + GLOBALS.context + "/Player", "Lib/Utilities/NotificationCenter", "Game/" + GLOBALS.context + "/GameObjects/Doll", - "Game/" + GLOBALS.context + "/GameObjects/GameObject", - "Game/" + GLOBALS.context + "/GameObjects/Item", - "Lib/Utilities/Assert", ], -function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert) { - - "use strict"; +function (PhysicsEngine, TiledLevel, Player, Nc, Doll) { function GameController (options) { this.options = options; this.players = {}; this.level = null; - this.worldUpdateObjects = {}; + this.gameObjects = null; + this.resetGameObjects(); this.physicsEngine = new PhysicsEngine(); this.physicsEngine.setCollisionDetector(); this.ncTokens = [ - nc.on(nc.ns.core.game.worldUpdateObjects.add, this.onWorldUpdateObjectAdd, this), - nc.on(nc.ns.core.game.worldUpdateObjects.remove, this.onWorldUpdateObjectRemove, this) + Nc.on(Nc.ns.core.game.gameObject.add, this.onGameObjectAdd, this), + Nc.on(Nc.ns.core.game.gameObject.remove, this.onGameObjectRemove, this) ]; this.loadLevel(options.levelUid); @@ -37,61 +33,46 @@ function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert) // extend for both sides if necessary }; - GameController.prototype.onWorldUpdateObjectAdd = function(object) { - this.worldUpdateObjects[object.uid] = object; + GameController.prototype.resetGameObjects = function() { + this.gameObjects = { + fixed: [], + animated: [] + }; }; - GameController.prototype.onWorldUpdateObjectRemove = function(object) { - delete this.worldUpdateObjects[object.uid]; + GameController.prototype.onGameObjectAdd = function(type, object) { + this.gameObjects[type].push(object); + }; + + GameController.prototype.onGameObjectRemove = function(type, object) { + var i = this.gameObjects[type].indexOf(object); + if(i>=0) this.gameObjects[type].splice(i, 1); }; GameController.prototype.getPhysicsEngine = function () { return this.physicsEngine; - }; - - GameController.prototype.getItemByUid = function(uid) { - // FIXME : maybe divide this into a dedicated item pool? - return this.worldUpdateObjects[uid]; - }; + } GameController.prototype.loadLevel = function (levelUid) { if (this.level) { this.level.destroy(); - this.worldUpdateObjects = {}; + this.resetGameObjects(); } - this.level = new TiledLevel(levelUid, this.physicsEngine); - }; - - /* - * This is now in core, because the recorder/player - * uses the world update mechanism on the channel side - */ - GameController.prototype.onWorldUpdate = function (updateData) { - - for (var uid in updateData) { - - var gameObject = this.worldUpdateObjects[uid]; - - if (!(gameObject instanceof GameObject)) { - console.warn('Can\'t find object ' + uid + ' in worldUpdateObjects pool:', Object.keys(this.worldUpdateObjects)); - continue; - } - - this.updateGameObject(gameObject, updateData[uid]); - } - }; - - - GameController.prototype.updateGameObject = function(gameObject, gameObjectUpdate) { - gameObject.setUpdateData(gameObjectUpdate); + this.level = new TiledLevel(levelUid, this.physicsEngine, this.gameObjects); } GameController.prototype.onResetLevel = function() { this.loadLevel(this.level.uid); }; + /* + GameController.prototype.userJoined = function (user) { + this.players[user.id] = this.createPlayer(user); + } + */ + GameController.prototype.onUserLeft = function (userId) { var player = this.players[userId]; if(!player) { @@ -101,34 +82,47 @@ function (PhysicsEngine, TiledLevel, Player, nc, Doll, GameObject, Item, Assert) player.destroy(); delete this.players[userId]; - }; + } - GameController.prototype.createPlayer = function(user, revealedGameController) { - var player = new Player(user.id, this.physicsEngine, user, revealedGameController); + GameController.prototype.createPlayer = function(user) { + var player = new Player(user.id, this.physicsEngine, user); this.players[user.id] = player; return player; }; - GameController.prototype.destroy = function () { for(var player in this.players) { - this.players[player].destroy(); + // this.players[player].destroy(); + + // FIXME: + // commented out for now, because players are in gameObjects array. + // try using a real gameobject for the health bar } - // FIXME ns.client in core? - nc.trigger(nc.ns.client.game.events.destroy); + for (var i = 0; i < this.ncTokens.length; i++) { + Nc.off(this.ncTokens[i]); + }; - // Testing after destroy if worldUpdateObjects is empty - // events.game.destroy -> gameobjects.destroy() -> nc.trigger(worldUpdateObjects.remove) - if(Object.keys(this.worldUpdateObjects).length > 0) { - console.warn('Not all worldUpdateObjects have been removed... ', Object.keys(this.worldUpdateObjects)); - } + /* + * Contents of gameObject: Players, Items, Tiles, RagDolls + * No Dolls. + */ + + for (var key in this.gameObjects) { + for (var i = 0; i < this.gameObjects[key].length; i++) { + var gameObject = this.gameObjects[key][i]; + + gameObject.destroy(); + }; + }; + + this.gameObjects = { + fixed: [], + animated: [] + }; this.physicsEngine.destroy(); - this.worldUpdateObjects = null; - - nc.off(this.ncTokens); - }; + } return GameController; }); diff --git a/app/Game/Core/GameObjects/Doll.js b/app/Game/Core/GameObjects/Doll.js index 32c3e05..1847956 100755 --- a/app/Game/Core/GameObjects/Doll.js +++ b/app/Game/Core/GameObjects/Doll.js @@ -1,17 +1,13 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/GameObject", - "Lib/Utilities/Exception", "Lib/Vendor/Box2D", "Game/Config/Settings", "Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/GameObjects/Item", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Assert) { - - "use strict"; +function (Parent, Box2D, Settings, CollisionDetector, Item, Nc) { function Doll (physicsEngine, uid, player) { @@ -28,8 +24,8 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.standing = false; this.moveDirection = 0; this.lookDirection = 0; - this.legs = null; - this.footSensor = null; + this.legs; + this.footSensor; this.actionState = null; this.lookAtXY = { x:0, y:0 }; this.reachableItems = { @@ -40,12 +36,11 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.holdingJoint = null; this.holdingItem = null; - this.ragDoll = {head: null, body: null}; // FIXME: wtf is this? can we remove it? + this.ragDoll = {head: null, body: null}; this.createFixtures(); this.body.SetActive(false); - nc.trigger(nc.ns.core.game.worldUpdateObjects.add, this); } Doll.prototype = Object.create(Parent.prototype); @@ -61,10 +56,6 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser }; Doll.prototype.createFixtures = function () { - Assert.number(this.width, this.height); - Assert.number(this.reachDistance); - Assert.number(this.areaSize); - var self = this; var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); @@ -73,15 +64,13 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser fixtureDef.restitution = Settings.PLAYER_RESTITUTION; var headShape = new Box2D.Collision.Shapes.b2CircleShape(); - var radius = this.width / 2 / Settings.RATIO; - headShape.SetRadius(radius); - + headShape.SetRadius(this.width / 2 / Settings.RATIO); headShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(0, -(this.height - (this.width / 2)) / Settings.RATIO)); fixtureDef.shape = headShape; fixtureDef.isSensor = false; fixtureDef.userData = { onCollisionChange: this.onImpact.bind(this) - }; + } this.body.CreateFixture(fixtureDef); @@ -114,7 +103,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser fixtureDef.userData = { onCollisionChange: this.onFootSensorDetection.bind(this) - }; + } this.footSensor = this.body.CreateFixture(fixtureDef); @@ -133,7 +122,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser onCollisionChange: function(isColliding, fixture) { self.onFixtureWithinReach(isColliding, "left", fixture); } - }; + } this.body.CreateFixture(fixtureDef); var grabSensorRightShape = new Box2D.Collision.Shapes.b2PolygonShape(); @@ -152,7 +141,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser onCollisionChange: function(isColliding, fixture) { self.onFixtureWithinReach(isColliding, "right", fixture); } - }; + } this.body.CreateFixture(fixtureDef); @@ -171,7 +160,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser fixtureDef.userData = { onCollisionChange: function(isColliding, fixture) { - var userData = fixture.GetBody().GetUserData(); + var userData = fixture.GetBody().GetUserData() if(userData instanceof Doll) { var doll = userData; var i = self.nearbyDolls.indexOf(doll); @@ -186,29 +175,28 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser } } } - }; + } this.body.CreateFixture(fixtureDef); - }; + } Doll.prototype.setActionState = function(state) { this.actionState = state; - }; + } Doll.prototype.getActionState = function() { return this.actionState; - }; + } Doll.prototype.isWalking = function() { return ["walk", "walkback", "run"].indexOf(this.actionState) >= 0; - }; + } Doll.prototype.spawn = function (x, y) { - Assert.number(x, y); this.body.SetPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO)); this.body.SetActive(true); this.setActionState("fall"); - }; + } Doll.prototype.getHeadPosition = function() { var pos = this.body.GetPosition(); @@ -221,21 +209,19 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser Doll.prototype.setFriction = function (friction) { if(!friction) friction = -1; - Assert.number(friction); - if (this.legs.GetFriction() != friction) { this.legs.SetFriction(friction); } - }; + } - Doll.prototype.move = function (direction, modifierActivated) { + Doll.prototype.move = function (direction) { this.moveDirection = direction; var speed; var isHoldingHeavyItem = this.holdingItem && this.holdingItem.options.weight > Settings.MAX_RUNNING_WEIGHT; switch(true) { - case direction == this.lookDirection && this.isStanding() && !isHoldingHeavyItem && !modifierActivated: + case direction == this.lookDirection && this.isStanding() && !isHoldingHeavyItem: speed = Settings.RUN_SPEED; break; @@ -256,15 +242,13 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.setFriction(Settings.PLAYER_MOTION_FRICTION); this.body.SetAwake(true); - - Assert.number(speed, direction); var vector = new Box2D.Common.Math.b2Vec2(speed * direction, this.body.GetLinearVelocity().y); this.body.SetLinearVelocity(vector); if(this.isStanding()) { if(this.moveDirection == this.lookDirection) { - if(isHoldingHeavyItem || modifierActivated) { + if(isHoldingHeavyItem) { this.setActionState("walk"); } else { this.setActionState("run"); @@ -274,7 +258,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.setActionState("walkback"); } } - }; + } Doll.prototype.stop = function () { this.moveDirection = 0; @@ -286,20 +270,20 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser vector.x *= Settings.JUMP_STOP_DAMPING_FACTOR; this.body.SetLinearVelocity(vector); } - }; + } Doll.prototype.jump = function () { if (this.isStanding()) { this.body.SetAwake(true); - var vector = new Box2D.Common.Math.b2Vec2(0, -Settings.JUMP_SPEED); this.body.SetLinearVelocity(vector); this.setStanding(false); + this.setActionState("jump"); } - }; + } Doll.prototype.jumpStop = function () { if (!this.isStanding() ) { @@ -310,17 +294,17 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.body.SetLinearVelocity(vector); } } - }; + } Doll.prototype.setStanding = function (isStanding) { if (this.standing == isStanding) return; this.standing = isStanding; if(isStanding) this.setActionState("stand"); - }; + } Doll.prototype.isStanding = function () { return this.standing; - }; + } Doll.prototype.lookAt = function(x, y) { var oldLookDirection = this.lookDirection; @@ -354,12 +338,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser } var bodyPosition = this.body.GetPosition(); - - Assert.number(this.width, this.height); - Assert.number(this.lookDirection); var handPosition = new Box2D.Common.Math.b2Vec2( bodyPosition.x + ((this.width / 2 / Settings.RATIO) * this.lookDirection), - bodyPosition.y - this.height / 4 * 2 / Settings.RATIO // 2/3 of the body height + bodyPosition.y - this.height / 3 * 2 / Settings.RATIO // 2/3 of the body height ); this.holdingItem.reposition(handPosition, this.lookDirection); @@ -371,31 +352,19 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser } }; - Doll.prototype.throw = function(item, options) { - if(this.holdingJoint) { - this.body.GetWorld().DestroyJoint(this.holdingJoint); - } else { - // log stack if we called throw without a holdingJoint - var w = new Error("Throwing without a holdingJoint"); - console.error(w.message + "\n" + w.stack); - } - + Doll.prototype.throw = function(item, x, y) { + this.body.GetWorld().DestroyJoint(this.holdingJoint); this.holdingJoint = null; this.holdingItem = null; - var dollVelocity = { - x: this.body.GetLinearVelocity().x, - y: this.body.GetLinearVelocity().y - }; - - item.throw(options, dollVelocity); + item.throw(x, y); }; Doll.prototype.isAnotherPlayerNearby = function() { return this.nearbyDolls.length > 0; }; - Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { // jshint unused:false + Doll.prototype.onFootSensorDetection = function(isColliding, fixture) { var self = this; @@ -432,9 +401,9 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser self.setStanding(false); } } - }; + } - Doll.prototype.onImpact = function(isColliding, fixture) { // jshint unused:false + Doll.prototype.onImpact = function(isColliding, fixture) { // overwrite if necessary }; @@ -452,7 +421,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser this.reachableItems[side].splice(i, 1); } } - }; + } Doll.prototype.getVelocities = function() { return { @@ -463,7 +432,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser Doll.prototype.update = function() { - if (this.body.GetLinearVelocity().x === 0 && this.isWalking()) { + if (this.body.GetLinearVelocity().x == 0 && this.isWalking()) { this.stop(); } @@ -472,16 +441,7 @@ function (Parent, Exception, Box2D, Settings, CollisionDetector, Item, nc, Asser } }; - Doll.prototype.setUpdateData = function(update) { - - Parent.prototype.setUpdateData.call(this, update); - - this.setActionState(update.as); - this.lookAt(update.laxy.x, update.laxy.y); - }; - Doll.prototype.destroy = function() { - nc.trigger(nc.ns.core.game.worldUpdateObjects.remove, this); Parent.prototype.destroy.call(this); }; diff --git a/app/Game/Core/GameObjects/GameObject.js b/app/Game/Core/GameObjects/GameObject.js index a1eb12d..20553a1 100755 --- a/app/Game/Core/GameObjects/GameObject.js +++ b/app/Game/Core/GameObjects/GameObject.js @@ -1,24 +1,16 @@ define([ "Lib/Vendor/Box2D", - "Lib/Utilities/Exception", - "Lib/Utilities/Assert", - "Lib/Utilities/NotificationCenter" + "Lib/Utilities/Exception" ], -function (Box2D, Exception, Assert, nc) { - - "use strict"; +function (Box2D, Exception) { function GameObject(physicsEngine, uid) { this.uid = uid; var def = this.getBodyDef(); def.userData = this; - this.body = physicsEngine.createBody(def); - - this.ncTokens = (this.ncTokens || []).concat([ - nc.on(nc.ns.client.game.events.destroy, this.destroy, this) - ]); + this.body = physicsEngine.getWorld().CreateBody(def); } GameObject.prototype.getBodyDef = function() { @@ -26,14 +18,11 @@ function (Box2D, Exception, Assert, nc) { }; GameObject.prototype.destroy = function() { - if(this.body instanceof Box2D.Dynamics.b2Body) { this.body.GetWorld().DestroyBody(this.body); } else { throw new Exception("can not destroy body"); } - - nc.off(this.ncTokens); }; GameObject.prototype.getBody = function() { @@ -43,20 +32,6 @@ function (Box2D, Exception, Assert, nc) { GameObject.prototype.getPosition = function() { return this.body.GetPosition().Copy(); }; - - GameObject.prototype.setUpdateData = function(update) { - - Assert.number(update.p.x, update.p.y); - Assert.number(update.a); - Assert.number(update.lv.x, update.lv.y); - Assert.number(update.av); - - this.body.SetAwake(true); - this.body.SetPosition(update.p); - this.body.SetAngle(update.a); - this.body.SetLinearVelocity(update.lv); - this.body.SetAngularVelocity(update.av); - }; return GameObject; diff --git a/app/Game/Core/GameObjects/Item.js b/app/Game/Core/GameObjects/Item.js index 4e25fb0..dea0e5f 100644 --- a/app/Game/Core/GameObjects/Item.js +++ b/app/Game/Core/GameObjects/Item.js @@ -1,16 +1,13 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/GameObject", "Lib/Vendor/Box2D", - "Lib/Utilities/OptionsHelper", + "Lib/Utilities/Options", "Game/Config/Settings", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { - - "use strict"; +function (Parent, Box2D, Options, Settings, Exception, Nc) { function Item(physicsEngine, uid, options) { @@ -26,28 +23,25 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { y: parseFloat(options.y) }; - this.options = optionsHelper.merge(floatOptions, options); + this.options = Options.merge(floatOptions, options); if(!this.options.category) { // FIXME add more validation - //console.warn('item category empty (' + this.options.name + ')' ); + console.warn('item category empty (' + this.options.name + ')' ); } Parent.call(this, physicsEngine, uid); this.createFixture(); this.body.ResetMassData(); this.flipDirection = 1; - if (this.body.GetMass() < 1) { - this.body.SetBullet(true); - } - nc.trigger(nc.ns.core.game.worldUpdateObjects.add, this); + Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this); } Item.prototype = Object.create(Parent.prototype); Item.prototype.getBodyDef = function() { - Assert.number(this.options.x, this.options.y); + var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = this.options.x / Settings.RATIO; @@ -55,18 +49,14 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { bodyDef.angle = 0; return bodyDef; - }; + } Item.prototype.getFixtureDef = function() { - Assert.number(this.options.width, this.options.height); - Assert.number(this.options.weight); - Assert.number(this.options.bounce); - var itemShape; var w = this.options.width / Settings.RATIO; var h = this.options.height / Settings.RATIO; - if(this.options.type == "circle") { + if(this.options.type == 'circle'){ var r = (w + h) / 4 ; itemShape = new Box2D.Collision.Shapes.b2CircleShape(); itemShape.SetRadius(r); @@ -76,19 +66,25 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { itemShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(h/2))); } + var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); fixtureDef.shape = itemShape; - fixtureDef.density = this.options.weight; + var offset = 4, + factor = 80; + var density = ((this.options.weight + offset) / this.options.width / this.options.height) * factor; + fixtureDef.density = density; fixtureDef.friction = Settings.ITEM_FRICTION; - fixtureDef.restitution = this.options.bounce ? this.options.bounce / 10 : Settings.ITEM_RESTITUTION; + fixtureDef.restitution = this.options.bounce + ? this.options.bounce / 10 + : Settings.ITEM_RESTITUTION; fixtureDef.isSensor = false; fixtureDef.userData = { onCollisionChange: this.onCollisionChange.bind(this) - }; + } return fixtureDef; }; @@ -96,7 +92,7 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { Item.prototype.createFixture = function () { var fixtureDef = this.getFixtureDef(); this.body.CreateFixture(fixtureDef); - }; + } Item.prototype.flip = function(direction) { this.flipDirection = direction; @@ -104,61 +100,48 @@ function (Parent, Box2D, optionsHelper, Settings, Exception, nc, Assert) { // FIXME: implement body flip if necessary }; - Item.prototype.beingGrabbed = function(player) { // jshint unused:false + Item.prototype.beingGrabbed = function(player) { // overwrite if necessary }; - Item.prototype.beingReleased = function(player) { // jshint unused:false + Item.prototype.beingReleased = function(player) { // overwrite if necessary }; - Item.prototype.onCollisionChange = function(isColliding, fixture, info) { // jshint unused:false + Item.prototype.onCollisionChange = function(isColliding, fixture, info) { // overwrite if necessary }; Item.prototype.reposition = function(handPosition, direction) { - Assert.number(handPosition.x, handPosition.y); - Assert.number(direction); - Assert.number(this.options.width); - Assert.number(this.options.grabAngle); - this.body.SetAwake(true); var position = new Box2D.Common.Math.b2Vec2( handPosition.x + ((this.options.width / Settings.RATIO / 2) * direction), handPosition.y - ); + ) this.body.SetPosition(position); - this.body.SetAngle((this.options.grabAngle || 0.0) * direction); this.flip(direction); + this.body.SetAngle((this.options.grabAngle || 0) * direction); }; Item.prototype.getGrabPoint = function() { return this.body.GetWorldCenter(); }; - Item.prototype.throw = function(options, carrierVelocity) { - this.accelerateBody(this.body, options, carrierVelocity); - }; - - Item.prototype.accelerateBody = function(body, options, carrierVelocity) { - Assert.number(this.options.weight); - Assert.number(carrierVelocity.x, carrierVelocity.y); - Assert.number(options.x, options.y); - Assert.number(options.av); - + Item.prototype.throw = function(x, y) { + var body = this.body; body.SetAwake(true); - var x = options.x * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.x; - var y = -options.y * Settings.MAX_THROW_FORCE / this.options.weight + carrierVelocity.y; - var vector = new Box2D.Common.Math.b2Vec2(x, y); - body.SetLinearVelocity(vector); + var vector = new Box2D.Common.Math.b2Vec2( + x * Settings.MAX_THROW_FORCE / this.options.weight, + -y * Settings.MAX_THROW_FORCE / this.options.weight + ); + this.body.SetLinearVelocity(vector); - var av = -options.av * Settings.MAX_THROW_ANGULAR_VELOCITY; - body.SetAngularVelocity(av); + body.SetAngularVelocity(Settings.MAX_THROW_ANGULAR_VELOCITY * x); }; Item.prototype.destroy = function() { - nc.trigger(nc.ns.core.game.worldUpdateObjects.remove, this); + Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this); Parent.prototype.destroy.call(this); }; diff --git a/app/Game/Core/GameObjects/Items/RagDoll.js b/app/Game/Core/GameObjects/Items/RagDoll.js index 48faba6..ea7ca36 100644 --- a/app/Game/Core/GameObjects/Items/RagDoll.js +++ b/app/Game/Core/GameObjects/Items/RagDoll.js @@ -2,15 +2,10 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Item", "Lib/Vendor/Box2D", "Game/Config/Settings", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert", - "Lib/Utilities/OptionsHelper", - "Game/Config/ItemSettings", + "Lib/Utilities/NotificationCenter" ], -function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { - - "use strict"; +function (Parent, Box2D, Settings, Nc) { function RagDoll(physicsEngine, uid, options) { @@ -95,15 +90,16 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { - // FIXME - var ragdollOptions = optionsHelper.merge(ItemSettings.RagDoll, ItemSettings.Default); - options = optionsHelper.merge(options, ragdollOptions); + + + + Parent.call(this, physicsEngine, uid, options); //this.createSensor(); this.limbs = {}; - this.addHead(); + this.addHead(); this.addLimb( @@ -137,6 +133,7 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { + this.addLimb( "upperLeftArm", this.body, @@ -164,7 +161,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { 0, options.limbs.upperRightArm.height / 2 ); - } RagDoll.prototype = Object.create(Parent.prototype); @@ -185,14 +181,10 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { var bodyDef = Parent.prototype.getBodyDef.call(this); bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING; bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; - bodyDef.position.y -= this.options.height / 2 / Settings.RATIO; // position it on top of ground - return bodyDef; }; RagDoll.prototype.getFixtureDef = function() { - Assert.number(this.options.limbs.chest.width, this.options.limbs.chest.height); - var fixtureDef = Parent.prototype.getFixtureDef.call(this); fixtureDef.density = Settings.PLAYER_DENSITY; fixtureDef.friction = Settings.PLAYER_FRICTION; @@ -212,8 +204,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { }; RagDoll.prototype.createSensor = function() { - Assert.number(this.options.width, this.options.height); - var w = this.options.width / Settings.RATIO; var h = this.options.height / Settings.RATIO; @@ -226,18 +216,14 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { fixtureDef.userData = { onCollisionChange: this.onCollisionChange.bind(this) - }; + } this.body.CreateFixture(fixtureDef); }; RagDoll.prototype.addHead = function() { - Assert.number(this.options.x, this.options.y); - Assert.number(this.options.limbs.head.x, this.options.limbs.head.y); - Assert.number(this.options.limbs.head.width); - var x = this.options.x + this.options.limbs.head.x, - y = this.options.y + this.options.limbs.head.y - this.options.height / 2; // position it on top of ground; + y = this.options.y + this.options.limbs.head.y; var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; @@ -282,13 +268,8 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { }; RagDoll.prototype.addLimb = function(name, connectTo, xOffset, yOffset) { - Assert.number(xOffset, yOffset); - Assert.number(this.options.x, this.options.y); - Assert.number(this.options.limbs[name].x, this.options.limbs[name].y); - Assert.number(this.options.limbs[name].width, this.options.limbs[name].height); - var x = this.options.x + this.options.limbs[name].x, - y = this.options.y + this.options.limbs[name].y - this.options.height / 2; // position it on top of ground;; + y = this.options.y + this.options.limbs[name].y; var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.linearDamping = Settings.PLAYER_LINEAR_DAMPING; @@ -339,10 +320,6 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { }; RagDoll.prototype.reposition = function(handPosition, direction) { - Assert.number(this.options.limbs.head.x, this.options.limbs.head.y); - Assert.number(this.options.grabAngle); - Assert.number(direction); - Parent.prototype.reposition.call(this, handPosition, direction); var chestPosition = this.body.GetPosition(); @@ -350,25 +327,30 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { var position = new Box2D.Common.Math.b2Vec2( chestPosition.x + this.options.limbs.head.x / Settings.RATIO, chestPosition.y + this.options.limbs.head.y / Settings.RATIO - ); + ) this.limbs.head.SetPosition(position); - this.limbs.head.SetAngle((this.options.grabAngle || 0.0) * direction); + this.limbs.head.SetAngle((this.options.grabAngle || 0) * direction); }; - RagDoll.prototype.throw = function(options, carrierVelocity) { - Parent.prototype.throw.call(this, options, carrierVelocity); + RagDoll.prototype.throw = function(x, y) { + Parent.prototype.throw.call(this, x, y); + + var limbDampingFactor = 1; for(var name in this.limbs) { var body = this.limbs[name]; + body.SetAwake(true); - this.accelerateBody(body, options, carrierVelocity); + var vector = new Box2D.Common.Math.b2Vec2( + x * Settings.MAX_THROW_FORCE * limbDampingFactor / this.options.weight, + -y * Settings.MAX_THROW_FORCE * limbDampingFactor / this.options.weight + ); + body.SetLinearVelocity(vector); + // body.SetAngularVelocity(Settings.MAX_THROW_ANGULAR_VELOCITY * x); } }; RagDoll.prototype.setVelocities = function(options) { - Assert.number(options.linearVelocity.x, options.linearVelocity.y); - Assert.number(options.angularVelocity); - this.body.SetLinearVelocity(options.linearVelocity); this.body.SetAngularVelocity(options.angularVelocity); for(var name in this.limbs) { @@ -378,6 +360,7 @@ function (Parent, Box2D, Settings, nc, Assert, optionsHelper, ItemSettings) { RagDoll.prototype.destroy = function() { + Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this); var world = this.body.GetWorld(); for (var name in this.limbs) { diff --git a/app/Game/Core/GameObjects/Items/RagDoll2.js b/app/Game/Core/GameObjects/Items/RagDoll2.js index 75fd89e..8ebedff 100644 --- a/app/Game/Core/GameObjects/Items/RagDoll2.js +++ b/app/Game/Core/GameObjects/Items/RagDoll2.js @@ -5,8 +5,6 @@ define([ ], function (Parent, Box2D, Settings) { - - "use strict"; function RagDoll(physicsEngine, uid, options) { Parent.call(this, physicsEngine, uid, options); diff --git a/app/Game/Core/GameObjects/Items/Rube.js b/app/Game/Core/GameObjects/Items/Rube.js new file mode 100644 index 0000000..c5c66c5 --- /dev/null +++ b/app/Game/Core/GameObjects/Items/Rube.js @@ -0,0 +1,1408 @@ +define([ + "Game/" + GLOBALS.context + "/GameObjects/Item", + "Lib/Vendor/RubeLoader", + "Lib/Vendor/Box2D", + "Game/Config/Settings" +], + +function (Parent, RubeLoader, Box2D, Settings ) { + + // Fixme - make this loadable + var __ragdollJson; + + function Rube(physicsEngine, uid, options) { + + this.rubeLoader = null; + this.body = null; + + Parent.call(this, physicsEngine, uid, options); + var world = physicsEngine.getWorld(); + world.DestroyBody(this.body); + + var json = __ragdollJson; + + this.rubeLoader = new RubeLoader(json, world); + var scene = this.rubeLoader.getScene(); + + for (var i in scene.bodies) { + var body = scene.bodies[i]; + var position = body.GetPosition().Copy(); + position.Add(new Box2D.Common.Math.b2Vec2( + options.x / Settings.RATIO, + options.y / Settings.RATIO + )); + body.SetPosition(position); + + if(body.name == "chest"){ + this.body = body; + } + } + + var def = this.body.GetDefinition(); + def.userData = this; + this.body.SetUserData(this); + } + + Rube.prototype = Object.create(Parent.prototype); + + Rube.prototype.flip = function(direction) { + Parent.prototype.flip.call(this, direction); + // Extend + }; + + __ragdollJson = + +{ + "allowSleep" : true, + "autoClearForces" : true, + "body" : + [ + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.05748672783374786, + 0.05748672783374786, + -0.05748683214187622, + -0.05748683214187622 + ], + "y" : + [ + -0.2322469353675842, + 0.2322462797164917, + 0.2322462797164917, + -0.2322469353675842 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.001019014045596123, + "massData-center" : + { + "x" : -5.215406062575312e-08, + "y" : -3.278255462646484e-07 + }, + "massData-mass" : 0.05340443924069405, + "name" : "upperArmLeft", + "position" : + { + "x" : -0.1699507087469101, + "y" : 1.113796472549438 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture0", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.1718577891588211, + 0.1684816330671310, + 0.001688212156295776, + -0.1718577295541763, + -0.1718577295541763, + 0.001460619270801544 + ], + "y" : + [ + -0.3928470611572266, + 0.4921868443489075, + 0.4921868443489075, + 0.3841522336006165, + -0.4204435348510742, + -0.4519201517105103 + ] + } + } + }, + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture2", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.1679489463567734, + 0.1679489463567734, + -0.004204027354717255, + -0.004204027354717255 + ], + "y" : + [ + 0.4449140429496765, + 0.6170670390129089, + 0.6170670390129089, + 0.4449140429496765 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.03228222951292992, + "massData-center" : + { + "x" : 0.008858840912580490, + "y" : 0.06282533705234528 + }, + "massData-mass" : 0.3355117142200470, + "name" : "chest", + "position" : + { + "x" : -0.05338868126273155, + "y" : 0.9620395302772522 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "circle" : + { + "center" : + { + "x" : -0.007499951869249344, + "y" : 0.003749847412109375 + }, + "radius" : 0.2746430933475494 + }, + "density" : 0.2204959988594055, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture1" + }, + + { + "circle" : + { + "center" : + { + "x" : -0.03327952325344086, + "y" : -0.1384725570678711 + }, + "radius" : 0.2485582530498505 + }, + "density" : 0.2204959988594055, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture1" + } + ], + "linearVelocity" : 0, + "massData-I" : 0.004164268728345633, + "massData-center" : + { + "x" : -0.01910765282809734, + "y" : -0.06028826907277107 + }, + "massData-mass" : 0.09504657238721848, + "name" : "head", + "position" : + { + "x" : 0.04257059469819069, + "y" : 1.812389135360718 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.05748683214187622, + 0.05748683214187622, + -0.05748690664768219, + -0.05748690664768219 + ], + "y" : + [ + -0.1419981122016907, + 0.1419981718063354, + 0.1419981718063354, + -0.1419981122016907 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.0002554289239924401, + "massData-center" : + { + "x" : -3.725290298461914e-08, + "y" : 2.980232238769531e-08 + }, + "massData-mass" : 0.03265211358666420, + "name" : "lowerArmRight", + "position" : + { + "x" : 0.1177217364311218, + "y" : 0.8479318022727966 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.1415265351533890, + 0.1415265351533890, + -0.08457186818122864, + -0.08457186818122864 + ], + "y" : + [ + -0.1143886670470238, + -0.05680520832538605, + -0.05680520832538605, + -0.1143886670470238 + ] + } + } + }, + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.08623030036687851, + 0.08623030036687851, + -0.08623020350933075, + -0.08623020350933075 + ], + "y" : + [ + -0.1138511821627617, + 0.1565139442682266, + 0.1565139442682266, + -0.1138511821627617 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.0005858240183442831, + "massData-center" : + { + "x" : 0.006215983536094427, + "y" : -0.002008607611060143 + }, + "massData-mass" : 0.05964682996273041, + "name" : "lowerLegLeft", + "position" : + { + "x" : -0.08319067955017090, + "y" : 0.1298431605100632 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.05748684704303741, + 0.05748684704303741, + -0.05748672783374786, + -0.05748672783374786 + ], + "y" : + [ + -0.1419981122016907, + 0.1419981718063354, + 0.1419981718063354, + -0.1419981122016907 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.0002554284874349833, + "massData-center" : + { + "x" : 5.960464477539062e-08, + "y" : 2.980232238769531e-08 + }, + "massData-mass" : 0.03265206888318062, + "name" : "lowerArmLeft", + "position" : + { + "x" : -0.1699528992176056, + "y" : 0.8479318022727966 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.05748683214187622, + 0.05748683214187622, + -0.05748690664768219, + -0.05748690664768219 + ], + "y" : + [ + -0.2322469353675842, + 0.2322462797164917, + 0.2322462797164917, + -0.2322469353675842 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.001019015791825950, + "massData-center" : + { + "x" : -3.725290298461914e-08, + "y" : -3.278255462646484e-07 + }, + "massData-mass" : 0.05340452119708061, + "name" : "upperArmRight", + "position" : + { + "x" : 0.1177217364311218, + "y" : 1.113796472549438 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.08623021841049194, + 0.08623021841049194, + -0.08623008430004120, + -0.08623008430004120 + ], + "y" : + [ + -0.2315792292356491, + 0.2315795421600342, + 0.2315795421600342, + -0.2315792292356491 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.001625877106562257, + "massData-center" : + { + "x" : 6.705522537231445e-08, + "y" : 1.564621925354004e-07 + }, + "massData-mass" : 0.07987650483846664, + "name" : "upperLegRight", + "position" : + { + "x" : 0.03142313286662102, + "y" : 0.4171121716499329 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.08623032271862030, + 0.08623032271862030, + -0.08623017370700836, + -0.08623017370700836 + ], + "y" : + [ + -0.2315792292356491, + 0.2315795421600342, + 0.2315795421600342, + -0.2315792292356491 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.001625879434868693, + "massData-center" : + { + "x" : 7.450580596923828e-08, + "y" : 1.564621925354004e-07 + }, + "massData-mass" : 0.07987659424543381, + "name" : "upperLegLeft", + "position" : + { + "x" : -0.08319067955017090, + "y" : 0.4171121716499329 + }, + "type" : 2 + }, + + { + "angle" : 0, + "angularVelocity" : 0, + "awake" : true, + "fixture" : + [ + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.08623021841049194, + 0.08623021841049194, + -0.08623008430004120, + -0.08623008430004120 + ], + "y" : + [ + -0.1138515025377274, + 0.1563164740800858, + 0.1563164740800858, + -0.1138515025377274 + ] + } + } + }, + + { + "density" : 1, + "filter-groupIndex" : -55, + "friction" : 0.2, + "name" : "fixture3", + "polygon" : + { + "vertices" : + { + "x" : + [ + 0.1415264606475830, + 0.1415264606475830, + -0.08457189798355103, + -0.08457189798355103 + ], + "y" : + [ + -0.1143886670470238, + -0.05680520832538605, + -0.05680520832538605, + -0.1143886670470238 + ] + } + } + } + ], + "linearVelocity" : 0, + "massData-I" : 0.0005849063745699823, + "massData-center" : + { + "x" : 0.006219535600394011, + "y" : -0.002099231118336320 + }, + "massData-mass" : 0.05961277708411217, + "name" : "lowerLegRight", + "position" : + { + "x" : 0.03142313286662102, + "y" : 0.1298431605100632 + }, + "type" : 2 + } + ], + "collisionbitplanes" : + { + "names" : + [ + "bitplane1", + "bitplane2", + "bitplane3", + "bitplane4", + "bitplane5", + "bitplane6", + "bitplane7", + "bitplane8", + "bitplane9", + "bitplane10", + "bitplane11", + "bitplane12", + "bitplane13", + "bitplane14", + "bitplane15", + "bitplane16", + "bitplane17", + "bitplane18", + "bitplane19", + "bitplane20", + "bitplane21", + "bitplane22", + "bitplane23", + "bitplane24", + "bitplane25", + "bitplane26", + "bitplane27", + "bitplane28", + "bitplane29", + "bitplane30", + "bitplane31", + "bitplane32" + ] + }, + "continuousPhysics" : true, + "gravity" : + { + "x" : 0, + "y" : -10 + }, + "image" : + [ + + { + "aspectScale" : 1, + "body" : 9, + "center" : + { + "x" : 0.02911517955362797, + "y" : -0.0009155124425888062 + }, + "corners" : + { + "x" : + [ + -0.08536797016859055, + 0.1435983330011368, + 0.1435983330011368, + -0.08536797016859055 + ], + "y" : + [ + -0.1153986603021622, + -0.1153986603021622, + 0.1135676354169846, + 0.1135676354169846 + ] + }, + "file" : "../../img/Characters/Chuck/lowerLeftLeg.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.08536797016859055, + -0.1153986603021622, + 0.1435983330011368, + -0.1153986603021622, + 0.1435983330011368, + 0.1135676354169846, + -0.08536797016859055, + 0.1135676354169846 + ], + "name" : "image5", + "opacity" : 1, + "scale" : 0.2289662957191467 + }, + + { + "aspectScale" : 1, + "body" : 7, + "center" : + { + "x" : -0.02732392773032188, + "y" : 0.02671334147453308 + }, + "corners" : + { + "x" : + [ + -0.1425068378448486, + 0.08785898983478546, + 0.08785898983478546, + -0.1425068378448486 + ], + "y" : + [ + -0.2324482202529907, + -0.2324482202529907, + 0.2858749032020569, + 0.2858749032020569 + ] + }, + "file" : "../../img/Characters/Chuck/upperRightLeg.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.1425068378448486, + -0.2324482202529907, + 0.08785898983478546, + -0.2324482202529907, + 0.08785898983478546, + 0.2858749032020569, + -0.1425068378448486, + 0.2858749032020569 + ], + "name" : "image6", + "opacity" : 1, + "scale" : 0.5183231234550476 + }, + + { + "aspectScale" : 1, + "body" : 6, + "center" : + { + "x" : 0.0003027096390724182, + "y" : 0.0006600618362426758 + }, + "corners" : + { + "x" : + [ + -0.05836960300803185, + 0.05897502228617668, + 0.05897502228617668, + -0.05836960300803185 + ], + "y" : + [ + -0.2340291887521744, + -0.2340291887521744, + 0.2353493124246597, + 0.2353493124246597 + ] + }, + "file" : "../../img/Characters/Chuck/upperLeftArm.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.05836960300803185, + -0.2340291887521744, + 0.05897502228617668, + -0.2340291887521744, + 0.05897502228617668, + 0.2353493124246597, + -0.05836960300803185, + 0.2353493124246597 + ], + "name" : "image4", + "opacity" : 1, + "renderOrder" : 1, + "scale" : 0.4693785011768341 + }, + + { + "aspectScale" : 1, + "body" : 3, + "center" : + { + "x" : 0.0007003694772720337, + "y" : 0.001779437065124512 + }, + "corners" : + { + "x" : + [ + -0.05596264451742172, + 0.05736338347196579, + 0.05736338347196579, + -0.05596264451742172 + ], + "y" : + [ + -0.1398780941963196, + -0.1398780941963196, + 0.1434369683265686, + 0.1434369683265686 + ] + }, + "file" : "../../img/Characters/Chuck/lowerLeftArm.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.05596264451742172, + -0.1398780941963196, + 0.05736338347196579, + -0.1398780941963196, + 0.05736338347196579, + 0.1434369683265686, + -0.05596264451742172, + 0.1434369683265686 + ], + "name" : "image3", + "opacity" : 1, + "renderOrder" : 1, + "scale" : 0.2833150625228882 + }, + + { + "aspectScale" : 1, + "body" : 1, + "center" : + { + "x" : -0.0008481591939926147, + "y" : -0.001265347003936768 + }, + "corners" : + { + "x" : + [ + -0.1698881536722183, + 0.1681918352842331, + 0.1681918352842331, + -0.1698881536722183 + ], + "y" : + [ + -0.480212002992630, + -0.480212002992630, + 0.4776813089847565, + 0.4776813089847565 + ] + }, + "file" : "../../img/Characters/Chuck/chest.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.1698881536722183, + -0.480212002992630, + 0.1681918352842331, + -0.480212002992630, + 0.1681918352842331, + 0.4776813089847565, + -0.1698881536722183, + 0.4776813089847565 + ], + "name" : "image2", + "opacity" : 1, + "renderOrder" : 5, + "scale" : 0.9578933119773865 + }, + + { + "aspectScale" : 1, + "body" : 8, + "center" : + { + "x" : 0.003173574805259705, + "y" : -0.001172244548797607 + }, + "corners" : + { + "x" : + [ + -0.1414211541414261, + 0.1477683037519455, + 0.1477683037519455, + -0.1414211541414261 + ], + "y" : + [ + -0.2325238138437271, + -0.2325238138437271, + 0.2301793247461319, + 0.2301793247461319 + ] + }, + "file" : "../../img/Characters/Chuck/upperLeftLeg.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.1414211541414261, + -0.2325238138437271, + 0.1477683037519455, + -0.2325238138437271, + 0.1477683037519455, + 0.2301793247461319, + -0.1414211541414261, + 0.2301793247461319 + ], + "name" : "image6", + "opacity" : 1, + "renderOrder" : 6, + "scale" : 0.4627031385898590 + }, + + { + "aspectScale" : 1, + "body" : 4, + "center" : + { + "x" : 0.02851789817214012, + "y" : -0.0009155124425888062 + }, + "corners" : + { + "x" : + [ + -0.08596524596214294, + 0.1430010497570038, + 0.1430010497570038, + -0.08596524596214294 + ], + "y" : + [ + -0.1153986603021622, + -0.1153986603021622, + 0.1135676354169846, + 0.1135676354169846 + ] + }, + "file" : "../../img/Characters/Chuck/lowerLeftLeg.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.08596524596214294, + -0.1153986603021622, + 0.1430010497570038, + -0.1153986603021622, + 0.1430010497570038, + 0.1135676354169846, + -0.08596524596214294, + 0.1135676354169846 + ], + "name" : "image5", + "opacity" : 1, + "renderOrder" : 6, + "scale" : 0.2289662957191467 + }, + + { + "aspectScale" : 1, + "body" : 2, + "center" : + { + "x" : 0.01975236460566521, + "y" : -0.07194232940673828 + }, + "corners" : + { + "x" : + [ + -0.2679373621940613, + 0.3074420690536499, + 0.3074420690536499, + -0.2679373621940613 + ], + "y" : + [ + -0.4171699881553650, + -0.4171699881553650, + 0.2732853293418884, + 0.2732853293418884 + ] + }, + "file" : "../../img/Characters/Chuck/head.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.2679373621940613, + -0.4171699881553650, + 0.3074420690536499, + -0.4171699881553650, + 0.3074420690536499, + 0.2732853293418884, + -0.2679373621940613, + 0.2732853293418884 + ], + "name" : "image1", + "opacity" : 1, + "renderOrder" : 6, + "scale" : 0.6904553174972534 + }, + + { + "aspectScale" : 1, + "body" : 0, + "center" : + { + "x" : 0.002138927578926086, + "y" : 0.0006600618362426758 + }, + "corners" : + { + "x" : + [ + -0.05653338506817818, + 0.06081124022603035, + 0.06081124022603035, + -0.05653338506817818 + ], + "y" : + [ + -0.2340291887521744, + -0.2340291887521744, + 0.2353493124246597, + 0.2353493124246597 + ] + }, + "file" : "../../img/Characters/Chuck/upperLeftArm.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.05653338506817818, + -0.2340291887521744, + 0.06081124022603035, + -0.2340291887521744, + 0.06081124022603035, + 0.2353493124246597, + -0.05653338506817818, + 0.2353493124246597 + ], + "name" : "image4", + "opacity" : 1, + "renderOrder" : 8, + "scale" : 0.4693785011768341 + }, + + { + "aspectScale" : 1, + "body" : 5, + "center" : + { + "x" : 0.002538725733757019, + "y" : 0.001779437065124512 + }, + "corners" : + { + "x" : + [ + -0.05412428826093674, + 0.05920173972845078, + 0.05920173972845078, + -0.05412428826093674 + ], + "y" : + [ + -0.1398780941963196, + -0.1398780941963196, + 0.1434369683265686, + 0.1434369683265686 + ] + }, + "file" : "../../img/Characters/Chuck/lowerLeftArm.png", + "filter" : 0, + "glDrawElements" : [ 0, 1, 2, 2, 3, 0 ], + "glTexCoordPointer" : [ 0.0, 0.0, 1, 0.0, 1, 1, 0.0, 1 ], + "glVertexPointer" : + [ + -0.05412428826093674, + -0.1398780941963196, + 0.05920173972845078, + -0.1398780941963196, + 0.05920173972845078, + 0.1434369683265686, + -0.05412428826093674, + 0.1434369683265686 + ], + "name" : "image3", + "opacity" : 1, + "renderOrder" : 8, + "scale" : 0.2833150625228882 + } + ], + "joint" : + [ + + { + "anchorA" : + { + "x" : 0.001047849655151367, + "y" : -0.1790249347686768 + }, + "anchorB" : + { + "x" : 0.001048207283020020, + "y" : 0.08683943748474121 + }, + "bodyA" : 0, + "bodyB" : 5, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : 0, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint4", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 1.919862151145935 + }, + + { + "anchorA" : + { + "x" : -0.1165831685066223, + "y" : 0.3330366015434265 + }, + "anchorB" : + { + "x" : -2.135336399078369e-05, + "y" : 0.1812803745269775 + }, + "bodyA" : 1, + "bodyB" : 0, + "enableLimit" : false, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -2.268928050994873, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint3", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 3.141592741012573 + }, + + { + "anchorA" : + { + "x" : 0.07454992830753326, + "y" : 0.5068108439445496 + }, + "anchorB" : + { + "x" : -0.02141102217137814, + "y" : -0.3435407876968384 + }, + "bodyA" : 1, + "bodyB" : 2, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -1.221730470657349, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint0", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 0.6981316804885864 + }, + + { + "anchorA" : + { + "x" : 0.1367489844560623, + "y" : -0.3606387376785278 + }, + "anchorB" : + { + "x" : 0.05056380107998848, + "y" : 0.1842886805534363 + }, + "bodyA" : 1, + "bodyB" : 7, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -0.6981316804885864, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint5", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 1.919862151145935 + }, + + { + "anchorA" : + { + "x" : -0.08329562842845917, + "y" : -0.3541148304939270 + }, + "anchorB" : + { + "x" : -0.05503869056701660, + "y" : 0.1909851431846619 + }, + "bodyA" : 1, + "bodyB" : 8, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -0.6981316804885864, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint6", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 1.919862151145935 + }, + + { + "anchorA" : + { + "x" : 0.1710196435451508, + "y" : 0.3308989405632019 + }, + "anchorB" : + { + "x" : -9.131431579589844e-05, + "y" : 0.1791421175003052 + }, + "bodyA" : 1, + "bodyB" : 6, + "enableLimit" : false, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -2.268928050994873, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint2", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 3.141592741012573 + }, + + { + "anchorA" : + { + "x" : 0.0004334598779678345, + "y" : 0.08706557750701904 + }, + "anchorB" : + { + "x" : 0.0004332214593887329, + "y" : -0.1787990331649780 + }, + "bodyA" : 3, + "bodyB" : 6, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : 0, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint1", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 1.919862151145935 + }, + + { + "anchorA" : + { + "x" : 0.002425249665975571, + "y" : -0.1845821887254715 + }, + "anchorB" : + { + "x" : 0.002425376325845718, + "y" : 0.1026860624551773 + }, + "bodyA" : 7, + "bodyB" : 9, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -2.268928050994873, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint8", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 0 + }, + + { + "anchorA" : + { + "x" : -0.0009558200836181641, + "y" : -0.1818936169147491 + }, + "anchorB" : + { + "x" : -0.0009555891156196594, + "y" : 0.1055182516574860 + }, + "bodyA" : 8, + "bodyB" : 4, + "enableLimit" : true, + "enableMotor" : false, + "jointSpeed" : 0, + "lowerLimit" : -2.268928050994873, + "maxMotorTorque" : 1, + "motorSpeed" : 0, + "name" : "joint7", + "refAngle" : 0, + "type" : "revolute", + "upperLimit" : 0 + } + ], + "positionIterations" : 3, + "stepsPerSecond" : 60.0, + "subStepping" : false, + "velocityIterations" : 8, + "warmStarting" : true +} + + + + + + + return Rube; + +}); \ No newline at end of file diff --git a/app/Game/Core/GameObjects/Items/RubeDoll.js b/app/Game/Core/GameObjects/Items/RubeDoll.js deleted file mode 100644 index 77b511d..0000000 --- a/app/Game/Core/GameObjects/Items/RubeDoll.js +++ /dev/null @@ -1,223 +0,0 @@ -define([ - "Game/" + GLOBALS.context + "/GameObjects/Item", - "Lib/Vendor/RubeLoader", - "Lib/Vendor/Box2D", - "Game/Config/Settings", - "Lib/Utilities/Assert", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Matrix", - "json!Game/Asset/RubeDoll.json" // using requirejs json loader plugin -], - -function (Parent, RubeLoader, Box2D, Settings, Assert, nc, Matrix, RubeDollJson) { - - "use strict"; - - function RubeDoll(physicsEngine, uid, options) { - Assert.number(options.x, options.y); - - this.rubeLoader = null; - this.body = null; - this.limbs = {}; - this.joints = null; - this.limits = []; - - var chest = null; - this.rubeLoader = new RubeLoader(RubeDollJson, physicsEngine.getWorldForRubeLoader()); - - this.loadRubeDollFromScene(options); - - Parent.call(this, physicsEngine, uid, options); - physicsEngine.destroyBody(this.body); - this.body = this.limbs.chest; - delete this.limbs.chest; - - this.body.SetUserData(this); - - this.flip(options.direction || 1); - } - - RubeDoll.prototype = Object.create(Parent.prototype); - - RubeDoll.prototype.loadRubeDollFromScene = function(options) { - var scene = this.rubeLoader.getScene(); - - - - for (var i in scene.bodies) { - var body = scene.bodies[i]; - var position = body.GetPosition().Copy(); - position.Add(new Box2D.Common.Math.b2Vec2( - options.x / Settings.RATIO, - options.y / Settings.RATIO - )); - body.SetPosition(position); - this.limbs[body.name] = body; - - // code snipped possibly needed for filtering between doll and rubedoll while holding - //var filterData = new Box2D.Dynamics.b2FilterData(); - //filterData.groupIndex = -66; - //if(body.name != "head" && body.name != "chest") { - // for (var fixture = body.GetFixtureList(); fixture; fixture = fixture.GetNext()) { - // fixture.SetFilterData(filterData); - // } - //} - } - - this.joints = scene.joints; - - var count = 0; - for (var i in this.joints) { - this.limits[i] = { - lower: this.joints[i].GetLowerLimit(), - upper: this.joints[i].GetUpperLimit(), - }; -/* - this.joints[i].EnableLimit(false); - - if(count < 4 && this.joints[i] instanceof Box2D.Dynamics.Joints.b2RevoluteJoint) { - console.log(i); - } else { - body.GetWorld().DestroyJoint(this.joints[i]); - } - count++; - */ - } - }; - - RubeDoll.prototype.getFixtureDef = function() { - var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); - fixtureDef.shape = new Box2D.Collision.Shapes.b2CircleShape(); - return fixtureDef; - }; - - RubeDoll.prototype.flip = function(direction) { - var oldFlipDirection = this.flipDirection; - - Parent.prototype.flip.call(this, direction); - - if(oldFlipDirection != direction) { - - for (var i in this.joints) { - var joint = this.joints[i]; - var limits = this.limits[i]; - - if (joint instanceof Box2D.Dynamics.Joints.b2RevoluteJoint) { - - if (direction > 0) { - joint.SetLimits(limits.lower, limits.upper); - continue; - } - - var a1 = limits.lower * -1; - var a2 = limits.upper * -1; - - if (a2 > a1) { - joint.SetLimits(a1, a2); - } else { - joint.SetLimits(a2, a1); - } - - // joint.SetAngle(joint.GetAngle() * -1); - } - } - } - }; - - RubeDoll.prototype.reposition = function(handPosition, direction) { - var oldPosition = this.getPosition(); - var oldAngle = this.body.GetAngle(); - var oldDirection = this.flipDirection; - - // calls flip() at the end of Parent reposition() - Parent.prototype.reposition.call(this, handPosition, direction); - - var differenceAngle = oldAngle - this.body.GetAngle(); - - //this.body.SetLinearVelocity(new Box2D.Common.Math.b2Vec2(0, 0)); - - var offset = Box2D.Common.Math.b2Math.SubtractVV(this.getPosition(), oldPosition); - var grabAngle = (this.options.grabAngle || 0.001); - - for(var key in this.limbs) { - var limb = this.limbs[key]; - - // Setting position offset first (floor to hand) - var position = limb.GetPosition().Copy(); - position.Add(offset); - limb.SetPosition(position); - - // grabing local point to "rotate" around (x, y position transform only) - var localPoint = this.body.GetLocalPoint(limb.GetPosition().Copy()); - - // create rotation matrix from chest rotation difference - var mat = Box2D.Common.Math.b2Mat22.FromAngle(differenceAngle); - - // matrix multiplication with local limb position - position = Box2D.Common.Math.b2Math.MulTMV(mat, localPoint); - - // translating back to global position - var globalPoint = this.body.GetWorldPoint(position); - limb.SetPosition(globalPoint); - - // relative limb rotating by chest rotation difference - var d = (oldDirection == direction) ? -1 : 1; - limb.SetAngle((limb.GetAngle() - differenceAngle) * d); - - //limb.SetType(Box2D.Dynamics.b2Body.b2_staticBody); - //limb.SetLinearVelocity(new Box2D.Common.Math.b2Vec2(0, 0)); - } - }; - - RubeDoll.prototype.setVelocities = function(options) { - Assert.number(options.linearVelocity.x, options.linearVelocity.y); - Assert.number(options.angularVelocity); - - this.body.SetLinearVelocity(options.linearVelocity); - this.body.SetAngularVelocity(options.angularVelocity); - for(var name in this.limbs) { - this.limbs[name].SetLinearVelocity(options.linearVelocity); - } - }; - - RubeDoll.prototype.getPosition = function() { - return this.body.GetPosition().Copy(); - }; - - RubeDoll.prototype.getHeadPosition = function() { - return this.limbs.head.GetPosition().Copy(); - }; - - RubeDoll.prototype.setUpdateData = function(update) { - - Parent.prototype.setUpdateData.call(this, update); - -/* - for(var name in update.limbs) { - Assert.number(update.limbs[name].p.x, update.limbs[name].p.y); - Assert.number(update.limbs[name].a); - Assert.number(update.limbs[name].lv.x, update.limbs[name].lv.y); - Assert.number(update.limbs[name].av); - - this.limbs[name].SetAwake(true); - this.limbs[name].SetPosition(update.limbs[name].p); - this.limbs[name].SetAngle(update.limbs[name].a); - this.limbs[name].SetLinearVelocity(update.limbs[name].lv); - this.limbs[name].SetAngularVelocity(update.limbs[name].av); - } - */ - } - - RubeDoll.prototype.destroy = function() { - - var world = this.body.GetWorld(); - - for (var name in this.limbs) { - world.DestroyBody(this.limbs[name]); - } - - Parent.prototype.destroy.call(this); - }; - - return RubeDoll; -}); \ No newline at end of file diff --git a/app/Game/Core/GameObjects/Items/Skateboard.js b/app/Game/Core/GameObjects/Items/Skateboard.js index 1e12df6..67fc387 100755 --- a/app/Game/Core/GameObjects/Items/Skateboard.js +++ b/app/Game/Core/GameObjects/Items/Skateboard.js @@ -1,125 +1,30 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Item", "Lib/Vendor/Box2D", - "Game/Config/Settings", - "Lib/Utilities/Assert" + "Game/Config/Settings" ], -function (Parent, Box2D, Settings, Assert) { - - "use strict"; +function (Parent, Box2D, Settings) { function Skateboard(physicsEngine, uid, options) { Parent.call(this, physicsEngine, uid, options); - } - - Skateboard.prototype = Object.create(Parent.prototype); - - Skateboard.prototype.createFixture = function () { - Assert.number(this.options.width, this.options.height); - Assert.number(this.options.weight); - - var deckShape = new Box2D.Collision.Shapes.b2PolygonShape(); - var w = this.options.width / Settings.RATIO; - var h = 2 / Settings.RATIO; - deckShape.SetAsOrientedBox(w / 2, h / 2, new Box2D.Common.Math.b2Vec2(0, -(4.5 / Settings.RATIO))); - - var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); - fixtureDef.shape = deckShape; - - var offset = 4, - factor = 80; - var density = ((this.options.weight + offset) / this.options.width / this.options.height) * factor; - fixtureDef.density = density; - fixtureDef.friction = Settings.ITEM_FRICTION; - fixtureDef.restitution = 0.2; - fixtureDef.isSensor = false; - - this.body.CreateFixture(fixtureDef); - - - this.addWheel( - -8, - -2.5 - ); - - this.addWheel( - 7, - -2.5 - ); - - }; - - Skateboard.prototype.addWheel = function(x, y) { - Assert.number(x, y); - - var bodyDef = new Box2D.Dynamics.b2BodyDef(); - bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; - bodyDef.position.x = x / Settings.RATIO; - bodyDef.position.y = y / Settings.RATIO; - bodyDef.angle = 0; - - var wheelShape = new Box2D.Collision.Shapes.b2CircleShape(); - wheelShape.SetRadius(2.5 / Settings.RATIO); - wheelShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(x / Settings.RATIO, y / Settings.RATIO)); - - - var fixtureDef = new Box2D.Dynamics.b2FixtureDef(); - var offset = 4, - factor = 80; - var density = ((0.1 + offset) / 3 / 3) * factor; - fixtureDef.density = density; - fixtureDef.shape = wheelShape; - fixtureDef.restitution = 0.2; - fixtureDef.isSensor = false; - fixtureDef.friction = 0.0005; - - this.body.CreateFixture(fixtureDef); - }; - - Skateboard.prototype.flip = function(direction) { - this.flipDirection = direction; - }; - - return Skateboard; - -}); - - -/* -define([ - "Game/" + GLOBALS.context + "/GameObjects/Item", - "Lib/Vendor/Box2D", - "Game/Config/Settings", - "Lib/Utilities/Assert" -], - -function (Parent, Box2D, Settings, Assert) { - - "use strict"; - - function Skateboard(physicsEngine, uid, options) { - - Parent.call(this, physicsEngine, uid, options); this.wheels = [ - this.addWheel( - options.x + 8, - options.y - 1.5 - ), - this.addWheel( - options.x - 8, - options.y - 1.5 - ) + this.addWheel( + options.x + 8, + options.y - 1.5 + ), + this.addWheel( + options.x - 8, + options.y - 1.5 + ) ]; } Skateboard.prototype = Object.create(Parent.prototype); Skateboard.prototype.createFixture = function () { - Assert.number(this.options.width, this.options.height); - Assert.number(this.options.weight); var deckShape = new Box2D.Collision.Shapes.b2PolygonShape(); var w = this.options.width / Settings.RATIO; @@ -138,18 +43,17 @@ function (Parent, Box2D, Settings, Assert) { fixtureDef.isSensor = false; this.body.CreateFixture(fixtureDef); - }; + } Skateboard.prototype.addWheel = function(x, y) { - Assert.number(x, y); - var bodyDef = new Box2D.Dynamics.b2BodyDef(); + var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_dynamicBody; bodyDef.position.x = x / Settings.RATIO; bodyDef.position.y = y / Settings.RATIO; bodyDef.angle = 0; - var wheelShape = new Box2D.Collision.Shapes.b2CircleShape(); + var wheelShape = new Box2D.Collision.Shapes.b2CircleShape(); wheelShape.SetRadius(1.5 / Settings.RATIO); wheelShape.SetLocalPosition(new Box2D.Common.Math.b2Vec2(0, 0)); @@ -160,23 +64,18 @@ function (Parent, Box2D, Settings, Assert) { fixtureDef.density = density; fixtureDef.shape = wheelShape; fixtureDef.isSensor = false; - fixtureDef.friction = 0; var wheelBody = this.body.GetWorld().CreateBody(bodyDef); wheelBody.CreateFixture(fixtureDef); - //var revoluteJointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef(); - var revoluteJointDef = new Box2D.Dynamics.Joints.b2WeldJointDef(); - //revoluteJointDef.enableMotor = false; + var revoluteJointDef = new Box2D.Dynamics.Joints.b2RevoluteJointDef(); + revoluteJointDef.enableMotor = false; + revoluteJointDef.Initialize(this.body, wheelBody, wheelBody.GetWorldCenter()); + this.body.GetWorld().CreateJoint(revoluteJointDef); - - revoluteJointDef.Initialize(this.body, wheelBody, wheelBody.GetWorldCenter()); - var j = this.body.GetWorld().CreateJoint(revoluteJointDef); - - - // FIXME this means, that we will have bodies in the world, which must not be - // updated (wheels) because they are always connected to a body which will be updated. + // FIXME this means, that we will have bodies in the world, which must not be + // updated (wheels) because they are always connected to a body which will be updated. return wheelBody; }; @@ -186,13 +85,18 @@ function (Parent, Box2D, Settings, Assert) { // FIXME: implement body flip if necessary }; - Skateboard.prototype.throw = function(options, carrierVelocity) { - Parent.prototype.throw.call(this, options, carrierVelocity); + Skateboard.prototype.throw = function(x, y) { + Parent.prototype.throw.call(this, x, y); for (var i = 0; i < this.wheels.length; i++) { var body = this.wheels[i]; + body.SetAwake(true); - this.accelerateBody(body, options, carrierVelocity); + var vector = new Box2D.Common.Math.b2Vec2( + x * Settings.MAX_THROW_FORCE / this.options.weight, + -y * Settings.MAX_THROW_FORCE / this.options.weight + ); + body.SetLinearVelocity(vector); } }; @@ -206,5 +110,4 @@ function (Parent, Box2D, Settings, Assert) { return Skateboard; -}); -*/ \ No newline at end of file +}); \ No newline at end of file diff --git a/app/Game/Core/GameObjects/SpectatorDoll.js b/app/Game/Core/GameObjects/SpectatorDoll.js index 912314a..f86bba6 100644 --- a/app/Game/Core/GameObjects/SpectatorDoll.js +++ b/app/Game/Core/GameObjects/SpectatorDoll.js @@ -4,11 +4,9 @@ define([ ], function (Parent, Box2D) { - - "use strict"; function SpectatorDoll(physicsEngine, uid, player) { - //Parent.call(this, physicsEngine, uid); + Parent.call(this, physicsEngine, uid); } SpectatorDoll.prototype = Object.create(Parent.prototype); @@ -33,9 +31,6 @@ function (Parent, Box2D) { SpectatorDoll.prototype.update = function() { }; - - SpectatorDoll.prototype.destroy = function() { - }; return SpectatorDoll; diff --git a/app/Game/Core/GameObjects/Tile.js b/app/Game/Core/GameObjects/Tile.js index dee3a1a..2f483db 100755 --- a/app/Game/Core/GameObjects/Tile.js +++ b/app/Game/Core/GameObjects/Tile.js @@ -3,25 +3,22 @@ define([ "Lib/Vendor/Box2D", "Game/Config/Settings", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert" + "Lib/Utilities/NotificationCenter" ], -function (Parent, Box2D, Settings, Exception, nc, Assert) { - - "use strict"; +function (Parent, Box2D, Settings, Exception, Nc) { function Tile(physicsEngine, uid, options) { this.options = options; Parent.call(this, physicsEngine, uid); this.createPhysicTile(this.options); + + Nc.trigger(Nc.ns.core.game.gameObject.add, 'fixed', this); } Tile.prototype = Object.create(Parent.prototype); Tile.prototype.getBodyDef = function() { - Assert.number(this.options.x, this.options.y); - Assert.number(this.options.r); var bodyDef = new Box2D.Dynamics.b2BodyDef(); bodyDef.type = Box2D.Dynamics.b2Body.b2_staticBody; @@ -30,7 +27,7 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) { bodyDef.angle = (this.options.r || 0) * 90 * Math.PI / 180; return bodyDef; - }; + } Tile.prototype.createPhysicTile = function (tile) { var vertices = this.createVertices(tile); @@ -44,7 +41,7 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) { fixtureDef.restitution = Settings.TILE_RESTITUTION; fixtureDef.isSensor = false; this.body.CreateFixture(fixtureDef); - }; + } Tile.prototype.createVertices = function (tile) { var vs = []; @@ -105,17 +102,22 @@ function (Parent, Box2D, Settings, Exception, nc, Assert) { default: throw new Exception("Tile Creation - no shape given"); + break; } return vs; - }; + } Tile.prototype.mkArg = function (multiplier) { return Settings.TILE_SIZE / 2 / Settings.RATIO * multiplier; - }; + } Tile.prototype.addVec = function (vs, m1, m2) { return vs.push(new Box2D.Common.Math.b2Vec2(this.mkArg(m1), this.mkArg(m2))); + } + + Tile.prototype.destroy = function() { + Nc.trigger(Nc.ns.core.game.gameObject.remove, 'fixed', this); }; return Tile; diff --git a/app/Game/Core/Loader/Level.js b/app/Game/Core/Loader/Level.js index 83cabde..e20b6ab 100755 --- a/app/Game/Core/Loader/Level.js +++ b/app/Game/Core/Loader/Level.js @@ -2,17 +2,14 @@ define([ "Game/Config/Settings", "Lib/Vendor/Box2D", "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Abstract", "Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/GameObjects/Tile", "Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard", "Game/" + GLOBALS.context + "/GameObjects/Items/RagDoll", - "Game/" + GLOBALS.context + "/GameObjects/Items/RubeDoll" + "Game/" + GLOBALS.context + "/GameObjects/Items/Rube" -], function (Settings, Box2D, nc, Abstract, CollisionDetector, Tile, Item, Skateboard, RagDoll, RubeDoll) { - - "use strict"; +], function (Settings, Box2D, Nc, CollisionDetector, Tile, Item, Skateboard, RagDoll, Rube) { function Level (uid, engine) { this.uid = uid; @@ -20,83 +17,87 @@ define([ this.levelObject = null; this.isLoaded = false; this.load(this.uid); - this.spawnPoints = null; } Level.prototype.load = function (uid) { var self = this; - // FIXME: check if theres a security hazard here (user injected path) - var path = Settings.MAPS_PATH + uid + ".json"; - this.loadLevelDataFromPath(path, function (levelData) { - self.setup(levelData); + var path = Settings.MAPS_PATH + uid + ".json" + this.loadLevelDataFromPath(path, function(levelData) { + self.levelData = levelData; + self.createTiles(); + self.createItems(); + self.isLoaded = true; + Nc.trigger(Nc.ns.core.game.events.level.loaded); }); - }; - - Level.prototype.setup = function(levelData) { // jshint unused:false - this.isLoaded = true; - nc.trigger(nc.ns.core.game.events.level.loaded); - }; - - Level.prototype.createItems = function(options) { - for (var i = 0; i < options.length; i++) { - var uid = "item-" + i; - this.createItem(uid, options[i]); - } - }; + } Level.prototype.createItem = function(uid, options) { - switch(options.type) { - case "skateboard": + case 'skateboard': return new Skateboard(this.engine, uid, options); - case "ragdoll": + case 'ragdoll': return new RagDoll(this.engine, uid, options); - case "rubedoll": - return new RubeDoll(this.engine, uid, options); + case 'rube': + return new Rube(this.engine, uid, options); default: return new Item(this.engine, uid, options); } }; - Level.prototype.createTiles = function(options) { - for (var i = 0; i < options.length; i++) { - new Tile(this.engine, "tile-" + i, options[i]); - } - }; - - Level.prototype.createSpawnPoints = function(points) { - this.spawnPoints = points; - }; - - Level.prototype.setupLayer = function(options, behind, referenceId) { // jshint unused:false - // will be extended (so far only in client) - }; - - - Level.prototype.createContainer = function(options) { // jshint unused:false - // nothing to do here yet, in the future perhaps synchronize day/night graphics - }; - Level.prototype.getRandomSpawnPoint = function() { - if(!this.spawnPoints) { - return { - x: 150 + Math.random() * 300, - y: -500 - }; - } - - var size = this.spawnPoints.length; - var object = this.spawnPoints[parseInt(Math.random() * (size -1), 10)]; - + throw new Error("Level not loaded."); return { - x: object.x / Settings.TILE_RATIO, - y: object.y / Settings.TILE_RATIO + x: 150 + Math.random() * 300, + y: -500 }; }; Level.prototype.destroy = function () { + /* + for (var key in this.gameObjects) { + for (var i = 0; i < this.gameObjects[key].length; i++) { + this.gameObjects[key][i].destroy(); + } + } + */ this.isLoaded = false; + } + +/* Extended by TiledLevel + Level.prototype.createTiles = function () { + + if (!this.levelData || !this.levelData.tiles || this.levelData.tiles.length < 1) { + throw "Level: Can't create physic tiles, no tiles found"; + } + + var tiles = this.levelData.tiles; + + for (var i = 0; i < tiles.length; i++) { + var options = tiles[i]; + //options.m = this.tileAtPositionExists(options.x, options.y - 1) ? "Soil" : "GrassSoil"; + options.m = "Soil"; + //this.gameObjects.fixed.push( + new Tile(this.engine, "tile-" + i, options); + //); + } + } +*/ + +/* Extended by TiledLevel + Level.prototype.createItems = function() { + if (!this.levelData || !this.levelData.items) { + return; + } + var items = this.levelData.items; + + for (var i = 0; i < items.length; i++) { + var options = items[i]; + var uid = "item-" + i; + var item = this.createItem(uid, options); + //this.gameObjects.animated.push(item); + }; }; +*/ return Level; -}); \ No newline at end of file +}) \ No newline at end of file diff --git a/app/Game/Core/Loader/TiledLevel.js b/app/Game/Core/Loader/TiledLevel.js index 16834b0..9ffe666 100755 --- a/app/Game/Core/Loader/TiledLevel.js +++ b/app/Game/Core/Loader/TiledLevel.js @@ -3,191 +3,115 @@ define([ "Game/Config/Settings", "Game/Config/ItemSettings", "Lib/Vendor/Box2D", - "Lib/Utilities/OptionsHelper", + "Lib/Utilities/Options", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter", - "Lib/Utilities/Assert", - "Game/Client/View/Abstract/Layer", "Game/" + GLOBALS.context + "/Collision/Detector", "Game/" + GLOBALS.context + "/GameObjects/Tile", "Game/" + GLOBALS.context + "/GameObjects/Item", "Game/" + GLOBALS.context + "/GameObjects/Items/Skateboard", -], function (Parent, Settings, ItemSettings, Box2D, optionsHelper, Exception, nc, Assert, AbstractLayer, CollisionDetector, Tile, Item, Skateboard) { +], function (Parent, Settings, ItemSettings, Box2D, Options, Exception, CollisionDetector, Tile, Item, Skateboard) { - "use strict"; - + // Public function TiledLevel (path, engine) { - this.layerMapping = { - tiles: this.createTiles.bind(this), - items: this.createItems.bind(this), - spawnpoints: this.createSpawnPoints.bind(this) - //collision: this.createTiles.bind(this), collision renamed to tiles - }; - this.levelData = null; Parent.call(this, path, engine); } TiledLevel.prototype = Object.create(Parent.prototype); - - TiledLevel.prototype.setup = function(levelData) { - this.levelData = levelData; - - var spawnpointsExists = levelData.layers.some(function(o) { - return o.name == AbstractLayer.ID.SPAWN; - }); - - if (!spawnpointsExists) { - console.warn("No layerMapping for level file layer: " + layerOptions.name); - return; + TiledLevel.prototype.createTiles = function () { + if (!this.levelData) { + throw "Level: Can't create level, nothing found"; } - function getLayerId(name, i) { - var mapping = { - tiles: AbstractLayer.ID.TILE, - items: AbstractLayer.ID.ITEM, - spawnpoints: AbstractLayer.ID.SPAWN - }; - if(mapping[name]) { - return mapping[name]; + var collisionLayer = this.getLayer(this.levelData, "collision"); + + if(collisionLayer) { + + for (var i = 0; i < collisionLayer.data.length; i++) { + + var gid = collisionLayer.data[i]; + if(gid === 0) continue; + + var imagePath = this.getTileImagePath(gid); + + + var parts = imagePath.split("/"); + var tileType = parts[parts.length - 1].split(".")[0].split(""); + + // FIXME rename s to shape, r to rotation etc. + + var options = { + s: parseInt(tileType[0], 10), + r: parseInt(tileType[1], 10), + t: imagePath, + x: i % collisionLayer.width, + y: parseInt(i / collisionLayer.height , 10) + } + + //this.gameObjects.fixed.push( + new Tile(this.engine, "tile-" + i, options); + //); } - return "layer-" + i + "-" + name; + } else { + console.warn("Level: No collision Layer given"); } + } - var spawnpointsFound = false, - lastLayerId = null; + TiledLevel.prototype.createItems = function() { + var objects = this.getLayer(this.levelData, "items").objects; - // from spawnpoints to background - for (var i = levelData.layers.length - 1; i >= 0; i--) { - var layerOptions = levelData.layers[i]; - layerOptions.z = i; - layerOptions.layerId = getLayerId(layerOptions.name, i); - - if (layerOptions.name == AbstractLayer.ID.SPAWN) { - spawnpointsFound = true; - } - - if (!spawnpointsFound) { - continue; - } - - // Setting up spawnpoints and then all layers behind it - this.setupLayer(layerOptions, true, lastLayerId); - - if(this.layerMapping[layerOptions.name]) { - this.layerMapping[layerOptions.name](layerOptions); - } - - lastLayerId = layerOptions.layerId; - } - - spawnpointsFound = false; // reset (used in mkLayer) - lastLayerId = AbstractLayer.ID.SPAWN; - - - // from spawnpoints to foreground - for (var i = 0; i < levelData.layers.length; i++) { - var layerOptions = levelData.layers[i]; - layerOptions.z = i; - layerOptions.layerId = getLayerId(layerOptions.name, i); - - if (layerOptions.name == AbstractLayer.ID.SPAWN) { - spawnpointsFound = true; - continue; - } - - if (!spawnpointsFound) { - continue; - } - - // Setting up all layers before - this.setupLayer(layerOptions, false, lastLayerId); - - if(this.layerMapping[layerOptions.name]) { - this.layerMapping[layerOptions.name](layerOptions); - } - - lastLayerId = layerOptions.layerId; - } - - - Parent.prototype.setup.call(this, levelData); - }; - - TiledLevel.prototype.createTiles = function(options) { - - var data = options.data; - var tilesOptions = []; - for (var i = 0; i < data.length; i++) { - - var gid = data[i]; - if(gid === 0) continue; - - var imagePath = this.getTileImagePath(gid); - - var parts = imagePath.split("/"); - var tileType = parts[parts.length - 1].split(".")[0].split(""); - - // FIXME rename s to shape, r to rotation etc. - - var tileOptions = { - s: parseInt(tileType[0], 10), - r: parseInt(tileType[1], 10), - t: imagePath, - x: i % options.width, - y: parseInt(i / options.width , 10) - }; - - tilesOptions.push(tileOptions); - } - - Parent.prototype.createTiles.call(this, tilesOptions); - }; - - TiledLevel.prototype.createItems = function(options) { - var objects = options.objects; - var itemsOptions = []; for (var i = 0; i < objects.length; i++) { - options = this.gatherOptions(objects[i]); - itemsOptions.push(options); - } + var object = objects[i]; - Parent.prototype.createItems.call(this, itemsOptions); - }; + var options = this.gatherOptions(object); - TiledLevel.prototype.createSpawnPoints = function(options) { - var points = options.objects.map(function(o) { - return { x: o.x, y: o.y }; - }); - - Parent.prototype.createSpawnPoints.call(this, points); + var uid = "item-" + i; + var item = this.createItem(uid, options); + //this.gameObjects.animated.push(item); + }; }; TiledLevel.prototype.gatherOptions = function(tiledObject) { - var options = this.getDefaultItemSettingsByName(tiledObject.name); + var options = {}; + options.name = tiledObject.name; - options.x = (tiledObject.x + options.width / 2) / Settings.TILE_RATIO; + options.rotation = tiledObject.rotation; + options.width = tiledObject.width / Settings.TILE_RATIO; + options.height = tiledObject.height / Settings.TILE_RATIO; + options.x = (tiledObject.x + tiledObject.width / 2) / Settings.TILE_RATIO; options.y = (tiledObject.y + options.height / 2) / Settings.TILE_RATIO; - // FIXME: check RAD vs. DEG for options.rotation = tiledObject.rotation; + + if (!options.width) options.width = undefined; + if (!options.height) options.height = undefined; + + var defaultOptions = this.getDefaultItemSettingsByName(options.name); + + options = Options.merge(options, defaultOptions); + //options = Options.merge(tiledObject.properties, options); return options; }; + TiledLevel.prototype.getDefaultItemSettingsByName = function(name) { if(!name) { - throw new Exception("Item name cannot be be empty"); + throw new Exception('Item name cannot be be empty'); } if(ItemSettings[name] === undefined) { - throw new Exception("Item name (" + name + ") cannot be found in item list"); + throw new Exception('Item name (' + name + ') cannot be found in item list'); } - return optionsHelper.merge(ItemSettings[name], ItemSettings.Default); + var options = ItemSettings.Default; + + options = Options.merge(ItemSettings[name], options); + + return options; }; TiledLevel.prototype.getTileImagePath = function(gid) { @@ -198,7 +122,35 @@ define([ return tileset.tiles["" + (gid - offset)].image; } } + } + + TiledLevel.prototype.getRandomSpawnPoint = function() { + if(!this.levelData) { + return Parent.prototype.getRandomSpawnPoint.call(this); + } else { + + var spawnLayer = this.getLayer(this.levelData, "spawnpoints"); + + var size = spawnLayer.objects.length; + var object = spawnLayer.objects[parseInt(Math.random() * (size -1), 10)]; + + return { + x: object.x / Settings.TILE_RATIO, + y: object.y / Settings.TILE_RATIO + } + + } + }; + + TiledLevel.prototype.getLayer = function(levelData, name) { + for (var i = 0; i < levelData.layers.length; i++) { + if(levelData.layers[i].name === name) { + return levelData.layers[i]; + } + } + + throw "Layer '" + name + "' not found."; }; return TiledLevel; -}); \ No newline at end of file +}) \ No newline at end of file diff --git a/app/Game/Core/Physics/Engine.js b/app/Game/Core/Physics/Engine.js index 4ec27b2..8eeb92c 100755 --- a/app/Game/Core/Physics/Engine.js +++ b/app/Game/Core/Physics/Engine.js @@ -5,9 +5,7 @@ define([ "Lib/Utilities/NotificationCenter" ], -function (Settings, Box2D, CollisionDetector, nc) { - - "use strict"; +function (Settings, Box2D, CollisionDetector, Nc) { function Engine () { this.world = new Box2D.Dynamics.b2World( @@ -15,30 +13,33 @@ function (Settings, Box2D, CollisionDetector, nc) { Settings.BOX2D_ALLOW_SLEEP ); this.world.SetWarmStarting(true); + this.ground = null; this.lastStep = Date.now(); this.worldQueue = []; this.ncTokens = [ - nc.on(nc.ns.channel.engine.worldQueue.add, this.addToWorldQueue, this) + Nc.on(Nc.ns.channel.engine.worldQueue.add, this.addToWorldQueue, this) ]; } + Engine.prototype.getWorld = function () { + return this.world; + } + + Engine.prototype.getGround = function () { + return this.ground; + } + Engine.prototype.setCollisionDetector = function () { var detector = new CollisionDetector(); this.world.SetContactListener(detector.getListener()); } - Engine.prototype.getWorldForRubeLoader = function() { - return this.world; - }; - Engine.prototype.createBody = function (bodyDef) { - return this.world.CreateBody(bodyDef); - } - - Engine.prototype.destroyBody = function (body) { - return this.world.DestroyBody(body); + var body = this.world.CreateBody(bodyDef); + if(!this.ground) this.ground = body; + return body; } Engine.prototype.addToWorldQueue = function(callback) { @@ -62,8 +63,8 @@ function (Settings, Box2D, CollisionDetector, nc) { } Engine.prototype.destroy = function() { - nc.offAll(this.ncTokens); delete this.world; + Nc.offAll(this.ncTokens); }; diff --git a/app/Game/Core/Player.js b/app/Game/Core/Player.js index 996facb..9543c02 100755 --- a/app/Game/Core/Player.js +++ b/app/Game/Core/Player.js @@ -1,19 +1,16 @@ define([ "Game/" + GLOBALS.context + "/GameObjects/Doll", - "Game/" + GLOBALS.context + "/Control/PlayerController", "Game/Config/Settings", "Lib/Utilities/NotificationCenter", "Lib/Utilities/Exception", - "Lib/Utilities/ColorConverter", "Game/" + GLOBALS.context + "/GameObjects/SpectatorDoll", - "Game/" + GLOBALS.context + "/GameObjects/Items/RubeDoll" + "Game/" + GLOBALS.context + "/GameObjects/Items/RagDoll" ], -function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, SpectatorDoll, RubeDoll) { - "use strict"; +function (Doll, Settings, Nc, Exception, SpectatorDoll, RagDoll) { - function Player (id, physicsEngine, user, revealedGameController) { + function Player (id, physicsEngine, user) { this.stats = { health: 100, deaths: 0, @@ -22,23 +19,18 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect this.user = user; this.physicsEngine = physicsEngine; - this.playerController = null; // pre-initialise with null, because client/players don't get one + this.playerController = null; this.doll; this.id = id; - this.spawned = false; + this.isSpawned = false; this.holdingItem = null; - this.inBetweenRounds = true; this.spectatorDoll = new SpectatorDoll(this.physicsEngine, "spectatorDoll-" + this.id, this); - this.revealedGameController = revealedGameController; - this.modifierActivated = false; + + Nc.trigger(Nc.ns.core.game.gameObject.add, 'animated', this); } - Player.prototype.getNickname = function() { - return this.user.options.nickname; - }; - Player.prototype.getActiveDoll = function() { - if(this.spawned) { + if(this.isSpawned) { return this.doll; } else if (this.ragDoll) { return this.ragDoll; @@ -49,13 +41,9 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect Player.prototype.spawn = function (x, y) { this.doll = new Doll(this.physicsEngine, "doll-" + this.id, this); this.doll.spawn(x, y); - this.spawned = true; + this.isSpawned = true; } - Player.prototype.isSpawned = function() { - return this.spawned; - }; - Player.prototype.getPosition = function () { return this.getActiveDoll().getPosition(); } @@ -66,73 +54,54 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect Player.prototype.move = function (direction) { - if(!this.spawned) return false; - this.doll.move(direction, this.modifierActivated); + if(!this.isSpawned) return false; + this.doll.move(direction); } Player.prototype.stop = function () { - if(!this.spawned) return false; + if(!this.isSpawned) return false; this.doll.stop(); } Player.prototype.jump = function () { - if(!this.spawned) return false; + if(!this.isSpawned) return false; this.doll.jump(); } Player.prototype.jumpStop = function () { - if(!this.spawned) return false; + if(!this.isSpawned) return false; this.doll.jumpStop(); } Player.prototype.lookAt = function (x, y) { - if(!this.spawned) return false; + if(!this.isSpawned) return false; // FIXME implement spectator movement here this.doll.lookAt(x, y); } - Player.prototype.activateModifier = function () { - if(!this.spawned) return false; - this.modifierActivated = true; - } - - Player.prototype.deactivateModifier = function () { - if(!this.spawned) return false; - this.modifierActivated = false; - } - Player.prototype.grab = function(item) { - if(!this.spawned) return false; + if(!this.isSpawned) return false; this.doll.grab(item); item.beingGrabbed(this); this.holdingItem = item; }; - Player.prototype.throw = function(options, item) { - if(!this.spawned) return false; - this.doll.throw(item, options); + Player.prototype.throw = function(x, y, item) { + if(!this.isSpawned) return false; + this.doll.throw(item, x, y); item.beingReleased(this); this.holdingItem = null; }; Player.prototype.kill = function(killedByPlayer, ragDollId) { - if(!this.spawned) return false; + if(!this.isSpawned) return false; // FIXME: do something better then just respawn in GameController if(this.holdingItem) { - var options = { - x: 0, - y: 0, - av: 0 - }; - this.throw(options, this.holdingItem) + this.throw(0, 0, this.holdingItem) } // prepare for creating the ragdoll - - var converter = new ColorConverter(); - var primaryColor = converter.getColorByName(this.getNickname()); - var options = { x: this.getPosition().x * Settings.RATIO, y: this.getPosition().y * Settings.RATIO, @@ -141,23 +110,21 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect image: "chest.png", name: "RagDoll", rotation: 0, - type: "rubedoll", + type: "ragdoll", weight: 3, width: 5, - height: 12, - primaryColor: primaryColor, - direction: this.doll.lookDirection + height: 12 }; - var rubeDoll = new RubeDoll(this.physicsEngine, "rubeDoll-" + this.id + "-" + ragDollId, options); - rubeDoll.setVelocities(this.doll.getVelocities()); + var ragDoll = new RagDoll(this.physicsEngine, "ragDoll-" + this.id + "-" + ragDollId, options); + ragDoll.setVelocities(this.doll.getVelocities()); - this.spawned = false; + this.isSpawned = false; this.doll.destroy(); this.doll = null; - this.ragDoll = rubeDoll; + this.ragDoll = ragDoll; }; Player.prototype.update = function () { @@ -173,23 +140,16 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect Player.prototype.destroy = function () { - // FIXME add destroy nc hook + Nc.trigger(Nc.ns.core.game.gameObject.remove, 'animated', this); if(this.holdingItem) { - var options = { - x: 0, - y: 0, - av: 0 - }; - this.throw(options, this.holdingItem); + this.throw(0, 0, this.holdingItem); } this.spectatorDoll.destroy(); - // doll destoys itself at the end cause its a gameobject - // but on userLeft, the player has to destroy it. if(this.doll) { - this.doll.destroy(); + this.doll.destroy(); } if(this.playerController) { @@ -197,13 +157,9 @@ function (Doll, PlayerController, Settings, nc, Exception, ColorConverter, Spect } } - Player.prototype.setInBetweenRounds = function(inBetweenRounds) { - this.inBetweenRounds = inBetweenRounds; - }; - - Player.prototype.isInBetweenRounds = function() { - return this.inBetweenRounds; - }; + Player.prototype.setPlayerController = function(playerController) { + this.playerController = playerController; + } return Player; }); diff --git a/app/Game/Core/User.js b/app/Game/Core/User.js index e2eda24..de3264f 100755 --- a/app/Game/Core/User.js +++ b/app/Game/Core/User.js @@ -1,7 +1,4 @@ -define([ -], - -function () { +define(function () { function User (id, options) { this.id = id; diff --git a/app/Lib/Utilities/Abstract.js b/app/Lib/Utilities/Abstract.js deleted file mode 100644 index c68e8ae..0000000 --- a/app/Lib/Utilities/Abstract.js +++ /dev/null @@ -1,20 +0,0 @@ -define([ - "Lib/Utilities/Exception" -], - -function (Exception) { - - "use strict"; - - function Abstract() { - } - - Abstract.prototype.addMethod = function(methodName, params) { - this.prototype[methodName] = function() { - throw new Exception("Abstract method", this, methodName + "(" + params.join(', ') + ") not overwritten."); - } - } - - return Abstract; - -}); \ No newline at end of file diff --git a/app/Lib/Utilities/Assert.js b/app/Lib/Utilities/Assert.js deleted file mode 100644 index 0a89ed7..0000000 --- a/app/Lib/Utilities/Assert.js +++ /dev/null @@ -1,21 +0,0 @@ -define([ - "Lib/Utilities/Exception" -], - -function (Exception) { - - "use strict"; - - var Assert = {}; - - Assert.number = function() { - for (var i = 0; i < arguments.length; i++) { - if(isNaN(parseFloat(arguments[i]))) { - throw new Exception("Assert: not a number ", JSON.stringify(arguments)); - } - } - }; - - return Assert; - -}); \ No newline at end of file diff --git a/app/Lib/Utilities/Channel/Extensions.js b/app/Lib/Utilities/Channel/Extensions.js deleted file mode 100644 index 269e880..0000000 --- a/app/Lib/Utilities/Channel/Extensions.js +++ /dev/null @@ -1,22 +0,0 @@ -define([ - "Lib/Utilities/Core/Extensions" -], - -function (Parent) { - - //"use strict"; - - console.checkpoint = function (s) { - console.log(" \033[32mbeep - \033[0m" + s); - } - - console.warn = function (s) { - console.log(" \033[33mwarn - \033[0m" + s); - } - - console.error = function (s) { - console.log(" \033[31merror - \033[0m" + s); - } - - -}); \ No newline at end of file diff --git a/app/Lib/Utilities/Client/Extensions.js b/app/Lib/Utilities/Client/Extensions.js deleted file mode 100644 index 07e65ab..0000000 --- a/app/Lib/Utilities/Client/Extensions.js +++ /dev/null @@ -1,8 +0,0 @@ -define([ - "Lib/Utilities/Core/Extensions" -], - -function (Parent) { - - "use strict"; -}); \ No newline at end of file diff --git a/app/Lib/Utilities/ColorConverter.js b/app/Lib/Utilities/ColorConverter.js deleted file mode 100644 index 6332a74..0000000 --- a/app/Lib/Utilities/ColorConverter.js +++ /dev/null @@ -1,83 +0,0 @@ -define([ - "Lib/Vendor/CryptoJS" -], - -function (CryptoJS) { - - "use strict"; - - function ColorConverter() { - this.sin = 0; - var palette = [ - 0x634c72, - 0x724c5e, - 0x787950, - 0x507971, - 0x506a79, - 0x8c423c, - 0x557e4a, - 0x436785, - 0xa62423, - 0x427f87, - 0x472e1a, - 0x4d667c, - 0x2a3c49, - 0x7c7e2b, - 0x3b3c21, - 0x263c27, - 0x7e897e, - 0xb55014, - 0x978c32, - 0x739137, - 0x46824f, - 0x19b0b4, - 0x1c1eb1, - 0xccb206, - 0x433e20, - 0x201a13, - 0x145396, - 0x313d08, - 0xb7a345, - 0xdc168a, - 0x310505, - 0x051631, - ]; - /* - var element, color; - - var start = 5; - var step = 4; - var max = 16; - - for(var r=start; r>>2]|=(c[b>>>2]>>>24-8*(b%4)&255)<<24-8*((d+b)%4);else if(65535>>2]=c[b>>>2];else e.push.apply(e,c);this.sigBytes+=a;return this},clamp:function(){var a=this.words,e=this.sigBytes;a[e>>>2]&=4294967295<<32-8*(e%4);a.length=o.ceil(e/4)},clone:function(){var a= -n.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var e=[],c=0;c>>2]>>>24-8*(d%4)&255;c.push((b>>>4).toString(16));c.push((b&15).toString(16))}return c.join("")},parse:function(a){for(var b=a.length,c=[],d=0;d>>3]|=parseInt(a.substr(d,2),16)<<24-4*(d%8);return j.create(c,b/2)}},p=k.Latin1={stringify:function(a){for(var b= -a.words,a=a.sigBytes,c=[],d=0;d>>2]>>>24-8*(d%4)&255));return c.join("")},parse:function(a){for(var b=a.length,c=[],d=0;d>>2]|=(a.charCodeAt(d)&255)<<24-8*(d%4);return j.create(c,b)}},h=k.Utf8={stringify:function(a){try{return decodeURIComponent(escape(p.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return p.parse(unescape(encodeURIComponent(a)))}},b=m.BufferedBlockAlgorithm=n.extend({reset:function(){this._data=j.create(); -this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=h.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var b=this._data,c=b.words,d=b.sigBytes,f=this.blockSize,i=d/(4*f),i=a?o.ceil(i):o.max((i|0)-this._minBufferSize,0),a=i*f,d=o.min(4*a,d);if(a){for(var h=0;h>>32-d)+f}function l(b,f,a,e,c,d,g){b=b+(f&e|a&~e)+c+g;return(b<>>32-d)+f}function m(b,f,a,e,c,d,g){b=b+(f^a^e)+c+g;return(b<>>32-d)+f}function n(b,f,a,e,c,d,g){b=b+(a^(f|~e))+c+g;return(b<>>32-d)+f}var j=CryptoJS,k=j.lib,r=k.WordArray,k=k.Hasher,p=j.algo,h=[];(function(){for(var b=0;64>b;b++)h[b]=4294967296*o.abs(o.sin(b+1))|0})();p=p.MD5=k.extend({_doReset:function(){this._hash=r.create([1732584193,4023233417, -2562383102,271733878])},_doProcessBlock:function(b,f){for(var a=0;16>a;a++){var e=f+a,c=b[e];b[e]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360}for(var e=this._hash.words,c=e[0],d=e[1],g=e[2],i=e[3],a=0;64>a;a+=4)16>a?(c=q(c,d,g,i,b[f+a],7,h[a]),i=q(i,c,d,g,b[f+a+1],12,h[a+1]),g=q(g,i,c,d,b[f+a+2],17,h[a+2]),d=q(d,g,i,c,b[f+a+3],22,h[a+3])):32>a?(c=l(c,d,g,i,b[f+(a+1)%16],5,h[a]),i=l(i,c,d,g,b[f+(a+6)%16],9,h[a+1]),g=l(g,i,c,d,b[f+(a+11)%16],14,h[a+2]),d=l(d,g,i,c,b[f+a%16],20,h[a+3])):48>a?(c= -m(c,d,g,i,b[f+(3*a+5)%16],4,h[a]),i=m(i,c,d,g,b[f+(3*a+8)%16],11,h[a+1]),g=m(g,i,c,d,b[f+(3*a+11)%16],16,h[a+2]),d=m(d,g,i,c,b[f+(3*a+14)%16],23,h[a+3])):(c=n(c,d,g,i,b[f+3*a%16],6,h[a]),i=n(i,c,d,g,b[f+(3*a+7)%16],10,h[a+1]),g=n(g,i,c,d,b[f+(3*a+14)%16],15,h[a+2]),d=n(d,g,i,c,b[f+(3*a+5)%16],21,h[a+3]));e[0]=e[0]+c|0;e[1]=e[1]+d|0;e[2]=e[2]+g|0;e[3]=e[3]+i|0},_doFinalize:function(){var b=this._data,f=b.words,a=8*this._nDataBytes,e=8*b.sigBytes;f[e>>>5]|=128<<24-e%32;f[(e+64>>>9<<4)+14]=(a<<8|a>>> -24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(f.length+1);this._process();b=this._hash.words;for(f=0;4>f;f++)a=b[f],b[f]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360}});j.MD5=k._createHelper(p);j.HmacMD5=k._createHmacHelper(p)})(Math); - - return CryptoJS; - -}); \ No newline at end of file diff --git a/app/Lib/Vendor/Pixi/pixi.dev.1.5.1.js b/app/Lib/Vendor/Pixi/pixi.dev.1.5.1.js deleted file mode 100644 index c7dd126..0000000 --- a/app/Lib/Vendor/Pixi/pixi.dev.1.5.1.js +++ /dev/null @@ -1,14221 +0,0 @@ -/** - * @license - * pixi.js - v1.5.1 - * Copyright (c) 2012-2014, Mat Groves - * http://goodboydigital.com/ - * - * Compiled: 2014-02-13 - * - * pixi.js is licensed under the MIT License. - * http://www.opensource.org/licenses/mit-license.php - */ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -(function(){ - - var root = this; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * @module PIXI - */ -var PIXI = PIXI || {}; - -/* -* -* This file contains a lot of pixi consts which are used across the rendering engine -* @class Consts -*/ -PIXI.WEBGL_RENDERER = 0; -PIXI.CANVAS_RENDERER = 1; - -// useful for testing against if your lib is using pixi. -PIXI.VERSION = "v1.5.1"; - -// the various blend modes supported by pixi -PIXI.blendModes = { - NORMAL:0, - ADD:1, - MULTIPLY:2, - SCREEN:3, - OVERLAY:4, - DARKEN:5, - LIGHTEN:6, - COLOR_DODGE:7, - COLOR_BURN:8, - HARD_LIGHT:9, - SOFT_LIGHT:10, - DIFFERENCE:11, - EXCLUSION:12, - HUE:13, - SATURATION:14, - COLOR:15, - LUMINOSITY:16 -}; - -// the scale modes -PIXI.scaleModes = { - DEFAULT:0, - LINEAR:0, - NEAREST:1 -}; - -// interaction frequency -PIXI.INTERACTION_FREQUENCY = 30; -PIXI.AUTO_PREVENT_DEFAULT = true; - -PIXI.RAD_TO_DEG = 180 / Math.PI; -PIXI.DEG_TO_RAD = Math.PI / 180; -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. - * - * @class Point - * @constructor - * @param x {Number} position of the point on the x axis - * @param y {Number} position of the point on the y axis - */ -PIXI.Point = function(x, y) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; -}; - -/** - * Creates a clone of this point - * - * @method clone - * @return {Point} a copy of the point - */ -PIXI.Point.prototype.clone = function() -{ - return new PIXI.Point(this.x, this.y); -}; - -// constructor -PIXI.Point.prototype.constructor = PIXI.Point; - -PIXI.Point.prototype.set = function(x, y) -{ - this.x = x || 0; - this.y = y || ( (y !== 0) ? this.x : 0 ) ; -}; - - -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height. - * - * @class Rectangle - * @constructor - * @param x {Number} The X coord of the upper-left corner of the rectangle - * @param y {Number} The Y coord of the upper-left corner of the rectangle - * @param width {Number} The overall width of this rectangle - * @param height {Number} The overall height of this rectangle - */ -PIXI.Rectangle = function(x, y, width, height) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -}; - -/** - * Creates a clone of this Rectangle - * - * @method clone - * @return {Rectangle} a copy of the rectangle - */ -PIXI.Rectangle.prototype.clone = function() -{ - return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -}; - -/** - * Checks whether the x and y coordinates passed to this function are contained within this Rectangle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coords are within this Rectangle - */ -PIXI.Rectangle.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; - - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } - - return false; -}; - -// constructor -PIXI.Rectangle.prototype.constructor = PIXI.Rectangle; - -PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); -/** - * @author Adrien Brault - */ - -/** - * @class Polygon - * @constructor - * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon, - * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be - * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the - * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are - * Numbers. - */ -PIXI.Polygon = function(points) -{ - //if points isn't an array, use arguments as the array - if(!(points instanceof Array)) - points = Array.prototype.slice.call(arguments); - - //if this is a flat array of numbers, convert it to points - if(typeof points[0] === 'number') { - var p = []; - for(var i = 0, il = points.length; i < il; i+=2) { - p.push( - new PIXI.Point(points[i], points[i + 1]) - ); - } - - points = p; - } - - this.points = points; -}; - -/** - * Creates a clone of this polygon - * - * @method clone - * @return {Polygon} a copy of the polygon - */ -PIXI.Polygon.prototype.clone = function() -{ - var points = []; - for (var i=0; i y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); - - if(intersect) inside = !inside; - } - - return inside; -}; - -// constructor -PIXI.Polygon.prototype.constructor = PIXI.Polygon; - -/** - * @author Chad Engler - */ - -/** - * The Circle object can be used to specify a hit area for displayObjects - * - * @class Circle - * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this circle - * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this circle - * @param radius {Number} The radius of the circle - */ -PIXI.Circle = function(x, y, radius) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property radius - * @type Number - * @default 0 - */ - this.radius = radius || 0; -}; - -/** - * Creates a clone of this Circle instance - * - * @method clone - * @return {Circle} a copy of the polygon - */ -PIXI.Circle.prototype.clone = function() -{ - return new PIXI.Circle(this.x, this.y, this.radius); -}; - -/** - * Checks whether the x, and y coordinates passed to this function are contained within this circle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this polygon - */ -PIXI.Circle.prototype.contains = function(x, y) -{ - if(this.radius <= 0) - return false; - - var dx = (this.x - x), - dy = (this.y - y), - r2 = this.radius * this.radius; - - dx *= dx; - dy *= dy; - - return (dx + dy <= r2); -}; - -// constructor -PIXI.Circle.prototype.constructor = PIXI.Circle; - - -/** - * @author Chad Engler - */ - -/** - * The Ellipse object can be used to specify a hit area for displayObjects - * - * @class Ellipse - * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse - * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse - * @param width {Number} The overall width of this ellipse - * @param height {Number} The overall height of this ellipse - */ -PIXI.Ellipse = function(x, y, width, height) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -}; - -/** - * Creates a clone of this Ellipse instance - * - * @method clone - * @return {Ellipse} a copy of the ellipse - */ -PIXI.Ellipse.prototype.clone = function() -{ - return new PIXI.Ellipse(this.x, this.y, this.width, this.height); -}; - -/** - * Checks whether the x and y coordinates passed to this function are contained within this ellipse - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coords are within this ellipse - */ -PIXI.Ellipse.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - //normalize the coords to an ellipse with center 0,0 - var normx = ((x - this.x) / this.width), - normy = ((y - this.y) / this.height); - - normx *= normx; - normy *= normy; - - return (normx + normy <= 1); -}; - -/** -* Returns the framing rectangle of the ellipse as a PIXI.Rectangle object -* -* @method getBounds -* @return {Rectangle} the framing rectangle -*/ -PIXI.Ellipse.prototype.getBounds = function() -{ - return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -}; - -// constructor -PIXI.Ellipse.prototype.constructor = PIXI.Ellipse; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.determineMatrixArrayType = function() { - return (typeof Float32Array !== 'undefined') ? Float32Array : Array; -}; - -/* -* @class Matrix2 -* The Matrix2 class will choose the best type of array to use between -* a regular javascript Array and a Float32Array if the latter is available -* -*/ -PIXI.Matrix2 = PIXI.determineMatrixArrayType(); - -/* -* @class Matrix -* The Matrix class is now an object, which makes it a lot faster, -* here is a representation of it : -* | a | b | tx| -* | c | c | ty| -* | 0 | 0 | 1 | -* -*/ -PIXI.Matrix = function() -{ - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.tx = 0; - this.ty = 0; -}; - -/** - * Creates a pixi matrix object based on the array given as a parameter - * - * @method fromArray - * @param array {Array} The array that the matrix will be filled with - */ -PIXI.Matrix.prototype.fromArray = function(array) -{ - this.a = array[0]; - this.b = array[1]; - this.c = array[3]; - this.d = array[4]; - this.tx = array[2]; - this.ty = array[5]; -}; - -/** - * Creates an array from the current Matrix object - * - * @method toArray - * @param transpose {Boolean} Whether we need to transpose the matrix or not - * @return array {Array} the newly created array which contains the matrix - */ -PIXI.Matrix.prototype.toArray = function(transpose) -{ - if(!this.array) this.array = new Float32Array(9); - var array = this.array; - - if(transpose) - { - this.array[0] = this.a; - this.array[1] = this.c; - this.array[2] = 0; - this.array[3] = this.b; - this.array[4] = this.d; - this.array[5] = 0; - this.array[6] = this.tx; - this.array[7] = this.ty; - this.array[8] = 1; - } - else - { - this.array[0] = this.a; - this.array[1] = this.b; - this.array[2] = this.tx; - this.array[3] = this.c; - this.array[4] = this.d; - this.array[5] = this.ty; - this.array[6] = 0; - this.array[7] = 0; - this.array[8] = 1; - } - - return array;//[this.a, this.b, this.tx, this.c, this.d, this.ty, 0, 0, 1]; -}; - -PIXI.identityMatrix = new PIXI.Matrix(); -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The base class for all objects that are rendered on the screen. - * - * @class DisplayObject - * @constructor - */ -PIXI.DisplayObject = function() -{ - /** - * The coordinate of the object relative to the local coordinates of the parent. - * - * @property position - * @type Point - */ - this.position = new PIXI.Point(); - - /** - * The scale factor of the object. - * - * @property scale - * @type Point - */ - this.scale = new PIXI.Point(1,1);//{x:1, y:1}; - - /** - * The pivot point of the displayObject that it rotates around - * - * @property pivot - * @type Point - */ - this.pivot = new PIXI.Point(0,0); - - /** - * The rotation of the object in radians. - * - * @property rotation - * @type Number - */ - this.rotation = 0; - - /** - * The opacity of the object. - * - * @property alpha - * @type Number - */ - this.alpha = 1; - - /** - * The visibility of the object. - * - * @property visible - * @type Boolean - */ - this.visible = true; - - /** - * This is the defined area that will pick up mouse / touch events. It is null by default. - * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) - * - * @property hitArea - * @type Rectangle|Circle|Ellipse|Polygon - */ - this.hitArea = null; - - /** - * This is used to indicate if the displayObject should display a mouse hand cursor on rollover - * - * @property buttonMode - * @type Boolean - */ - this.buttonMode = false; - - /** - * Can this object be rendered - * - * @property renderable - * @type Boolean - */ - this.renderable = false; - - /** - * [read-only] The display object container that contains this display object. - * - * @property parent - * @type DisplayObjectContainer - * @readOnly - */ - this.parent = null; - - /** - * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. - * - * @property stage - * @type Stage - * @readOnly - */ - this.stage = null; - - /** - * [read-only] The multiplied alpha of the displayObject - * - * @property worldAlpha - * @type Number - * @readOnly - */ - this.worldAlpha = 1; - - /** - * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property - * - * @property _interactive - * @type Boolean - * @readOnly - * @private - */ - this._interactive = false; - - /** - * This is the cursor that will be used when the mouse is over this object. To enable this the element must have interaction = true and buttonMode = true - * - * @property defaultCursor - * @type String - * - */ - this.defaultCursor = 'pointer'; - - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Mat3 - * @readOnly - * @private - */ - this.worldTransform = new PIXI.Matrix(); - - /** - * [NYI] Unknown - * - * @property color - * @type Array<> - * @private - */ - this.color = []; - - /** - * [NYI] Holds whether or not this object is dynamic, for rendering optimization - * - * @property dynamic - * @type Boolean - * @private - */ - this.dynamic = true; - - // cached sin rotation and cos rotation - this._sr = 0; - this._cr = 1; - - /** - * The area the filter is applied to - * - * @property filterArea - * @type Rectangle - */ - this.filterArea = new PIXI.Rectangle(0,0,1,1); - - /** - * The original, cached bounds of the object - * - * @property _bounds - * @type Rectangle - * @private - */ - this._bounds = new PIXI.Rectangle(0, 0, 1, 1); - /** - * The most up-to-date bounds of the object - * - * @property _currentBounds - * @type Rectangle - * @private - */ - this._currentBounds = null; - /** - * The original, cached mask of the object - * - * @property _currentBounds - * @type Rectangle - * @private - */ - this._mask = null; - - /* - * MOUSE Callbacks - */ - - /** - * A callback that is used when the users clicks on the displayObject with their mouse - * @method click - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user clicks the mouse down over the sprite - * @method mousedown - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse that was over the displayObject - * for this callback to be fired the mouse must have been pressed down over the displayObject - * @method mouseup - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, The touch must have started over the displayObject - * @method mouseupoutside - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the users mouse rolls over the displayObject - * @method mouseover - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the users mouse leaves the displayObject - * @method mouseout - * @param interactionData {InteractionData} - */ - - - /* - * TOUCH Callbacks - */ - - /** - * A callback that is used when the users taps on the sprite with their finger - * basically a touch version of click - * @method tap - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user touches over the displayObject - * @method touchstart - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases a touch over the displayObject - * @method touchend - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the touch that was over the displayObject - * for this callback to be fired, The touch must have started over the sprite - * @method touchendoutside - * @param interactionData {InteractionData} - */ -}; - -// constructor -PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; - -/** - * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default - * Instead of using this function you can now simply set the interactive property to true or false - * - * @method setInteractive - * @param interactive {Boolean} - * @deprecated Simply set the `interactive` property directly - */ -PIXI.DisplayObject.prototype.setInteractive = function(interactive) -{ - this.interactive = interactive; -}; - -/** - * Indicates if the sprite will have touch and mouse interactivity. It is false by default - * - * @property interactive - * @type Boolean - * @default false - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', { - get: function() { - return this._interactive; - }, - set: function(value) { - this._interactive = value; - - // TODO more to be done here.. - // need to sort out a re-crawl! - if(this.stage)this.stage.dirty = true; - } -}); - -/** - * [read-only] Indicates if the sprite is globaly visible. - * - * @property worldVisible - * @type Boolean - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'worldVisible', { - get: function() { - var item = this; - - do - { - if(!item.visible)return false; - item = item.parent; - } - while(item); - - return true; - } -}); - -/** - * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it. - * In PIXI a regular mask must be a PIXI.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping. - * To remove a mask, set this property to null. - * - * @property mask - * @type Graphics - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { - get: function() { - return this._mask; - }, - set: function(value) { - - if(this._mask)this._mask.isMask = false; - this._mask = value; - if(this._mask)this._mask.isMask = true; - } -}); - -/** - * Sets the filters for the displayObject. - * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. - * To remove filters simply set this property to 'null' - * @property filters - * @type Array An array of filters - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { - get: function() { - return this._filters; - }, - set: function(value) { - - if(value) - { - // now put all the passes in one place.. - var passes = []; - for (var i = 0; i < value.length; i++) - { - var filterPasses = value[i].passes; - for (var j = 0; j < filterPasses.length; j++) - { - passes.push(filterPasses[j]); - } - } - - // TODO change this as it is legacy - this._filterBlock = {target:this, filterPasses:passes}; - } - - this._filters = value; - } -}); - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.DisplayObject.prototype.updateTransform = function() -{ - // TODO OPTIMIZE THIS!! with dirty - if(this.rotation !== this.rotationCache) - { - - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } - - // var localTransform = this.localTransform//.toArray(); - var parentTransform = this.parent.worldTransform;//.toArray(); - var worldTransform = this.worldTransform;//.toArray(); - var px = this.pivot.x; - var py = this.pivot.y; - - var a00 = this._cr * this.scale.x, - a01 = -this._sr * this.scale.y, - a10 = this._sr * this.scale.x, - a11 = this._cr * this.scale.y, - a02 = this.position.x - a00 * px - py * a01, - a12 = this.position.y - a11 * py - px * a10, - b00 = parentTransform.a, b01 = parentTransform.b, - b10 = parentTransform.c, b11 = parentTransform.d; - - worldTransform.a = b00 * a00 + b01 * a10; - worldTransform.b = b00 * a01 + b01 * a11; - worldTransform.tx = b00 * a02 + b01 * a12 + parentTransform.tx; - - worldTransform.c = b10 * a00 + b11 * a10; - worldTransform.d = b10 * a01 + b11 * a11; - worldTransform.ty = b10 * a02 + b11 * a12 + parentTransform.ty; - - this.worldAlpha = this.alpha * this.parent.worldAlpha; -}; - -/** - * Retrieves the bounds of the displayObject as a rectangle object - * - * @method getBounds - * @return {Rectangle} the rectangular bounding area - */ -PIXI.DisplayObject.prototype.getBounds = function( matrix ) -{ - matrix = matrix;//just to get passed js hinting (and preserve inheritance) - return PIXI.EmptyRectangle; -}; - -/** - * Retrieves the local bounds of the displayObject as a rectangle object - * - * @method getLocalBounds - * @return {Rectangle} the rectangular bounding area - */ -PIXI.DisplayObject.prototype.getLocalBounds = function() -{ - //var matrixCache = this.worldTransform; - - return this.getBounds(PIXI.identityMatrix);///PIXI.EmptyRectangle(); -}; - -/** - * Sets the object's stage reference, the stage this object is connected to - * - * @method setStageReference - * @param stage {Stage} the stage that the object will have as its current stage reference - */ -PIXI.DisplayObject.prototype.setStageReference = function(stage) -{ - this.stage = stage; - if(this._interactive)this.stage.dirty = true; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.DisplayObject.prototype._renderWebGL = function(renderSession) -{ - // OVERWRITE; - // this line is just here to pass jshinting :) - renderSession = renderSession; -}; - -/** -* Renders the object using the Canvas renderer -* -* @method _renderCanvas -* @param renderSession {RenderSession} -* @private -*/ -PIXI.DisplayObject.prototype._renderCanvas = function(renderSession) -{ - // OVERWRITE; - // this line is just here to pass jshinting :) - renderSession = renderSession; -}; - -/** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @property x - * @type Number - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'x', { - get: function() { - return this.position.x; - }, - set: function(value) { - this.position.x = value; - } -}); - -/** - * The position of the displayObject on the y axis relative to the local coordinates of the parent. - * - * @property y - * @type Number - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'y', { - get: function() { - return this.position.y; - }, - set: function(value) { - this.position.y = value; - } -}); - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * A DisplayObjectContainer represents a collection of display objects. - * It is the base class of all display objects that act as a container for other objects. - * - * @class DisplayObjectContainer - * @extends DisplayObject - * @constructor - */ -PIXI.DisplayObjectContainer = function() -{ - PIXI.DisplayObject.call( this ); - - /** - * [read-only] The array of children of this container. - * - * @property children - * @type Array - * @readOnly - */ - this.children = []; -}; - -// constructor -PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); -PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; - -/** - * The width of the displayObjectContainer, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ - - /* -Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', { - get: function() { - return this.scale.x * this.getLocalBounds().width; - }, - set: function(value) { - this.scale.x = value / (this.getLocalBounds().width/this.scale.x); - this._width = value; - } -}); -*/ - -/** - * The height of the displayObjectContainer, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ - -/* -Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'height', { - get: function() { - return this.scale.y * this.getLocalBounds().height; - }, - set: function(value) { - this.scale.y = value / (this.getLocalBounds().height/this.scale.y); - this._height = value; - } -}); -*/ - -/** - * Adds a child to the container. - * - * @method addChild - * @param child {DisplayObject} The DisplayObject to add to the container - */ -PIXI.DisplayObjectContainer.prototype.addChild = function(child) -{ - this.addChildAt(child, this.children.length); -}; - -/** - * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown - * - * @method addChildAt - * @param child {DisplayObject} The child to add - * @param index {Number} The index to place the child in - */ -PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) -{ - if(index >= 0 && index <= this.children.length) - { - if(child.parent) - { - child.parent.removeChild(child); - } - - child.parent = this; - - this.children.splice(index, 0, child); - - if(this.stage)child.setStageReference(this.stage); - } - else - { - throw new Error(child + ' The index '+ index +' supplied is out of bounds ' + this.children.length); - } -}; - -/** - * [NYI] Swaps the depth of 2 displayObjects - * - * @method swapChildren - * @param child {DisplayObject} - * @param child2 {DisplayObject} - * @private - */ -PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) -{ - if(child === child2) { - return; - } - - var index1 = this.children.indexOf(child); - var index2 = this.children.indexOf(child2); - - if(index1 < 0 || index2 < 0) { - throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.'); - } - - this.children[index1] = child2; - this.children[index2] = child; - -}; - -/** - * Returns the child at the specified index - * - * @method getChildAt - * @param index {Number} The index to get the child from - */ -PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) -{ - if(index >= 0 && index < this.children.length) - { - return this.children[index]; - } - else - { - throw new Error('The supplied DisplayObjects must be a child of the caller ' + this); - } -}; - -/** - * Removes a child from the container. - * - * @method removeChild - * @param child {DisplayObject} The DisplayObject to remove - */ -PIXI.DisplayObjectContainer.prototype.removeChild = function(child) -{ - var index = this.children.indexOf( child ); - if ( index !== -1 ) - { - // update the stage reference.. - if(this.stage)child.removeStageReference(); - - child.parent = undefined; - this.children.splice( index, 1 ); - } - else - { - throw new Error(child + ' The supplied DisplayObject must be a child of the caller ' + this); - } -}; - - -/** -* Removes all the children -* -* @method removeAll -* NOT tested yet -*/ -/* PIXI.DisplayObjectContainer.prototype.removeAll = function() -{ - - - for(var i = 0 , j = this.children.length; i < j; i++) - { - this.removeChild(this.children[i]); - } - -}; -*/ -/* - * Updates the container's childrens transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.DisplayObjectContainer.prototype.updateTransform = function() -{ - //this._currentBounds = null; - - if(!this.visible)return; - - PIXI.DisplayObject.prototype.updateTransform.call( this ); - - for(var i=0,j=this.children.length; i childMaxX ? maxX : childMaxX; - maxY = maxY > childMaxY ? maxY : childMaxY; - } - - if(!childVisible) - return PIXI.EmptyRectangle; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.y = minY; - bounds.width = maxX - minX; - bounds.height = maxY - minY; - - // TODO: store a reference so that if this function gets called again in the render cycle we do not have to recalculate - //this._currentBounds = bounds; - - return bounds; -}; - -PIXI.DisplayObjectContainer.prototype.getLocalBounds = function() -{ - var matrixCache = this.worldTransform; - - this.worldTransform = PIXI.identityMatrix; - - for(var i=0,j=this.children.length; i maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Sprite.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(!this.visible || this.alpha <= 0)return; - - var i,j; - - // do a quick check to see if this element has a mask or a filter. - if(this._mask || this._filters) - { - var spriteBatch = renderSession.spriteBatch; - - if(this._mask) - { - spriteBatch.stop(); - renderSession.maskManager.pushMask(this.mask, renderSession); - spriteBatch.start(); - } - - if(this._filters) - { - spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - - // add this sprite to the batch - spriteBatch.render(this); - - // now loop through the children and make sure they get rendered - for(i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation - */ -PIXI.MovieClip = function(textures) -{ - PIXI.Sprite.call(this, textures[0]); - - /** - * The array of textures that make up the animation - * - * @property textures - * @type Array - */ - this.textures = textures; - - /** - * The speed that the MovieClip will play at. Higher is faster, lower is slower - * - * @property animationSpeed - * @type Number - * @default 1 - */ - this.animationSpeed = 1; - - /** - * Whether or not the movie clip repeats after playing. - * - * @property loop - * @type Boolean - * @default true - */ - this.loop = true; - - /** - * Function to call when a MovieClip finishes playing - * - * @property onComplete - * @type Function - */ - this.onComplete = null; - - /** - * [read-only] The MovieClips current frame index (this may not have to be a whole number) - * - * @property currentFrame - * @type Number - * @default 0 - * @readOnly - */ - this.currentFrame = 0; - - /** - * [read-only] Indicates if the MovieClip is currently playing - * - * @property playing - * @type Boolean - * @readOnly - */ - this.playing = false; -}; - -// constructor -PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype ); -PIXI.MovieClip.prototype.constructor = PIXI.MovieClip; - -/** -* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures -* assigned to the MovieClip. -* -* @property totalFrames -* @type Number -* @default 0 -* @readOnly -*/ -Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', { - get: function() { - - return this.textures.length; - } -}); - - -/** - * Stops the MovieClip - * - * @method stop - */ -PIXI.MovieClip.prototype.stop = function() -{ - this.playing = false; -}; - -/** - * Plays the MovieClip - * - * @method play - */ -PIXI.MovieClip.prototype.play = function() -{ - this.playing = true; -}; - -/** - * Stops the MovieClip and goes to a specific frame - * - * @method gotoAndStop - * @param frameNumber {Number} frame index to stop at - */ -PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber) -{ - this.playing = false; - this.currentFrame = frameNumber; - var round = (this.currentFrame + 0.5) | 0; - this.setTexture(this.textures[round % this.textures.length]); -}; - -/** - * Goes to a specific frame and begins playing the MovieClip - * - * @method gotoAndPlay - * @param frameNumber {Number} frame index to start at - */ -PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber) -{ - this.currentFrame = frameNumber; - this.playing = true; -}; - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.MovieClip.prototype.updateTransform = function() -{ - PIXI.Sprite.prototype.updateTransform.call(this); - - if(!this.playing)return; - - this.currentFrame += this.animationSpeed; - - var round = (this.currentFrame + 0.5) | 0; - - if(this.loop || round < this.textures.length) - { - this.setTexture(this.textures[round % this.textures.length]); - } - else if(round >= this.textures.length) - { - this.gotoAndStop(this.textures.length - 1); - if(this.onComplete) - { - this.onComplete(); - } - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -PIXI.FilterBlock = function() -{ - this.visible = true; - this.renderable = true; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Text Object will create a line(s) of text. To split a line you can use '\n' - * or add a wordWrap property set to true and and wordWrapWidth property with a value - * in the style object - * - * @class Text - * @extends Sprite - * @constructor - * @param text {String} The copy that you would like the text to display - * @param [style] {Object} The style parameters - * @param [style.font] {String} default 'bold 20px Arial' The style and size of the font - * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap, it needs wordWrap to be set to true - */ -PIXI.Text = function(text, style) -{ - /** - * The canvas element that everything is drawn to - * - * @property canvas - * @type HTMLCanvasElement - */ - this.canvas = document.createElement('canvas'); - - /** - * The canvas 2d context that everything is drawn with - * @property context - * @type HTMLCanvasElement 2d Context - */ - this.context = this.canvas.getContext('2d'); - - PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas)); - - this.setText(text); - this.setStyle(style); - - this.updateText(); - this.dirty = false; -}; - -// constructor -PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype); -PIXI.Text.prototype.constructor = PIXI.Text; - -/** - * Set the style of the text - * - * @method setStyle - * @param [style] {Object} The style parameters - * @param [style.font='bold 20pt Arial'] {String} The style and size of the font - * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke='black'] {String} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap - */ -PIXI.Text.prototype.setStyle = function(style) -{ - style = style || {}; - style.font = style.font || 'bold 20pt Arial'; - style.fill = style.fill || 'black'; - style.align = style.align || 'left'; - style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/GoodBoyDigital/pixi.js/issues/136 - style.strokeThickness = style.strokeThickness || 0; - style.wordWrap = style.wordWrap || false; - style.wordWrapWidth = style.wordWrapWidth || 100; - this.style = style; - this.dirty = true; -}; - -/** - * Set the copy for the text object. To split a line you can use '\n' - * - * @method setText - * @param {String} text The copy that you would like the text to display - */ -PIXI.Text.prototype.setText = function(text) -{ - this.text = text.toString() || ' '; - this.dirty = true; - -}; - -/** - * Renders text and updates it when needed - * - * @method updateText - * @private - */ -PIXI.Text.prototype.updateText = function() -{ - this.context.font = this.style.font; - - var outputText = this.text; - - // word wrap - // preserve original text - if(this.style.wordWrap)outputText = this.wordWrap(this.text); - - //split text into lines - var lines = outputText.split(/(?:\r\n|\r|\n)/); - - //calculate text width - var lineWidths = []; - var maxLineWidth = 0; - for (var i = 0; i < lines.length; i++) - { - var lineWidth = this.context.measureText(lines[i]).width; - lineWidths[i] = lineWidth; - maxLineWidth = Math.max(maxLineWidth, lineWidth); - } - this.canvas.width = maxLineWidth + this.style.strokeThickness; - - //calculate text height - var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness; - this.canvas.height = lineHeight * lines.length; - - if(navigator.isCocoonJS) this.context.clearRect(0,0,this.canvas.width,this.canvas.height); - - //set canvas text styles - this.context.fillStyle = this.style.fill; - this.context.font = this.style.font; - - this.context.strokeStyle = this.style.stroke; - this.context.lineWidth = this.style.strokeThickness; - - this.context.textBaseline = 'top'; - - //draw lines line by line - for (i = 0; i < lines.length; i++) - { - var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); - - if(this.style.align === 'right') - { - linePosition.x += maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - linePosition.x += (maxLineWidth - lineWidths[i]) / 2; - } - - if(this.style.stroke && this.style.strokeThickness) - { - this.context.strokeText(lines[i], linePosition.x, linePosition.y); - } - - if(this.style.fill) - { - this.context.fillText(lines[i], linePosition.x, linePosition.y); - } - } - - this.updateTexture(); -}; - -/** - * Updates texture size based on canvas size - * - * @method updateTexture - * @private - */ -PIXI.Text.prototype.updateTexture = function() -{ - this.texture.baseTexture.width = this.canvas.width; - this.texture.baseTexture.height = this.canvas.height; - this.texture.frame.width = this.canvas.width; - this.texture.frame.height = this.canvas.height; - - this._width = this.canvas.width; - this._height = this.canvas.height; - - this.requiresUpdate = true; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Text.prototype._renderWebGL = function(renderSession) -{ - if(this.requiresUpdate) - { - this.requiresUpdate = false; - PIXI.updateWebGLTexture(this.texture.baseTexture, renderSession.gl); - } - - PIXI.Sprite.prototype._renderWebGL.call(this, renderSession); -}; - -/** - * Updates the transform of this object - * - * @method updateTransform - * @private - */ -PIXI.Text.prototype.updateTransform = function() -{ - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - PIXI.Sprite.prototype.updateTransform.call(this); -}; - -/* - * http://stackoverflow.com/users/34441/ellisbben - * great solution to the problem! - * returns the height of the given font - * - * @method determineFontHeight - * @param fontStyle {Object} - * @private - */ -PIXI.Text.prototype.determineFontHeight = function(fontStyle) -{ - // build a little reference dictionary so if the font style has been used return a - // cached version... - var result = PIXI.Text.heightCache[fontStyle]; - - if(!result) - { - var body = document.getElementsByTagName('body')[0]; - var dummy = document.createElement('div'); - var dummyText = document.createTextNode('M'); - dummy.appendChild(dummyText); - dummy.setAttribute('style', fontStyle + ';position:absolute;top:0;left:0'); - body.appendChild(dummy); - - result = dummy.offsetHeight; - PIXI.Text.heightCache[fontStyle] = result; - - body.removeChild(dummy); - } - - return result; -}; - -/** - * Applies newlines to a string to have it optimally fit into the horizontal - * bounds set by the Text object's wordWrapWidth property. - * - * @method wordWrap - * @param text {String} - * @private - */ -PIXI.Text.prototype.wordWrap = function(text) -{ - // Greedy wrapping algorithm that will wrap words as the line grows longer - // than its horizontal bounds. - var result = ''; - var lines = text.split('\n'); - for (var i = 0; i < lines.length; i++) - { - var spaceLeft = this.style.wordWrapWidth; - var words = lines[i].split(' '); - for (var j = 0; j < words.length; j++) - { - var wordWidth = this.context.measureText(words[j]).width; - var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; - if(wordWidthWithSpace > spaceLeft) - { - // Skip printing the newline if it's the first word of the line that is - // greater than the word wrap width. - if(j > 0) - { - result += '\n'; - } - result += words[j] + ' '; - spaceLeft = this.style.wordWrapWidth - wordWidth; - } - else - { - spaceLeft -= wordWidthWithSpace; - result += words[j] + ' '; - } - } - - if (i < lines.length-1) - { - result += '\n'; - } - } - return result; -}; - -/** - * Destroys this text object - * - * @method destroy - * @param destroyTexture {Boolean} - */ -PIXI.Text.prototype.destroy = function(destroyTexture) -{ - if(destroyTexture) - { - this.texture.destroy(); - } - -}; - -PIXI.Text.heightCache = {}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Text Object will create a line(s) of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' - * You can generate the fnt files using - * http://www.angelcode.com/products/bmfont/ for windows or - * http://www.bmglyph.com/ for mac. - * - * @class BitmapText - * @extends DisplayObjectContainer - * @constructor - * @param text {String} The copy that you would like the text to display - * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - */ -PIXI.BitmapText = function(text, style) -{ - PIXI.DisplayObjectContainer.call(this); - - this._pool = []; - - this.setText(text); - this.setStyle(style); - this.updateText(); - this.dirty = false; -}; - -// constructor -PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); -PIXI.BitmapText.prototype.constructor = PIXI.BitmapText; - -/** - * Set the copy for the text object - * - * @method setText - * @param text {String} The copy that you would like the text to display - */ -PIXI.BitmapText.prototype.setText = function(text) -{ - this.text = text || ' '; - this.dirty = true; -}; - -/** - * Set the style of the text - * style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) - * [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * - * @method setStyle - * @param style {Object} The style parameters, contained as properties of an object - */ -PIXI.BitmapText.prototype.setStyle = function(style) -{ - style = style || {}; - style.align = style.align || 'left'; - this.style = style; - - var font = style.font.split(' '); - this.fontName = font[font.length - 1]; - this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size; - - this.dirty = true; - this.tint = style.tint; -}; - -/** - * Renders text and updates it when needed - * - * @method updateText - * @private - */ -PIXI.BitmapText.prototype.updateText = function() -{ - var data = PIXI.BitmapText.fonts[this.fontName]; - var pos = new PIXI.Point(); - var prevCharCode = null; - var chars = []; - var maxLineWidth = 0; - var lineWidths = []; - var line = 0; - var scale = this.fontSize / data.size; - - - for(var i = 0; i < this.text.length; i++) - { - var charCode = this.text.charCodeAt(i); - if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i))) - { - lineWidths.push(pos.x); - maxLineWidth = Math.max(maxLineWidth, pos.x); - line++; - - pos.x = 0; - pos.y += data.lineHeight; - prevCharCode = null; - continue; - } - - var charData = data.chars[charCode]; - if(!charData) continue; - - if(prevCharCode && charData[prevCharCode]) - { - pos.x += charData.kerning[prevCharCode]; - } - chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)}); - pos.x += charData.xAdvance; - - prevCharCode = charCode; - } - - lineWidths.push(pos.x); - maxLineWidth = Math.max(maxLineWidth, pos.x); - - var lineAlignOffsets = []; - for(i = 0; i <= line; i++) - { - var alignOffset = 0; - if(this.style.align === 'right') - { - alignOffset = maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - alignOffset = (maxLineWidth - lineWidths[i]) / 2; - } - lineAlignOffsets.push(alignOffset); - } - - var lenChildren = this.children.length; - var lenChars = chars.length; - var tint = this.tint || 0xFFFFFF; - for(i = 0; i < lenChars; i++) - { - var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool. - - if (c) c.setTexture(chars[i].texture); // check if got one before. - else c = new PIXI.Sprite(chars[i].texture); // if no create new one. - - c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale; - c.position.y = chars[i].position.y * scale; - c.scale.x = c.scale.y = scale; - c.tint = tint; - if (!c.parent) this.addChild(c); - } - - // remove unnecessary children. - // and put their into the pool. - while(this.children.length > lenChars) - { - var child = this.getChildAt(this.children.length - 1); - this._pool.push(child); - this.removeChild(child); - } - - - /** - * [read-only] The width of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textWidth - * @type Number - */ - this.textWidth = maxLineWidth * scale; - - /** - * [read-only] The height of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textHeight - * @type Number - */ - this.textHeight = (pos.y + data.lineHeight) * scale; -}; - -/** - * Updates the transform of this object - * - * @method updateTransform - * @private - */ -PIXI.BitmapText.prototype.updateTransform = function() -{ - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); -}; - -PIXI.BitmapText.fonts = {}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * Holds all information related to an Interaction event - * - * @class InteractionData - * @constructor - */ -PIXI.InteractionData = function() -{ - /** - * This point stores the global coords of where the touch/mouse event happened - * - * @property global - * @type Point - */ - this.global = new PIXI.Point(); - - // this is here for legacy... but will remove - this.local = new PIXI.Point(); - - /** - * The target Sprite that was interacted with - * - * @property target - * @type Sprite - */ - this.target = null; - - /** - * When passed to an event handler, this will be the original DOM Event that was captured - * - * @property originalEvent - * @type Event - */ - this.originalEvent = null; -}; - -/** - * This will return the local coordinates of the specified displayObject for this InteractionData - * - * @method getLocalPosition - * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off - * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject - */ -PIXI.InteractionData.prototype.getLocalPosition = function(displayObject) -{ - var worldTransform = displayObject.worldTransform; - var global = this.global; - - // do a cheeky transform to get the mouse coords; - var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx, - a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty, - id = 1 / (a00 * a11 + a01 * -a10); - // set the mouse coords... - return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, - a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id); -}; - -// constructor -PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - /** - * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive - * if its interactive parameter is set to true - * This manager also supports multitouch. - * - * @class InteractionManager - * @constructor - * @param stage {Stage} The stage to handle interactions - */ -PIXI.InteractionManager = function(stage) -{ - /** - * a reference to the stage - * - * @property stage - * @type Stage - */ - this.stage = stage; - - /** - * the mouse data - * - * @property mouse - * @type InteractionData - */ - this.mouse = new PIXI.InteractionData(); - - /** - * an object that stores current touches (InteractionData) by id reference - * - * @property touchs - * @type Object - */ - this.touchs = {}; - - // helpers - this.tempPoint = new PIXI.Point(); - - /** - * - * @property mouseoverEnabled - * @type Boolean - * @default - */ - this.mouseoverEnabled = true; - - /** - * tiny little interactiveData pool ! - * - * @property pool - * @type Array - */ - this.pool = []; - - /** - * An array containing all the iterative items from the our interactive tree - * @property interactiveItems - * @type Array - * @private - * - */ - this.interactiveItems = []; - - /** - * Our canvas - * @property interactionDOMElement - * @type HTMLCanvasElement - * @private - */ - this.interactionDOMElement = null; - - //this will make it so that you dont have to call bind all the time - this.onMouseMove = this.onMouseMove.bind( this ); - this.onMouseDown = this.onMouseDown.bind(this); - this.onMouseOut = this.onMouseOut.bind(this); - this.onMouseUp = this.onMouseUp.bind(this); - - this.onTouchStart = this.onTouchStart.bind(this); - this.onTouchEnd = this.onTouchEnd.bind(this); - this.onTouchMove = this.onTouchMove.bind(this); - - this.last = 0; - - /** - * The css style of the cursor that is being used - * @property currentCursorStyle - * @type String - * - */ - this.currentCursorStyle = 'inherit'; - - /** - * Is set to true when the mouse is moved out of the canvas - * @property mouseOut - * @type Boolean - * - */ - this.mouseOut = false; -}; - -// constructor -PIXI.InteractionManager.prototype.constructor = PIXI.InteractionManager; - -/** - * Collects an interactive sprite recursively to have their interactions managed - * - * @method collectInteractiveSprite - * @param displayObject {DisplayObject} the displayObject to collect - * @param iParent {DisplayObject} the display object's parent - * @private - */ -PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObject, iParent) -{ - var children = displayObject.children; - var length = children.length; - - // make an interaction tree... {item.__interactiveParent} - for (var i = length-1; i >= 0; i--) - { - var child = children[i]; - - // push all interactive bits - if(child.interactive) - { - iParent.interactiveChildren = true; - //child.__iParent = iParent; - this.interactiveItems.push(child); - - if(child.children.length > 0) - { - this.collectInteractiveSprite(child, child); - } - } - else - { - child.__iParent = null; - - if(child.children.length > 0) - { - this.collectInteractiveSprite(child, iParent); - } - } - - } -}; - -/** - * Sets the target for event delegation - * - * @method setTarget - * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to - * @private - */ -PIXI.InteractionManager.prototype.setTarget = function(target) -{ - this.target = target; - - //check if the dom element has been set. If it has don't do anything - if( this.interactionDOMElement === null ) { - - this.setTargetDomElement( target.view ); - } - - -}; - - -/** - * Sets the DOM element which will receive mouse/touch events. This is useful for when you have other DOM - * elements on top of the renderers Canvas element. With this you'll be able to delegate another DOM element - * to receive those events - * - * @method setTargetDomElement - * @param domElement {DOMElement} the DOM element which will receive mouse and touch events - * @private - */ -PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) -{ - - this.removeEvents(); - - - if (window.navigator.msPointerEnabled) - { - // time to remove some of that zoom in ja.. - domElement.style['-ms-content-zooming'] = 'none'; - domElement.style['-ms-touch-action'] = 'none'; - - // DO some window specific touch! - } - - this.interactionDOMElement = domElement; - - domElement.addEventListener('mousemove', this.onMouseMove, true); - domElement.addEventListener('mousedown', this.onMouseDown, true); - domElement.addEventListener('mouseout', this.onMouseOut, true); - - // aint no multi touch just yet! - domElement.addEventListener('touchstart', this.onTouchStart, true); - domElement.addEventListener('touchend', this.onTouchEnd, true); - domElement.addEventListener('touchmove', this.onTouchMove, true); - - document.body.addEventListener('mouseup', this.onMouseUp, true); -}; - - -PIXI.InteractionManager.prototype.removeEvents = function() -{ - if(!this.interactionDOMElement)return; - - this.interactionDOMElement.style['-ms-content-zooming'] = ''; - this.interactionDOMElement.style['-ms-touch-action'] = ''; - - this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true); - this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true); - this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true); - - // aint no multi touch just yet! - this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true); - this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true); - this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true); - - this.interactionDOMElement = null; - - document.body.removeEventListener('mouseup', this.onMouseUp, true); -}; - -/** - * updates the state of interactive objects - * - * @method update - * @private - */ -PIXI.InteractionManager.prototype.update = function() -{ - if(!this.target)return; - - // frequency of 30fps?? - var now = Date.now(); - var diff = now - this.last; - diff = (diff * PIXI.INTERACTION_FREQUENCY ) / 1000; - if(diff < 1)return; - this.last = now; - - var i = 0; - - // ok.. so mouse events?? - // yes for now :) - // OPTIMISE - how often to check?? - if(this.dirty) - { - this.dirty = false; - - var len = this.interactiveItems.length; - - for (i = 0; i < len; i++) { - this.interactiveItems[i].interactiveChildren = false; - } - - this.interactiveItems = []; - - if(this.stage.interactive)this.interactiveItems.push(this.stage); - // go through and collect all the objects that are interactive.. - this.collectInteractiveSprite(this.stage, this.stage); - } - - // loop through interactive objects! - var length = this.interactiveItems.length; - var cursor = 'inherit'; - var over = false; - - for (i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - // OPTIMISATION - only calculate every time if the mousemove function exists.. - // OK so.. does the object have any other interactive functions? - // hit-test the clip! - // if(item.mouseover || item.mouseout || item.buttonMode) - // { - // ok so there are some functions so lets hit test it.. - item.__hit = this.hitTest(item, this.mouse); - this.mouse.target = item; - // ok so deal with interactions.. - // looks like there was a hit! - if(item.__hit && !over) - { - if(item.buttonMode) cursor = item.defaultCursor; - - if(!item.interactiveChildren)over = true; - - if(!item.__isOver) - { - if(item.mouseover)item.mouseover(this.mouse); - item.__isOver = true; - } - } - else - { - if(item.__isOver) - { - // roll out! - if(item.mouseout)item.mouseout(this.mouse); - item.__isOver = false; - } - } - } - - if( this.currentCursorStyle !== cursor ) - { - this.currentCursorStyle = cursor; - this.interactionDOMElement.style.cursor = cursor; - } -}; - -/** - * Is called when the mouse moves across the renderer element - * - * @method onMouseMove - * @param event {Event} The DOM event of the mouse moving - * @private - */ -PIXI.InteractionManager.prototype.onMouseMove = function(event) -{ - this.mouse.originalEvent = event || window.event; //IE uses window.event - // TODO optimize by not check EVERY TIME! maybe half as often? // - var rect = this.interactionDOMElement.getBoundingClientRect(); - - this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); - this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); - - var length = this.interactiveItems.length; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.mousemove) - { - //call the function! - item.mousemove(this.mouse); - } - } -}; - -/** - * Is called when the mouse button is pressed down on the renderer element - * - * @method onMouseDown - * @param event {Event} The DOM event of a mouse button being pressed down - * @private - */ -PIXI.InteractionManager.prototype.onMouseDown = function(event) -{ - this.mouse.originalEvent = event || window.event; //IE uses window.event - - if(PIXI.AUTO_PREVENT_DEFAULT)this.mouse.originalEvent.preventDefault(); - - // loop through interaction tree... - // hit test each item! -> - // get interactive items under point?? - //stage.__i - var length = this.interactiveItems.length; - - // while - // hit test - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.mousedown || item.click) - { - item.__mouseIsDown = true; - item.__hit = this.hitTest(item, this.mouse); - - if(item.__hit) - { - //call the function! - if(item.mousedown)item.mousedown(this.mouse); - item.__isDown = true; - - // just the one! - if(!item.interactiveChildren)break; - } - } - } -}; - -/** - * Is called when the mouse button is moved out of the renderer element - * - * @method onMouseOut - * @param event {Event} The DOM event of a mouse button being moved out - * @private - */ -PIXI.InteractionManager.prototype.onMouseOut = function() -{ - var length = this.interactiveItems.length; - - this.interactionDOMElement.style.cursor = 'inherit'; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - if(item.__isOver) - { - this.mouse.target = item; - if(item.mouseout)item.mouseout(this.mouse); - item.__isOver = false; - } - } - - this.mouseOut = true; - - // move the mouse to an impossible position - this.mouse.global.x = -10000; - this.mouse.global.y = -10000; -}; - -/** - * Is called when the mouse button is released on the renderer element - * - * @method onMouseUp - * @param event {Event} The DOM event of a mouse button being released - * @private - */ -PIXI.InteractionManager.prototype.onMouseUp = function(event) -{ - - this.mouse.originalEvent = event || window.event; //IE uses window.event - - var length = this.interactiveItems.length; - var up = false; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - item.__hit = this.hitTest(item, this.mouse); - - if(item.__hit && !up) - { - //call the function! - if(item.mouseup) - { - item.mouseup(this.mouse); - } - if(item.__isDown) - { - if(item.click)item.click(this.mouse); - } - - if(!item.interactiveChildren)up = true; - } - else - { - if(item.__isDown) - { - if(item.mouseupoutside)item.mouseupoutside(this.mouse); - } - } - - item.__isDown = false; - //} - } -}; - -/** - * Tests if the current mouse coordinates hit a sprite - * - * @method hitTest - * @param item {DisplayObject} The displayObject to test for a hit - * @param interactionData {InteractionData} The interactionData object to update in the case there is a hit - * @private - */ -PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) -{ - var global = interactionData.global; - - if( !item.worldVisible )return false; - - // temp fix for if the element is in a non visible - - var isSprite = (item instanceof PIXI.Sprite), - worldTransform = item.worldTransform, - a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx, - a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty, - id = 1 / (a00 * a11 + a01 * -a10), - x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, - y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - - interactionData.target = item; - - //a sprite or display object with a hit area defined - if(item.hitArea && item.hitArea.contains) { - if(item.hitArea.contains(x, y)) { - //if(isSprite) - interactionData.target = item; - - return true; - } - - return false; - } - // a sprite with no hitarea defined - else if(isSprite) - { - var width = item.texture.frame.width, - height = item.texture.frame.height, - x1 = -width * item.anchor.x, - y1; - - if(x > x1 && x < x1 + width) - { - y1 = -height * item.anchor.y; - - if(y > y1 && y < y1 + height) - { - // set the target property if a hit is true! - interactionData.target = item; - return true; - } - } - } - - var length = item.children.length; - - for (var i = 0; i < length; i++) - { - var tempItem = item.children[i]; - var hit = this.hitTest(tempItem, interactionData); - if(hit) - { - // hmm.. TODO SET CORRECT TARGET? - interactionData.target = item; - return true; - } - } - - return false; -}; - -/** - * Is called when a touch is moved across the renderer element - * - * @method onTouchMove - * @param event {Event} The DOM event of a touch moving across the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchMove = function(event) -{ - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - var touchData; - var i = 0; - - for (i = 0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - touchData = this.touchs[touchEvent.identifier]; - touchData.originalEvent = event || window.event; - - // update the touch position - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - if(navigator.isCocoonJS) { - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - } - - var length = this.interactiveItems.length; - for (i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - if(item.touchmove) - item.touchmove(touchData); - } -}; - -/** - * Is called when a touch is started on the renderer element - * - * @method onTouchStart - * @param event {Event} The DOM event of a touch starting on the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchStart = function(event) -{ - var rect = this.interactionDOMElement.getBoundingClientRect(); - - if(PIXI.AUTO_PREVENT_DEFAULT)event.preventDefault(); - - var changedTouches = event.changedTouches; - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - - var touchData = this.pool.pop(); - if(!touchData)touchData = new PIXI.InteractionData(); - - touchData.originalEvent = event || window.event; - - this.touchs[touchEvent.identifier] = touchData; - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - if(navigator.isCocoonJS) { - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - - var length = this.interactiveItems.length; - - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - - if(item.touchstart || item.tap) - { - item.__hit = this.hitTest(item, touchData); - - if(item.__hit) - { - //call the function! - if(item.touchstart)item.touchstart(touchData); - item.__isDown = true; - item.__touchData = touchData; - - if(!item.interactiveChildren)break; - } - } - } - } -}; - -/** - * Is called when a touch is ended on the renderer element - * - * @method onTouchEnd - * @param event {Event} The DOM event of a touch ending on the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchEnd = function(event) -{ - //this.mouse.originalEvent = event || window.event; //IE uses window.event - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - var touchData = this.touchs[touchEvent.identifier]; - var up = false; - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - if(navigator.isCocoonJS) { - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - - var length = this.interactiveItems.length; - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - var itemTouchData = item.__touchData; // <-- Here! - item.__hit = this.hitTest(item, touchData); - - if(itemTouchData === touchData) - { - // so this one WAS down... - touchData.originalEvent = event || window.event; - // hitTest?? - - if(item.touchend || item.tap) - { - if(item.__hit && !up) - { - if(item.touchend)item.touchend(touchData); - if(item.__isDown) - { - if(item.tap)item.tap(touchData); - } - - if(!item.interactiveChildren)up = true; - } - else - { - if(item.__isDown) - { - if(item.touchendoutside)item.touchendoutside(touchData); - } - } - - item.__isDown = false; - } - - item.__touchData = null; - - } - /* - else - { - - } - */ - } - // remove the touch.. - this.pool.push(touchData); - this.touchs[touchEvent.identifier] = null; - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Stage represents the root of the display tree. Everything connected to the stage is rendered - * - * @class Stage - * @extends DisplayObjectContainer - * @constructor - * @param backgroundColor {Number} the background color of the stage, you have to pass this in is in hex format - * like: 0xFFFFFF for white - * - * Creating a stage is a mandatory process when you use Pixi, which is as simple as this : - * var stage = new PIXI.Stage(0xFFFFFF); - * where the parameter given is the background colour of the stage, in hex - * you will use this stage instance to add your sprites to it and therefore to the renderer - * Here is how to add a sprite to the stage : - * stage.addChild(sprite); - */ -PIXI.Stage = function(backgroundColor) -{ - PIXI.DisplayObjectContainer.call( this ); - - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Mat3 - * @readOnly - * @private - */ - this.worldTransform = new PIXI.Matrix(); - - /** - * Whether or not the stage is interactive - * - * @property interactive - * @type Boolean - */ - this.interactive = true; - - /** - * The interaction manage for this stage, manages all interactive activity on the stage - * - * @property interactive - * @type InteractionManager - */ - this.interactionManager = new PIXI.InteractionManager(this); - - /** - * Whether the stage is dirty and needs to have interactions updated - * - * @property dirty - * @type Boolean - * @private - */ - this.dirty = true; - - //the stage is its own stage - this.stage = this; - - //optimize hit detection a bit - this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000); - - this.setBackgroundColor(backgroundColor); -}; - -// constructor -PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); -PIXI.Stage.prototype.constructor = PIXI.Stage; - -/** - * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element. - * This is useful for when you have other DOM elements on top of the Canvas element. - * - * @method setInteractionDelegate - * @param domElement {DOMElement} This new domElement which will receive mouse/touch events - */ -PIXI.Stage.prototype.setInteractionDelegate = function(domElement) -{ - this.interactionManager.setTargetDomElement( domElement ); -}; - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.Stage.prototype.updateTransform = function() -{ - this.worldAlpha = 1; - - for(var i=0,j=this.children.length; i> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; -}; - -/** - * Converts a color as an [R, G, B] array to a hex number - * - * @method rgb2hex - * @param rgb {Array} - */ -PIXI.rgb2hex = function(rgb) { - return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255); -}; - -/** - * A polyfill for Function.prototype.bind - * - * @method bind - */ -if (typeof Function.prototype.bind !== 'function') { - Function.prototype.bind = (function () { - var slice = Array.prototype.slice; - return function (thisArg) { - var target = this, boundArgs = slice.call(arguments, 1); - - if (typeof target !== 'function') throw new TypeError(); - - function bound() { - var args = boundArgs.concat(slice.call(arguments)); - target.apply(this instanceof bound ? this : thisArg, args); - } - - bound.prototype = (function F(proto) { - if (proto) F.prototype = proto; - if (!(this instanceof F)) return new F(); - })(target.prototype); - - return bound; - }; - })(); -} - -/** - * A wrapper for ajax requests to be handled cross browser - * - * @class AjaxRequest - * @constructor - */ -PIXI.AjaxRequest = function() -{ - var activexmodes = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; //activeX versions to check for in IE - - if (window.ActiveXObject) - { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) - for (var i=0; i 0 && (number & (number - 1)) === 0) // see: http://goo.gl/D9kPj - return number; - else - { - var result = 1; - while (result < number) result <<= 1; - return result; - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * https://github.com/mrdoob/eventtarget.js/ - * THankS mr DOob! - */ - -/** - * Adds event emitter functionality to a class - * - * @class EventTarget - * @example - * function MyEmitter() { - * PIXI.EventTarget.call(this); //mixes in event target stuff - * } - * - * var em = new MyEmitter(); - * em.emit({ type: 'eventName', data: 'some data' }); - */ -PIXI.EventTarget = function () { - - /** - * Holds all the listeners - * - * @property listeneners - * @type Object - */ - var listeners = {}; - - /** - * Adds a listener for a specific event - * - * @method addEventListener - * @param type {string} A string representing the event type to listen for. - * @param listener {function} The callback function that will be fired when the event occurs - */ - this.addEventListener = this.on = function ( type, listener ) { - - - if ( listeners[ type ] === undefined ) { - - listeners[ type ] = []; - - } - - if ( listeners[ type ].indexOf( listener ) === - 1 ) { - - listeners[ type ].push( listener ); - } - - }; - - /** - * Fires the event, ie pretends that the event has happened - * - * @method dispatchEvent - * @param event {Event} the event object - */ - this.dispatchEvent = this.emit = function ( event ) { - - if ( !listeners[ event.type ] || !listeners[ event.type ].length ) { - - return; - - } - - for(var i = 0, l = listeners[ event.type ].length; i < l; i++) { - - listeners[ event.type ][ i ]( event ); - - } - - }; - - /** - * Removes the specified listener that was assigned to the specified event type - * - * @method removeEventListener - * @param type {string} A string representing the event type which will have its listener removed - * @param listener {function} The callback function that was be fired when the event occured - */ - this.removeEventListener = this.off = function ( type, listener ) { - - var index = listeners[ type ].indexOf( listener ); - - if ( index !== - 1 ) { - - listeners[ type ].splice( index, 1 ); - - } - - }; - - /** - * Removes all the listeners that were active for the specified event type - * - * @method removeAllEventListeners - * @param type {string} A string representing the event type which will have all its listeners removed - */ - this.removeAllEventListeners = function( type ) { - var a = listeners[type]; - if (a) - a.length = 0; - }; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This helper function will automatically detect which renderer you should be using. - * WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by - * the browser then this function will return a canvas renderer - * @class autoDetectRenderer - * @static - * @param width=800 {Number} the width of the renderers view - * @param height=600 {Number} the height of the renderers view - * @param [view] {Canvas} the canvas to use as a view, optional - * @param [transparent=false] {Boolean} the transparency of the render view, default false - * @param [antialias=false] {Boolean} sets antialias (only applicable in webGL chrome at the moment) - * - */ -PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias) -{ - if(!width)width = 800; - if(!height)height = 600; - - // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { - var canvas = document.createElement( 'canvas' ); - return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); - } catch( e ) { - return false; - } - } )(); - - - if( webgl ) - { - return new PIXI.WebGLRenderer(width, height, view, transparent, antialias); - } - - return new PIXI.CanvasRenderer(width, height, view, transparent); -}; - -/* - PolyK library - url: http://polyk.ivank.net - Released under MIT licence. - - Copyright (c) 2012 Ivan Kuckir - - 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. - - This is an amazing lib! - - slightly modified by Mat Groves (matgroves.com); -*/ - -/** - * Based on the Polyk library http://polyk.ivank.net released under MIT licence. - * This is an amazing lib! - * slightly modified by Mat Groves (matgroves.com); - * @class PolyK - * - */ -PIXI.PolyK = {}; - -/** - * Triangulates shapes for webGL graphic fills - * - * @method Triangulate - * - */ -PIXI.PolyK.Triangulate = function(p) -{ - var sign = true; - - var n = p.length >> 1; - if(n < 3) return []; - - var tgs = []; - var avl = []; - for(var i = 0; i < n; i++) avl.push(i); - - i = 0; - var al = n; - while(al > 3) - { - var i0 = avl[(i+0)%al]; - var i1 = avl[(i+1)%al]; - var i2 = avl[(i+2)%al]; - - var ax = p[2*i0], ay = p[2*i0+1]; - var bx = p[2*i1], by = p[2*i1+1]; - var cx = p[2*i2], cy = p[2*i2+1]; - - var earFound = false; - if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign)) - { - earFound = true; - for(var j = 0; j < al; j++) - { - var vi = avl[j]; - if(vi === i0 || vi === i1 || vi === i2) continue; - - if(PIXI.PolyK._PointInTriangle(p[2*vi], p[2*vi+1], ax, ay, bx, by, cx, cy)) { - earFound = false; - break; - } - } - } - - if(earFound) - { - tgs.push(i0, i1, i2); - avl.splice((i+1)%al, 1); - al--; - i = 0; - } - else if(i++ > 3*al) - { - // need to flip flip reverse it! - // reset! - if(sign) - { - tgs = []; - avl = []; - for(i = 0; i < n; i++) avl.push(i); - - i = 0; - al = n; - - sign = false; - } - else - { - window.console.log("PIXI Warning: shape too complex to fill"); - return []; - } - } - } - - tgs.push(avl[0], avl[1], avl[2]); - return tgs; -}; - -/** - * Checks whether a point is within a triangle - * - * @method _PointInTriangle - * @param px {Number} x coordinate of the point to test - * @param py {Number} y coordinate of the point to test - * @param ax {Number} x coordinate of the a point of the triangle - * @param ay {Number} y coordinate of the a point of the triangle - * @param bx {Number} x coordinate of the b point of the triangle - * @param by {Number} y coordinate of the b point of the triangle - * @param cx {Number} x coordinate of the c point of the triangle - * @param cy {Number} y coordinate of the c point of the triangle - * @private - */ -PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) -{ - var v0x = cx-ax; - var v0y = cy-ay; - var v1x = bx-ax; - var v1y = by-ay; - var v2x = px-ax; - var v2y = py-ay; - - var dot00 = v0x*v0x+v0y*v0y; - var dot01 = v0x*v1x+v0y*v1y; - var dot02 = v0x*v2x+v0y*v2y; - var dot11 = v1x*v1x+v1y*v1y; - var dot12 = v1x*v2x+v1y*v2y; - - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v < 1); -}; - -/** - * Checks whether a shape is convex - * - * @method _convex - * - * @private - */ -PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign) -{ - return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -// TODO Alvin and Mat -// Should we eventually create a Utils class ? -// Or just move this file to the pixi.js file ? -PIXI.initDefaultShaders = function() -{ - - // PIXI.stripShader = new PIXI.StripShader(); -// PIXI.stripShader.init(); - -}; - -PIXI.CompileVertexShader = function(gl, shaderSrc) -{ - return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); -}; - -PIXI.CompileFragmentShader = function(gl, shaderSrc) -{ - return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); -}; - -PIXI._CompileShader = function(gl, shaderSrc, shaderType) -{ - var src = shaderSrc.join("\n"); - var shader = gl.createShader(shaderType); - gl.shaderSource(shader, src); - gl.compileShader(shader); - - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - window.console.log(gl.getShaderInfoLog(shader)); - return null; - } - - return shader; -}; - -PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc) -{ - var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); - var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); - - var shaderProgram = gl.createProgram(); - - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - gl.linkProgram(shaderProgram); - - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - window.console.log("Could not initialise shaders"); - } - - return shaderProgram; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * @author Richard Davey http://www.photonstorm.com @photonstorm - */ - -/** -* @class PixiShader -* @constructor -*/ -PIXI.PixiShader = function(gl) -{ - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * @property {any} program - The WebGL program. - */ - this.program = null; - - /** - * @property {array} fragmentSrc - The fragment shader. - */ - this.fragmentSrc = [ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]; - - - /** - * @property {number} textureCount - A local texture counter for multi-texture shaders. - */ - this.textureCount = 0; - - this.attributes = []; - - this.init(); -}; - -/** -* Initialises the shader -* @method init -* -*/ -PIXI.PixiShader.prototype.init = function() -{ - - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc); - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.dimensions = gl.getUniformLocation(program, 'dimensions'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - - // Begin worst hack eva // - - // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? - // maybe its something to do with the current state of the gl context. - // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel - // If theres any webGL people that know why could happen please help :) - if(this.colorAttribute === -1) - { - this.colorAttribute = 2; - } - - this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute]; - - // End worst hack eva // - - // add those custom shaders! - for (var key in this.uniforms) - { - // get the uniform locations.. - this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key); - } - - this.initUniforms(); - - this.program = program; -}; - -/** -* Initialises the shader uniform values. -* Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ -* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf -* -* @method initUniforms -*/ -PIXI.PixiShader.prototype.initUniforms = function() -{ - this.textureCount = 1; - var gl = this.gl; - var uniform; - - for (var key in this.uniforms) - { - uniform = this.uniforms[key]; - - var type = uniform.type; - - if (type === 'sampler2D') - { - uniform._init = false; - - if (uniform.value !== null) - { - this.initSampler2D(uniform); - } - } - else if (type === 'mat2' || type === 'mat3' || type === 'mat4') - { - // These require special handling - uniform.glMatrix = true; - uniform.glValueLength = 1; - - if (type === 'mat2') - { - uniform.glFunc = gl.uniformMatrix2fv; - } - else if (type === 'mat3') - { - uniform.glFunc = gl.uniformMatrix3fv; - } - else if (type === 'mat4') - { - uniform.glFunc = gl.uniformMatrix4fv; - } - } - else - { - // GL function reference - uniform.glFunc = gl['uniform' + type]; - - if (type === '2f' || type === '2i') - { - uniform.glValueLength = 2; - } - else if (type === '3f' || type === '3i') - { - uniform.glValueLength = 3; - } - else if (type === '4f' || type === '4i') - { - uniform.glValueLength = 4; - } - else - { - uniform.glValueLength = 1; - } - } - } - -}; - -/** -* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded) -* -* @method initSampler2D -*/ -PIXI.PixiShader.prototype.initSampler2D = function(uniform) -{ - if (!uniform.value || !uniform.value.baseTexture || !uniform.value.baseTexture.hasLoaded) - { - return; - } - - var gl = this.gl; - - gl.activeTexture(gl['TEXTURE' + this.textureCount]); - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTexture); - - // Extended texture data - if (uniform.textureData) - { - var data = uniform.textureData; - - // GLTexture = mag linear, min linear_mipmap_linear, wrap repeat + gl.generateMipmap(gl.TEXTURE_2D); - // GLTextureLinear = mag/min linear, wrap clamp - // GLTextureNearestRepeat = mag/min NEAREST, wrap repeat - // GLTextureNearest = mag/min nearest, wrap clamp - // AudioTexture = whatever + luminance + width 512, height 2, border 0 - // KeyTexture = whatever + luminance + width 256, height 2, border 0 - - // magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST - // wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT - - var magFilter = (data.magFilter) ? data.magFilter : gl.LINEAR; - var minFilter = (data.minFilter) ? data.minFilter : gl.LINEAR; - var wrapS = (data.wrapS) ? data.wrapS : gl.CLAMP_TO_EDGE; - var wrapT = (data.wrapT) ? data.wrapT : gl.CLAMP_TO_EDGE; - var format = (data.luminance) ? gl.LUMINANCE : gl.RGBA; - - if (data.repeat) - { - wrapS = gl.REPEAT; - wrapT = gl.REPEAT; - } - - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY); - - if (data.width) - { - var width = (data.width) ? data.width : 512; - var height = (data.height) ? data.height : 2; - var border = (data.border) ? data.border : 0; - - // void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels); - gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null); - } - else - { - // void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels); - gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.value.baseTexture.source); - } - - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); - } - - gl.uniform1i(uniform.uniformLocation, this.textureCount); - - uniform._init = true; - - this.textureCount++; - -}; - -/** -* Updates the shader uniform values. -* -* @method syncUniforms -*/ -PIXI.PixiShader.prototype.syncUniforms = function() -{ - this.textureCount = 1; - var uniform; - var gl = this.gl; - - // This would probably be faster in an array and it would guarantee key order - for (var key in this.uniforms) - { - - uniform = this.uniforms[key]; - - if (uniform.glValueLength === 1) - { - if (uniform.glMatrix === true) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.transpose, uniform.value); - } - else - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value); - } - } - else if (uniform.glValueLength === 2) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y); - } - else if (uniform.glValueLength === 3) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z); - } - else if (uniform.glValueLength === 4) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w); - } - else if (uniform.type === 'sampler2D') - { - if (uniform._init) - { - gl.activeTexture(gl['TEXTURE' + this.textureCount]); - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl)); - gl.uniform1i(uniform.uniformLocation, this.textureCount); - this.textureCount++; - } - else - { - this.initSampler2D(uniform); - } - } - } - -}; - -/** -* Destroys the shader -* @method destroy -* -*/ -PIXI.PixiShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attributes = null; -}; - -/** -* -* @property defaultVertexSrc -* @type String -*/ -PIXI.PixiShader.defaultVertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec2 aColor;', - - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void) {', - ' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', - ' vColor = vec4(color * aColor.x, aColor.x);', - '}' -]; - - - - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * @author Richard Davey http://www.photonstorm.com @photonstorm - */ - -/** -* @class PixiFastShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PixiFastShader = function(gl) -{ - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * @property {any} program - The WebGL program. - */ - this.program = null; - - /** - * @property {array} fragmentSrc - The fragment shader. - */ - this.fragmentSrc = [ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying float vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]; - - /** - * @property {array} vertexSrc - The vertex shader - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aPositionCoord;', - 'attribute vec2 aScale;', - 'attribute float aRotation;', - 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', - - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - 'uniform mat3 uMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying float vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void) {', - ' vec2 v;', - ' vec2 sv = aVertexPosition * aScale;', - ' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);', - ' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);', - ' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;', - ' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - // ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', - ' vColor = aColor;', - '}' - ]; - - - /** - * @property {number} textureCount - A local texture counter for multi-texture shaders. - */ - this.textureCount = 0; - - - this.init(); -}; - -/** -* Initialises the shader -* @method init -* -*/ -PIXI.PixiFastShader.prototype.init = function() -{ - - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.dimensions = gl.getUniformLocation(program, 'dimensions'); - this.uMatrix = gl.getUniformLocation(program, 'uMatrix'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord'); - - this.aScale = gl.getAttribLocation(program, 'aScale'); - this.aRotation = gl.getAttribLocation(program, 'aRotation'); - - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - - - // Begin worst hack eva // - - // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? - // maybe its somthing to do with the current state of the gl context. - // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel - // If theres any webGL people that know why could happen please help :) - if(this.colorAttribute === -1) - { - this.colorAttribute = 2; - } - - this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute]; - - // End worst hack eva // - - - this.program = program; -}; - -/** -* Destroys the shader -* @method destroy -* -*/ -PIXI.PixiFastShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attributes = null; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -PIXI.StripShader = function() -{ - /** - * @property {any} program - The WebGL program. - */ - this.program = null; - - /** - * @property {array} fragmentSrc - The fragment shader. - */ - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying float vColor;', - 'uniform float alpha;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));', - ' gl_FragColor = gl_FragColor * alpha;', - '}' - ]; - - /** - * @property {array} fragmentSrc - The fragment shader. - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'varying vec2 vTextureCoord;', - 'uniform vec2 offsetVector;', - 'varying float vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = aColor;', - '}' - ]; -}; - -/** -* Initialises the shader -* @method init -* -*/ -PIXI.StripShader.prototype.init = function() -{ - - var gl = PIXI.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - //this.dimensions = gl.getUniformLocation(this.program, 'dimensions'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class PrimitiveShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PrimitiveShader = function(gl) -{ - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * @property {any} program - The WebGL program. - */ - this.program = null; - - /** - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' gl_FragColor = vColor;', - '}' - ]; - - /** - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec4 aColor;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - 'uniform float alpha;', - 'uniform vec3 tint;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', - ' vColor = aColor * vec4(tint * alpha, alpha);', - '}' - ]; - - this.init(); -}; - -/** -* Initialises the shader -* @method init -* -*/ -PIXI.PrimitiveShader.prototype.init = function() -{ - - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.tintColor = gl.getUniformLocation(program, 'tint'); - - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - this.attributes = [this.aVertexPosition, this.colorAttribute]; - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** -* Destroys the shader -* @method destroy -* -*/ -PIXI.PrimitiveShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attribute = null; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A set of functions used by the webGL renderer to draw the primitive graphics data - * - * @class WebGLGraphics - * @private - * @static - */ -PIXI.WebGLGraphics = function() -{ - -}; - -/** - * Renders the graphics object - * - * @static - * @private - * @method renderGraphics - * @param graphics {Graphics} - * @param renderSession {Object} - */ -PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projection, offset) -{ - var gl = renderSession.gl; - var projection = renderSession.projection, - offset = renderSession.offset, - shader = renderSession.shaderManager.primitiveShader; - - if(!graphics._webGL[gl.id])graphics._webGL[gl.id] = {points:[], indices:[], lastIndex:0, - buffer:gl.createBuffer(), - indexBuffer:gl.createBuffer()}; - - var webGL = graphics._webGL[gl.id]; - - if(graphics.dirty) - { - graphics.dirty = false; - - if(graphics.clearDirty) - { - graphics.clearDirty = false; - - webGL.lastIndex = 0; - webGL.points = []; - webGL.indices = []; - - } - - PIXI.WebGLGraphics.updateGraphics(graphics, gl); - } - - renderSession.shaderManager.activatePrimitiveShader(); - - // This could be speeded up for sure! - - // set the matrix transform - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - - gl.uniform1f(shader.alpha, graphics.worldAlpha); - gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer); - - gl.drawElements(gl.TRIANGLE_STRIP, webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); - - renderSession.shaderManager.deactivatePrimitiveShader(); - - // return to default shader... -// PIXI.activateShader(PIXI.defaultShader); -}; - -/** - * Updates the graphics object - * - * @static - * @private - * @method updateGraphics - * @param graphicsData {Graphics} The graphics object to update - * @param gl {WebGLContext} the current WebGL drawing context - */ -PIXI.WebGLGraphics.updateGraphics = function(graphics, gl) -{ - var webGL = graphics._webGL[gl.id]; - - for (var i = webGL.lastIndex; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - if(data.type === PIXI.Graphics.POLY) - { - if(data.fill) - { - if(data.points.length>3) - PIXI.WebGLGraphics.buildPoly(data, webGL); - } - - if(data.lineWidth > 0) - { - PIXI.WebGLGraphics.buildLine(data, webGL); - } - } - else if(data.type === PIXI.Graphics.RECT) - { - PIXI.WebGLGraphics.buildRectangle(data, webGL); - } - else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP) - { - PIXI.WebGLGraphics.buildCircle(data, webGL); - } - } - - webGL.lastIndex = graphics.graphicsData.length; - - - - webGL.glPoints = new Float32Array(webGL.points); - - gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer); - gl.bufferData(gl.ARRAY_BUFFER, webGL.glPoints, gl.STATIC_DRAW); - - webGL.glIndicies = new Uint16Array(webGL.indices); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, webGL.glIndicies, gl.STATIC_DRAW); -}; - -/** - * Builds a rectangle to draw - * - * @static - * @private - * @method buildRectangle - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) -{ - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - - if(graphicsData.fill) - { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vertPos = verts.length/6; - - // start - verts.push(x, y); - verts.push(r, g, b, alpha); - - verts.push(x + width, y); - verts.push(r, g, b, alpha); - - verts.push(x , y + height); - verts.push(r, g, b, alpha); - - verts.push(x + width, y + height); - verts.push(r, g, b, alpha); - - // insert 2 dead triangles.. - indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3); - } - - if(graphicsData.lineWidth) - { - var tempPoints = graphicsData.points; - - graphicsData.points = [x, y, - x + width, y, - x + width, y + height, - x, y + height, - x, y]; - - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Builds a circle to draw - * - * @static - * @private - * @method buildCircle - * @param graphicsData {Graphics} The graphics object to draw - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) -{ - - // need to convert points to a nice regular data - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - var totalSegs = 40; - var seg = (Math.PI * 2) / totalSegs ; - - var i = 0; - - if(graphicsData.fill) - { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - indices.push(vecPos); - - for (i = 0; i < totalSegs + 1 ; i++) - { - verts.push(x,y, r, g, b, alpha); - - verts.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height, - r, g, b, alpha); - - indices.push(vecPos++, vecPos++); - } - - indices.push(vecPos-1); - } - - if(graphicsData.lineWidth) - { - var tempPoints = graphicsData.points; - - graphicsData.points = []; - - for (i = 0; i < totalSegs + 1; i++) - { - graphicsData.points.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height); - } - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Builds a line to draw - * - * @static - * @private - * @method buildLine - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) -{ - // TODO OPTIMISE! - var i = 0; - - var points = graphicsData.points; - if(points.length === 0)return; - - // if the line width is an odd number add 0.5 to align to a whole pixel - if(graphicsData.lineWidth%2) - { - for (i = 0; i < points.length; i++) { - points[i] += 0.5; - } - } - - // get first and last point.. figure out the middle! - var firstPoint = new PIXI.Point( points[0], points[1] ); - var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - // if the first point is the last point - gonna have issues :) - if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) - { - points.pop(); - points.pop(); - - lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; - var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; - - points.unshift(midPointX, midPointY); - points.push(midPointX, midPointY); - } - - var verts = webGLData.points; - var indices = webGLData.indices; - var length = points.length / 2; - var indexCount = points.length; - var indexStart = verts.length/6; - - // DRAW the Line - var width = graphicsData.lineWidth / 2; - - // sort color - var color = PIXI.hex2rgb(graphicsData.lineColor); - var alpha = graphicsData.lineAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var px, py, p1x, p1y, p2x, p2y, p3x, p3y; - var perpx, perpy, perp2x, perp2y, perp3x, perp3y; - var a1, b1, c1, a2, b2, c2; - var denom, pdist, dist; - - p1x = points[0]; - p1y = points[1]; - - p2x = points[2]; - p2y = points[3]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - // start - verts.push(p1x - perpx , p1y - perpy, - r, g, b, alpha); - - verts.push(p1x + perpx , p1y + perpy, - r, g, b, alpha); - - for (i = 1; i < length-1; i++) - { - p1x = points[(i-1)*2]; - p1y = points[(i-1)*2 + 1]; - - p2x = points[(i)*2]; - p2y = points[(i)*2 + 1]; - - p3x = points[(i+1)*2]; - p3y = points[(i+1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - perp2x = -(p2y - p3y); - perp2y = p2x - p3x; - - dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); - perp2x /= dist; - perp2y /= dist; - perp2x *= width; - perp2y *= width; - - a1 = (-perpy + p1y) - (-perpy + p2y); - b1 = (-perpx + p2x) - (-perpx + p1x); - c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); - a2 = (-perp2y + p3y) - (-perp2y + p2y); - b2 = (-perp2x + p2x) - (-perp2x + p3x); - c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); - - denom = a1*b2 - a2*b1; - - if(Math.abs(denom) < 0.1 ) - { - - denom+=10.1; - verts.push(p2x - perpx , p2y - perpy, - r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy, - r, g, b, alpha); - - continue; - } - - px = (b1*c2 - b2*c1)/denom; - py = (a2*c1 - a1*c2)/denom; - - - pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); - - - if(pdist > 140 * 140) - { - perp3x = perpx - perp2x; - perp3y = perpy - perp2y; - - dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); - perp3x /= dist; - perp3y /= dist; - perp3x *= width; - perp3y *= width; - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x + perp3x, p2y +perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - indexCount++; - } - else - { - - verts.push(px , py); - verts.push(r, g, b, alpha); - - verts.push(p2x - (px-p2x), p2y - (py - p2y)); - verts.push(r, g, b, alpha); - } - } - - p1x = points[(length-2)*2]; - p1y = points[(length-2)*2 + 1]; - - p2x = points[(length-1)*2]; - p2y = points[(length-1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - verts.push(p2x - perpx , p2y - perpy); - verts.push(r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy); - verts.push(r, g, b, alpha); - - indices.push(indexStart); - - for (i = 0; i < indexCount; i++) - { - indices.push(indexStart++); - } - - indices.push(indexStart-1); -}; - -/** - * Builds a polygon to draw - * - * @static - * @private - * @method buildPoly - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) -{ - var points = graphicsData.points; - if(points.length < 6)return; - - // get first and last point.. figure out the middle! - var verts = webGLData.points; - var indices = webGLData.indices; - - var length = points.length / 2; - - // sort color - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var triangles = PIXI.PolyK.Triangulate(points); - - var vertPos = verts.length / 6; - - var i = 0; - - for (i = 0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vertPos); - indices.push(triangles[i] + vertPos); - indices.push(triangles[i+1] + vertPos); - indices.push(triangles[i+2] +vertPos); - indices.push(triangles[i+2] + vertPos); - } - - for (i = 0; i < length; i++) - { - verts.push(points[i * 2], points[i * 2 + 1], - r, g, b, alpha); - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.glContexts = []; // this is where we store the webGL contexts for easy access. - -/** - * the WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer - * should be used for browsers that support webGL. This Render works by automatically managing webGLBatch's. - * So no need for Sprite Batch's or Sprite Cloud's - * Dont forget to add the view to your DOM or you will not see anything :) - * - * @class WebGLRenderer - * @constructor - * @param width=0 {Number} the width of the canvas view - * @param height=0 {Number} the height of the canvas view - * @param view {HTMLCanvasElement} the canvas to use as a view, optional - * @param transparent=false {Boolean} If the render view is transparent, default false - * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment) - * - */ -PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) -{ - if(!PIXI.defaultRenderer)PIXI.defaultRenderer = this; - - this.type = PIXI.WEBGL_RENDERER; - - // do a catch.. only 1 webGL renderer.. - /** - * Whether the render view is transparent - * - * @property transparent - * @type Boolean - */ - this.transparent = !!transparent; - - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; - - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; - - /** - * The canvas element that everything is drawn to - * - * @property view - * @type HTMLCanvasElement - */ - this.view = view || document.createElement( 'canvas' ); - this.view.width = this.width; - this.view.height = this.height; - - // deal with losing context.. - this.contextLost = this.handleContextLost.bind(this); - this.contextRestoredLost = this.handleContextRestored.bind(this); - - this.view.addEventListener('webglcontextlost', this.contextLost, false); - this.view.addEventListener('webglcontextrestored', this.contextRestoredLost, false); - - this.options = { - alpha: this.transparent, - antialias:!!antialias, // SPEED UP?? - premultipliedAlpha:!!transparent, - stencil:true - }; - - //try 'experimental-webgl' - try { - this.gl = this.view.getContext('experimental-webgl', this.options); - } catch (e) { - //try 'webgl' - try { - this.gl = this.view.getContext('webgl', this.options); - } catch (e2) { - // fail, not able to get a context - throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); - } - } - - var gl = this.gl; - this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++; - - PIXI.glContexts[this.glContextId] = gl; - - if(!PIXI.blendModesWebGL) - { - PIXI.blendModesWebGL = []; - - PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; - PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - } - - - - - this.projection = new PIXI.Point(); - this.projection.x = this.width/2; - this.projection.y = -this.height/2; - - this.offset = new PIXI.Point(0, 0); - - this.resize(this.width, this.height); - this.contextLost = false; - - // time to create the render managers! each one focuses on managine a state in webGL - this.shaderManager = new PIXI.WebGLShaderManager(gl); // deals with managing the shader programs and their attribs - this.spriteBatch = new PIXI.WebGLSpriteBatch(gl); // manages the rendering of sprites - this.maskManager = new PIXI.WebGLMaskManager(gl); // manages the masks using the stencil buffer - this.filterManager = new PIXI.WebGLFilterManager(gl, this.transparent); // manages the filters - - this.renderSession = {}; - this.renderSession.gl = this.gl; - this.renderSession.drawCount = 0; - this.renderSession.shaderManager = this.shaderManager; - this.renderSession.maskManager = this.maskManager; - this.renderSession.filterManager = this.filterManager; - this.renderSession.spriteBatch = this.spriteBatch; - - - gl.useProgram(this.shaderManager.defaultShader.program); - - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); - - gl.enable(gl.BLEND); - gl.colorMask(true, true, true, this.transparent); -}; - -// constructor -PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; - -/** - * Renders the stage to its webGL view - * - * @method render - * @param stage {Stage} the Stage element to be rendered - */ -PIXI.WebGLRenderer.prototype.render = function(stage) -{ - if(this.contextLost)return; - - - // if rendering a new stage clear the batches.. - if(this.__stage !== stage) - { - if(stage.interactive)stage.interactionManager.removeEvents(); - - // TODO make this work - // dont think this is needed any more? - this.__stage = stage; - } - - // update any textures this includes uvs and uploading them to the gpu - PIXI.WebGLRenderer.updateTextures(); - - // update the scene graph - stage.updateTransform(); - - var gl = this.gl; - - // -- Does this need to be set every frame? -- // - //gl.colorMask(true, true, true, this.transparent); - gl.viewport(0, 0, this.width, this.height); - - // make sure we are bound to the main frame buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - if(this.transparent) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1); - } - - - gl.clear(gl.COLOR_BUFFER_BIT); - - this.renderDisplayObject( stage, this.projection ); - - // interaction - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - else - { - if(stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = false; - stage.interactionManager.setTarget(this); - } - } - - /* - //can simulate context loss in Chrome like so: - this.view.onmousedown = function(ev) { - console.dir(this.gl.getSupportedExtensions()); - var ext = ( - gl.getExtension("WEBGL_scompressed_texture_s3tc") - // gl.getExtension("WEBGL_compressed_texture_s3tc") || - // gl.getExtension("MOZ_WEBGL_compressed_texture_s3tc") || - // gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc") - ); - console.dir(ext); - var loseCtx = this.gl.getExtension("WEBGL_lose_context"); - console.log("killing context"); - loseCtx.loseContext(); - setTimeout(function() { - console.log("restoring context..."); - loseCtx.restoreContext(); - }.bind(this), 1000); - }.bind(this); - */ -}; - -/** - * Renders a display Object - * - * @method renderDIsplayObject - * @param displayObject {DisplayObject} The DisplayObject to render - * @param projection {Point} The projection - * @param buffer {Array} a standard WebGL buffer - */ -PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, projection, buffer) -{ - // reset the render session data.. - this.renderSession.drawCount = 0; - this.renderSession.currentBlendMode = 9999; - - this.renderSession.projection = projection; - this.renderSession.offset = this.offset; - - // start the sprite batch - this.spriteBatch.begin(this.renderSession); - - // start the filter manager - this.filterManager.begin(this.renderSession, buffer); - - // render the scene! - displayObject._renderWebGL(this.renderSession); - - // finish the sprite batch - this.spriteBatch.end(); -}; - -/** - * Updates the textures loaded into this webgl renderer - * - * @static - * @method updateTextures - * @private - */ -PIXI.WebGLRenderer.updateTextures = function() -{ - var i = 0; - - //TODO break this out into a texture manager... - //for (i = 0; i < PIXI.texturesToUpdate.length; i++) - // PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); - - - for (i=0; i < PIXI.Texture.frameUpdates.length; i++) - PIXI.WebGLRenderer.updateTextureFrame(PIXI.Texture.frameUpdates[i]); - - for (i = 0; i < PIXI.texturesToDestroy.length; i++) - PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); - - PIXI.texturesToUpdate.length = 0; - PIXI.texturesToDestroy.length = 0; - PIXI.Texture.frameUpdates.length = 0; -}; - -/** - * Destroys a loaded webgl texture - * - * @method destroyTexture - * @param texture {Texture} The texture to update - * @private - */ -PIXI.WebGLRenderer.destroyTexture = function(texture) -{ - //TODO break this out into a texture manager... - - for (var i = texture._glTextures.length - 1; i >= 0; i--) - { - var glTexture = texture._glTextures[i]; - var gl = PIXI.glContexts[i]; - - if(gl && glTexture) - { - gl.deleteTexture(glTexture); - } - } - - texture._glTextures.length = 0; -}; - -/** - * - * @method updateTextureFrame - * @param texture {Texture} The texture to update the frame from - * @private - */ -PIXI.WebGLRenderer.updateTextureFrame = function(texture) -{ - texture.updateFrame = false; - - // now set the uvs. Figured that the uv data sits with a texture rather than a sprite. - // so uv data is stored on the texture itself - texture._updateWebGLuvs(); -}; - -/** - * resizes the webGL view to the specified width and height - * - * @method resize - * @param width {Number} the new width of the webGL view - * @param height {Number} the new height of the webGL view - */ -PIXI.WebGLRenderer.prototype.resize = function(width, height) -{ - this.width = width; - this.height = height; - - this.view.width = width; - this.view.height = height; - - this.gl.viewport(0, 0, this.width, this.height); - - this.projection.x = this.width/2; - this.projection.y = -this.height/2; -}; - -/** - * Creates a WebGL texture - * - * @method createWebGLTexture - * @param texture {Texture} the texture to render - * @param gl {webglContext} the WebGL context - * @static - */ -PIXI.createWebGLTexture = function(texture, gl) -{ - - - if(texture.hasLoaded) - { - texture._glTextures[gl.id] = gl.createTexture(); - - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - - // reguler... - - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } - - gl.bindTexture(gl.TEXTURE_2D, null); - } - - return texture._glTextures[gl.id]; -}; - -/** - * Updates a WebGL texture - * - * @method updateWebGLTexture - * @param texture {Texture} the texture to update - * @param gl {webglContext} the WebGL context - * @private - */ -PIXI.updateWebGLTexture = function(texture, gl) -{ - if( texture._glTextures[gl.id] ) - { - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - - // reguler... - - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } - - gl.bindTexture(gl.TEXTURE_2D, null); - } - -}; - -/** - * Handles a lost webgl context - * - * @method handleContextLost - * @param event {Event} - * @private - */ -PIXI.WebGLRenderer.prototype.handleContextLost = function(event) -{ - event.preventDefault(); - this.contextLost = true; -}; - -/** - * Handles a restored webgl context - * - * @method handleContextRestored - * @param event {Event} - * @private - */ -PIXI.WebGLRenderer.prototype.handleContextRestored = function() -{ - - //try 'experimental-webgl' - try { - this.gl = this.view.getContext('experimental-webgl', this.options); - } catch (e) { - //try 'webgl' - try { - this.gl = this.view.getContext('webgl', this.options); - } catch (e2) { - // fail, not able to get a context - throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); - } - } - - var gl = this.gl; - gl.id = PIXI.WebGLRenderer.glContextId ++; - - - - // need to set the context... - this.shaderManager.setContext(gl); - this.spriteBatch.setContext(gl); - this.maskManager.setContext(gl); - this.filterManager.setContext(gl); - - - this.renderSession.gl = this.gl; - - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); - - gl.enable(gl.BLEND); - gl.colorMask(true, true, true, this.transparent); - - this.gl.viewport(0, 0, this.width, this.height); - - for(var key in PIXI.TextureCache) - { - var texture = PIXI.TextureCache[key].baseTexture; - texture._glTextures = []; - } - - /** - * Whether the context was lost - * @property contextLost - * @type Boolean - */ - this.contextLost = false; - -}; - -/** - * Removes everything from the renderer (event listeners, spritebatch, etc...) - * - * @method destroy - */ -PIXI.WebGLRenderer.prototype.destroy = function() -{ - - // deal with losing context.. - - // remove listeners - this.view.removeEventListener('webglcontextlost', this.contextLost); - this.view.removeEventListener('webglcontextrestored', this.contextRestoredLost); - - PIXI.glContexts[this.glContextId] = null; - - this.projection = null; - this.offset = null; - - // time to create the render managers! each one focuses on managine a state in webGL - this.shaderManager.destroy(); - this.spriteBatch.destroy(); - this.maskManager.destroy(); - this.filterManager.destroy(); - - this.shaderManager = null; - this.spriteBatch = null; - this.maskManager = null; - this.filterManager = null; - - this.gl = null; - // - this.renderSession = null; -}; - - -PIXI.WebGLRenderer.glContextId = 0; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** -* @class WebGLMaskManager -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -* @private -*/ -PIXI.WebGLMaskManager = function(gl) -{ - this.maskStack = []; - this.maskPosition = 0; - - this.setContext(gl); -}; - -/** -* Sets the drawing context to the one given in parameter -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLMaskManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Applies the Mask and adds it to the current filter stack -* @method pushMask -* @param maskData {Array} -* @param renderSession {RenderSession} -*/ -PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession) -{ - var gl = this.gl; - - if(this.maskStack.length === 0) - { - gl.enable(gl.STENCIL_TEST); - gl.stencilFunc(gl.ALWAYS,1,1); - } - - // maskData.visible = false; - - this.maskStack.push(maskData); - - gl.colorMask(false, false, false, true); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - - PIXI.WebGLGraphics.renderGraphics(maskData, renderSession); - - gl.colorMask(true, true, true, true); - gl.stencilFunc(gl.NOTEQUAL,0, this.maskStack.length); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); -}; - -/** -* Removes the last filter from the filter stack and doesn't return it -* @method popMask -* -* @param renderSession {RenderSession} an object containing all the useful parameters -*/ -PIXI.WebGLMaskManager.prototype.popMask = function(renderSession) -{ - var gl = this.gl; - - var maskData = this.maskStack.pop(); - - if(maskData) - { - gl.colorMask(false, false, false, false); - - //gl.stencilFunc(gl.ALWAYS,1,1); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - - PIXI.WebGLGraphics.renderGraphics(maskData, renderSession); - - gl.colorMask(true, true, true, true); - gl.stencilFunc(gl.NOTEQUAL,0,this.maskStack.length); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - } - - if(this.maskStack.length === 0)gl.disable(gl.STENCIL_TEST); -}; - -/** -* Destroys the mask stack -* @method destroy -*/ -PIXI.WebGLMaskManager.prototype.destroy = function() -{ - this.maskStack = null; - this.gl = null; -}; -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLShaderManager -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -* @private -*/ -PIXI.WebGLShaderManager = function(gl) -{ - - this.maxAttibs = 10; - this.attribState = []; - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) { - this.attribState[i] = false; - } - - this.setContext(gl); - // the final one is used for the rendering strips - //this.stripShader = new PIXI.StripShader(gl); -}; - - -/** -* Initialises the context and the properties -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -* @param transparent {Boolean} Whether or not the drawing context should be transparent -*/ -PIXI.WebGLShaderManager.prototype.setContext = function(gl) -{ - this.gl = gl; - - // the next one is used for rendering primatives - this.primitiveShader = new PIXI.PrimitiveShader(gl); - - // this shader is used for the default sprite rendering - this.defaultShader = new PIXI.PixiShader(gl); - - // this shader is used for the fast sprite rendering - this.fastShader = new PIXI.PixiFastShader(gl); - - - this.activateShader(this.defaultShader); -}; - - -/** -* Takes the attributes given in parameters -* @method setAttribs -* @param attribs {Array} attribs -*/ -PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs) -{ - // reset temp state - - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (i = 0; i < attribs.length; i++) - { - var attribId = attribs[i]; - this.tempAttribState[attribId] = true; - } - - var gl = this.gl; - - for (i = 0; i < this.attribState.length; i++) - { - - if(this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if(this.tempAttribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** -* Sets-up the given shader -* -* @method activateShader -* @param shader {Object} the shader that is going to be activated -*/ -PIXI.WebGLShaderManager.prototype.activateShader = function(shader) -{ - //if(this.currentShader == shader)return; - - this.currentShader = shader; - - this.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - -}; - -/** -* Triggers the primitive shader -* @method activatePrimitiveShader -*/ -PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function() -{ - var gl = this.gl; - - gl.useProgram(this.primitiveShader.program); - - this.setAttribs(this.primitiveShader.attributes); - -}; - -/** -* Disable the primitive shader -* @method deactivatePrimitiveShader -*/ -PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function() -{ - var gl = this.gl; - - gl.useProgram(this.defaultShader.program); - - this.setAttribs(this.defaultShader.attributes); -}; - -/** -* Destroys -* @method destroy -*/ -PIXI.WebGLShaderManager.prototype.destroy = function() -{ - this.attribState = null; - - this.tempAttribState = null; - - this.primitiveShader.destroy(); - - this.defaultShader.destroy(); - - this.fastShader.destroy(); - - this.gl = null; -}; - - -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * - * Heavily inspired by LibGDX's WebGLSpriteBatch: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java - */ - - /** - * - * @class WebGLSpriteBatch - * @private - * @constructor - * @param gl {WebGLContext} the current WebGL drawing context - * - */ -PIXI.WebGLSpriteBatch = function(gl) -{ - - /** - * - * - * @property vertSize - * @type Number - */ - this.vertSize = 6; - - /** - * The number of images in the SpriteBatch before it flushes - * @property size - * @type Number - */ - this.size = 10000;//Math.pow(2, 16) / this.vertSize; - - //the total number of floats in our batch - var numVerts = this.size * 4 * this.vertSize; - //the total number of indices in our batch - var numIndices = this.size * 6; - - //vertex data - - /** - * Holds the vertices - * - * @property vertices - * @type Float32Array - */ - this.vertices = new Float32Array(numVerts); - - //index data - /** - * Holds the indices - * - * @property indices - * @type Uint16Array - */ - this.indices = new Uint16Array(numIndices); - - this.lastIndexCount = 0; - - for (var i=0, j=0; i < numIndices; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - - this.drawing = false; - this.currentBatchSize = 0; - this.currentBaseTexture = null; - - this.setContext(gl); -}; - -/** -* -* @method setContext -* -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLSpriteBatch.prototype.setContext = function(gl) -{ - this.gl = gl; - - // create a couple of buffers - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // 65535 is max index, so 65535 / 6 = 10922. - - - //upload the index data - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); - - this.currentBlendMode = 99999; -}; - -/** -* -* @method begin -* -* @param renderSession {RenderSession} the RenderSession -*/ -PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession) -{ - this.renderSession = renderSession; - this.shader = this.renderSession.shaderManager.defaultShader; - - this.start(); -}; - -/** -* -* @method end -* -*/ -PIXI.WebGLSpriteBatch.prototype.end = function() -{ - this.flush(); -}; - -/** -* -* @method render -* -* @param sprite {Sprite} the sprite to render when using this spritebatch -*/ -PIXI.WebGLSpriteBatch.prototype.render = function(sprite) -{ - // check texture.. - if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) - { - this.flush(); - this.currentBaseTexture = sprite.texture.baseTexture; - } - - - // check blend mode - if(sprite.blendMode !== this.currentBlendMode) - { - this.setBlendMode(sprite.blendMode); - } - - // get the uvs for the texture - var uvs = sprite._uvs || sprite.texture._uvs; - // if the uvs have not updated then no point rendering just yet! - if(!uvs)return; - - // get the sprites current alpha - var alpha = sprite.worldAlpha; - var tint = sprite.tint; - - var verticies = this.vertices; - - var width = sprite.texture.frame.width; - var height = sprite.texture.frame.height; - - // TODO trim?? - var aX = sprite.anchor.x; - var aY = sprite.anchor.y; - - var w0, w1, h0, h1; - - if (sprite.texture.trim) - { - // if the sprite is trimmed then we need to add the extra space before transforming the sprite coords.. - var trim = sprite.texture.trim; - - w1 = trim.x - aX * trim.width; - w0 = w1 + width; - - h1 = trim.y - aY * trim.height; - h0 = h1 + height; - } - else - { - w0 = (width ) * (1-aX); - w1 = (width ) * -aX; - - h0 = height * (1-aY); - h1 = height * -aY; - } - - var index = this.currentBatchSize * 4 * this.vertSize; - - var worldTransform = sprite.worldTransform;//.toArray(); - - var a = worldTransform.a;//[0]; - var b = worldTransform.c;//[3]; - var c = worldTransform.b;//[1]; - var d = worldTransform.d;//[4]; - var tx = worldTransform.tx;//[2]; - var ty = worldTransform.ty;///[5]; - - // xy - verticies[index++] = a * w1 + c * h1 + tx; - verticies[index++] = d * h1 + b * w1 + ty; - // uv - verticies[index++] = uvs.x0; - verticies[index++] = uvs.y0; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w0 + c * h1 + tx; - verticies[index++] = d * h1 + b * w0 + ty; - // uv - verticies[index++] = uvs.x1; - verticies[index++] = uvs.y1; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w0 + c * h0 + tx; - verticies[index++] = d * h0 + b * w0 + ty; - // uv - verticies[index++] = uvs.x2; - verticies[index++] = uvs.y2; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w1 + c * h0 + tx; - verticies[index++] = d * h0 + b * w1 + ty; - // uv - verticies[index++] = uvs.x3; - verticies[index++] = uvs.y3; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // increment the batchsize - this.currentBatchSize++; - - -}; - -/** -* Renders a tilingSprite using the spriteBatch -* @method renderTilingSprite -* -* @param sprite {TilingSprite} the tilingSprite to render -*/ -PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) -{ - var texture = tilingSprite.tilingTexture; - - if(texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) - { - this.flush(); - this.currentBaseTexture = texture.baseTexture; - } - - // check blend mode - if(tilingSprite.blendMode !== this.currentBlendMode) - { - this.setBlendMode(tilingSprite.blendMode); - } - - // set the textures uvs temporarily - // TODO create a separate texture so that we can tile part of a texture - - if(!tilingSprite._uvs)tilingSprite._uvs = new PIXI.TextureUvs(); - - var uvs = tilingSprite._uvs; - - tilingSprite.tilePosition.x %= texture.baseTexture.width; - tilingSprite.tilePosition.y %= texture.baseTexture.height; - - var offsetX = tilingSprite.tilePosition.x/texture.baseTexture.width; - var offsetY = tilingSprite.tilePosition.y/texture.baseTexture.height; - - var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x); - var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y); - - uvs.x0 = 0 - offsetX; - uvs.y0 = 0 - offsetY; - - uvs.x1 = (1 * scaleX) - offsetX; - uvs.y1 = 0 - offsetY; - - uvs.x2 = (1 * scaleX) - offsetX; - uvs.y2 = (1 * scaleY) - offsetY; - - uvs.x3 = 0 - offsetX; - uvs.y3 = (1 *scaleY) - offsetY; - - // get the tilingSprites current alpha - var alpha = tilingSprite.worldAlpha; - var tint = tilingSprite.tint; - - var verticies = this.vertices; - - var width = tilingSprite.width; - var height = tilingSprite.height; - - // TODO trim?? - var aX = tilingSprite.anchor.x; // - tilingSprite.texture.trim.x - var aY = tilingSprite.anchor.y; //- tilingSprite.texture.trim.y - var w0 = width * (1-aX); - var w1 = width * -aX; - - var h0 = height * (1-aY); - var h1 = height * -aY; - - var index = this.currentBatchSize * 4 * this.vertSize; - - var worldTransform = tilingSprite.worldTransform; - - var a = worldTransform.a;//[0]; - var b = worldTransform.c;//[3]; - var c = worldTransform.b;//[1]; - var d = worldTransform.d;//[4]; - var tx = worldTransform.tx;//[2]; - var ty = worldTransform.ty;///[5]; - - // xy - verticies[index++] = a * w1 + c * h1 + tx; - verticies[index++] = d * h1 + b * w1 + ty; - // uv - verticies[index++] = uvs.x0; - verticies[index++] = uvs.y0; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w0 + c * h1 + tx; - verticies[index++] = d * h1 + b * w0 + ty; - // uv - verticies[index++] = uvs.x1; - verticies[index++] = uvs.y1; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w0 + c * h0 + tx; - verticies[index++] = d * h0 + b * w0 + ty; - // uv - verticies[index++] = uvs.x2; - verticies[index++] = uvs.y2; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // xy - verticies[index++] = a * w1 + c * h0 + tx; - verticies[index++] = d * h0 + b * w1 + ty; - // uv - verticies[index++] = uvs.x3; - verticies[index++] = uvs.y3; - // color - verticies[index++] = alpha; - verticies[index++] = tint; - - // increment the batchs - this.currentBatchSize++; -}; - - -/** -* Renders the content and empties the current batch -* -* @method flush -* -*/ -PIXI.WebGLSpriteBatch.prototype.flush = function() -{ - // If the batch is length 0 then return as there is nothing to draw - if (this.currentBatchSize===0)return; - - var gl = this.gl; - - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.currentBaseTexture, gl)); - - // upload the verts to the buffer - - if(this.currentBatchSize > ( this.size * 0.5 ) ) - { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - } - else - { - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); - } - - // var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); - //gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); - - // now draw those suckas! - gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); - - // then reset the batch! - this.currentBatchSize = 0; - - // increment the draw count - this.renderSession.drawCount++; -}; - -/** -* -* @method stop -* -*/ -PIXI.WebGLSpriteBatch.prototype.stop = function() -{ - this.flush(); -}; - -/** -* -* @method start -* -*/ -PIXI.WebGLSpriteBatch.prototype.start = function() -{ - var gl = this.gl; - - // bind the main texture - gl.activeTexture(gl.TEXTURE0); - - // bind the buffers - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // set the projection - var projection = this.renderSession.projection; - gl.uniform2f(this.shader.projectionVector, projection.x, projection.y); - - // set the pointers - var stride = this.vertSize * 4; - gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); - gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(this.shader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); - - // set the blend mode.. - if(this.currentBlendMode !== PIXI.blendModes.NORMAL) - { - this.setBlendMode(PIXI.blendModes.NORMAL); - } -}; - -/** -* Sets-up the given blendMode from WebGL's point of view -* @method setBlendMode -* -* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD -*/ -PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) -{ - this.flush(); - - this.currentBlendMode = blendMode; - - var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; - this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); -}; - -/** -* Destroys the SpriteBatch -* @method destroy -*/ -PIXI.WebGLSpriteBatch.prototype.destroy = function() -{ - - this.vertices = null; - this.indices = null; - - this.gl.deleteBuffer( this.vertexBuffer ); - this.gl.deleteBuffer( this.indexBuffer ); - - this.currentBaseTexture = null; - - this.gl = null; -}; - - -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * - * Heavily inspired by LibGDX's WebGLSpriteBatch: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java - */ - -PIXI.WebGLFastSpriteBatch = function(gl) -{ - - - this.vertSize = 10; - this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize; - this.size = this.maxSize; - - //the total number of floats in our batch - var numVerts = this.size * 4 * this.vertSize; - //the total number of indices in our batch - var numIndices = this.maxSize * 6; - - //vertex data - this.vertices = new Float32Array(numVerts); - //index data - this.indices = new Uint16Array(numIndices); - - this.vertexBuffer = null; - this.indexBuffer = null; - - this.lastIndexCount = 0; - - for (var i=0, j=0; i < numIndices; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - this.drawing = false; - this.currentBatchSize = 0; - this.currentBaseTexture = null; - - this.currentBlendMode = 0; - this.renderSession = null; - - - this.shader = null; - - this.matrix = null; - - this.setContext(gl); -}; - -PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl) -{ - this.gl = gl; - - // create a couple of buffers - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // 65535 is max index, so 65535 / 6 = 10922. - - - //upload the index data - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); - - this.currentBlendMode = 99999; -}; - -PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession) -{ - this.renderSession = renderSession; - this.shader = this.renderSession.shaderManager.fastShader; - - this.matrix = spriteBatch.worldTransform.toArray(true); - - this.start(); -}; - -PIXI.WebGLFastSpriteBatch.prototype.end = function() -{ - this.flush(); -}; - - -PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) -{ - - var children = spriteBatch.children; - var sprite = children[0]; - - // if the uvs have not updated then no point rendering just yet! - - // check texture. - if(!sprite.texture._uvs)return; - - this.currentBaseTexture = sprite.texture.baseTexture; - // check blend mode - if(sprite.blendMode !== this.currentBlendMode) - { - this.setBlendMode(sprite.blendMode); - } - - for(var i=0,j= children.length; i= this.size) - { - this.flush(); - } -}; - -PIXI.WebGLFastSpriteBatch.prototype.flush = function() -{ - - // If the batch is length 0 then return as there is nothing to draw - if (this.currentBatchSize===0)return; - - var gl = this.gl; - - // bind the current texture - - if(!this.currentBaseTexture._glTextures[gl.id])PIXI.createWebGLTexture(this.currentBaseTexture, gl); - - gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]);// || PIXI.createWebGLTexture(this.currentBaseTexture, gl)); - - // upload the verts to the buffer - - - if(this.currentBatchSize > ( this.size * 0.5 ) ) - { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - } - else - { - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); - } - - - // now draw those suckas! - gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); - - // then reset the batch! - this.currentBatchSize = 0; - - // increment the draw count - this.renderSession.drawCount++; -}; - - -PIXI.WebGLFastSpriteBatch.prototype.stop = function() -{ - this.flush(); -}; - -PIXI.WebGLFastSpriteBatch.prototype.start = function() -{ - var gl = this.gl; - - // bind the main texture - gl.activeTexture(gl.TEXTURE0); - - // bind the buffers - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // set the projection - var projection = this.renderSession.projection; - gl.uniform2f(this.shader.projectionVector, projection.x, projection.y); - - // set the matrix - gl.uniformMatrix3fv(this.shader.uMatrix, false, this.matrix); - - // set the pointers - var stride = this.vertSize * 4; - - gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); - gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4); - gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4); - gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4); - gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4); - - // set the blend mode.. - if(this.currentBlendMode !== PIXI.blendModes.NORMAL) - { - this.setBlendMode(PIXI.blendModes.NORMAL); - } -}; - -PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode) -{ - this.flush(); - - this.currentBlendMode = blendMode; - - var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; - this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); -}; - - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLFilterManager -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -* @param transparent {Boolean} Whether or not the drawing context should be transparent -* @private -*/ -PIXI.WebGLFilterManager = function(gl, transparent) -{ - this.transparent = transparent; - - this.filterStack = []; - - this.offsetX = 0; - this.offsetY = 0; - - this.setContext(gl); -}; - -// API -/** -* Initialises the context and the properties -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLFilterManager.prototype.setContext = function(gl) -{ - this.gl = gl; - this.texturePool = []; - - this.initShaderBuffers(); -}; - -/** -* -* @method begin -* @param renderSession {RenderSession} -* @param buffer {ArrayBuffer} -*/ -PIXI.WebGLFilterManager.prototype.begin = function(renderSession, buffer) -{ - this.renderSession = renderSession; - this.defaultShader = renderSession.shaderManager.defaultShader; - - var projection = this.renderSession.projection; - - this.width = projection.x * 2; - this.height = -projection.y * 2; - this.buffer = buffer; -}; - -/** -* Applies the filter and adds it to the current filter stack -* @method pushFilter -* @param filterBlock {Object} the filter that will be pushed to the current filter stack -*/ -PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) -{ - var gl = this.gl; - - var projection = this.renderSession.projection; - var offset = this.renderSession.offset; - - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock.target.filterArea.x; - this.offsetY += filterBlock.target.filterArea.y; - - var texture = this.texturePool.pop(); - if(!texture) - { - texture = new PIXI.FilterTexture(this.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - filterBlock.target.filterArea = filterBlock.target.getBounds(); - - var filterArea = filterBlock.target.filterArea; - - var padidng = filter.padding; - filterArea.x -= padidng; - filterArea.y -= padidng; - filterArea.width += padidng * 2; - filterArea.height += padidng * 2; - - // cap filter to screen size.. - if(filterArea.x < 0)filterArea.x = 0; - if(filterArea.width > this.width)filterArea.width = this.width; - if(filterArea.y < 0)filterArea.y = 0; - if(filterArea.height > this.height)filterArea.height = this.height; - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - - -/** -* Removes the last filter from the filter stack and doesn't return it -* @method popFilter -*/ -PIXI.WebGLFilterManager.prototype.popFilter = function() -{ - var gl = this.gl; - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock.target.filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderSession.projection; - var offset = this.renderSession.offset; - - if(filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if(this.filterStack.length === 0) - { - gl.colorMask(true, true, true, this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter.target.filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - - - // TODO need toremove thease global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock.target.filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. - gl.useProgram(this.defaultShader.program); - gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** -* Applies the filter to the specified area -* @method applyFilterPass -* @param filter {AbstractFilter} the filter that needs to be applied -* @param filterArea {texture} TODO - might need an update -* @param width {Number} the horizontal range of the filter -* @param height {Number} the vertical range of the filter -*/ -PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height) -{ - // use program - var gl = this.gl; - var shader = filter.shaders[gl.id]; - - if(!shader) - { - shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if(filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.colorAttribute, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderSession.drawCount++; -}; - -/** -* Initialises the shader buffers -* @method initShaderBuffers -*/ -PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() -{ - var gl = this.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.vertexArray, - gl.STATIC_DRAW); - - - // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.uvArray, - gl.STATIC_DRAW); - - this.colorArray = new Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.colorArray, - gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData( - gl.ELEMENT_ARRAY_BUFFER, - new Uint16Array([0, 1, 2, 1, 3, 2]), - gl.STATIC_DRAW); -}; - -/** -* Destroys the filter and removes it from the filter stack -* @method destroy -*/ -PIXI.WebGLFilterManager.prototype.destroy = function() -{ - var gl = this.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) { - this.texturePool.destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); -}; -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class FilterTexture -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -* @param width {Number} the horizontal range of the filter -* @param height {Number} the vertical range of the filter -* @private -*/ -PIXI.FilterTexture = function(gl, width, height) -{ - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - // next time to create a frame buffer and texture - this.frameBuffer = gl.createFramebuffer(); - this.texture = gl.createTexture(); - - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); - - this.resize(width, height); -}; - - -/** -* Clears the filter texture -* @method clear -*/ -PIXI.FilterTexture.prototype.clear = function() -{ - var gl = this.gl; - - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); -}; - -/** - * Resizes the texture to the specified width and height - * - * @method resize - * @param width {Number} the new width of the texture - * @param height {Number} the new height of the texture - */ -PIXI.FilterTexture.prototype.resize = function(width, height) -{ - if(this.width === width && this.height === height) return; - - this.width = width; - this.height = height; - - var gl = this.gl; - - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - -}; - -/** -* Destroys the filter texture -* @method destroy -*/ -PIXI.FilterTexture.prototype.destroy = function() -{ - var gl = this.gl; - gl.deleteFramebuffer( this.frameBuffer ); - gl.deleteTexture( this.texture ); - - this.frameBuffer = null; - this.texture = null; -}; - -/** - * @author Mat Groves - * - * - */ -/** - * A set of functions used to handle masking - * - * @class CanvasMaskManager - */ -PIXI.CanvasMaskManager = function() -{ - -}; - -/** - * This method adds it to the current stack of masks - * - * @method pushMask - * @param maskData the maskData that will be pushed - * @param context {Context2D} the 2d drawing method of the canvas - */ -PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, context) -{ - context.save(); - - var cacheAlpha = maskData.alpha; - var transform = maskData.worldTransform; - - context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); - - PIXI.CanvasGraphics.renderGraphicsMask(maskData, context); - - context.clip(); - - maskData.worldAlpha = cacheAlpha; -}; - -/** - * Restores the current drawing context to the state it was before the mask was applied - * - * @method popMask - * @param context {Context2D} the 2d drawing method of the canvas - */ -PIXI.CanvasMaskManager.prototype.popMask = function(context) -{ - context.restore(); -}; - -/** - * @author Mat Groves - * - * - */ - -/** - * @class CanvasTinter - * @constructor - * @static - */ -PIXI.CanvasTinter = function() -{ - /// this.textureCach -}; - -//PIXI.CanvasTinter.cachTint = true; - - -/** - * Basically this method just needs a sprite and a color and tints the sprite - * with the given color - * - * @method getTintedTexture - * @param sprite {Sprite} the sprite to tint - * @param color {Number} the color to use to tint the sprite with - */ -PIXI.CanvasTinter.getTintedTexture = function(sprite, color) -{ - - var texture = sprite.texture; - - color = PIXI.CanvasTinter.roundColor(color); - - var stringColor = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - - texture.tintCache = texture.tintCache || {}; - - if(texture.tintCache[stringColor]) return texture.tintCache[stringColor]; - - // clone texture.. - var canvas = PIXI.CanvasTinter.canvas || document.createElement("canvas"); - - //PIXI.CanvasTinter.tintWithPerPixel(texture, stringColor, canvas); - - - PIXI.CanvasTinter.tintMethod(texture, color, canvas); - - if(PIXI.CanvasTinter.convertTintToImage) - { - // is this better? - var tintImage = new Image(); - tintImage.src = canvas.toDataURL(); - - texture.tintCache[stringColor] = tintImage; - } - else - { - - texture.tintCache[stringColor] = canvas; - // if we are not converting the texture to an image then we need to lose the reference to the canvas - PIXI.CanvasTinter.canvas = null; - - } - - return canvas; -}; - -/** - * Tint a texture using the "multiply" operation - * @method tintWithMultiply - * @param texture {texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithMultiply = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var frame = texture.frame; - - canvas.width = frame.width; - canvas.height = frame.height; - - context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - - context.fillRect(0, 0, frame.width, frame.height); - - context.globalCompositeOperation = "multiply"; - - context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - frame.width, - frame.height); - - context.globalCompositeOperation = "destination-atop"; - - context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - frame.width, - frame.height); -}; - -/** - * Tint a texture using the "overlay" operation - * @method tintWithOverlay - * @param texture {texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithOverlay = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var frame = texture.frame; - - canvas.width = frame.width; - canvas.height = frame.height; - - - - context.globalCompositeOperation = "copy"; - context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - context.fillRect(0, 0, frame.width, frame.height); - - context.globalCompositeOperation = "destination-atop"; - context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - frame.width, - frame.height); - - - //context.globalCompositeOperation = "copy"; - -}; - -/** - * Tint a texture pixel per pixel - * @method tintPerPixel - * @param texture {texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var frame = texture.frame; - - canvas.width = frame.width; - canvas.height = frame.height; - - context.globalCompositeOperation = "copy"; - context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - frame.width, - frame.height); - - var rgbValues = PIXI.hex2rgb(color); - var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2]; - - var pixelData = context.getImageData(0, 0, frame.width, frame.height); - - var pixels = pixelData.data; - - for (var i = 0; i < pixels.length; i += 4) - { - pixels[i+0] *= r; - pixels[i+1] *= g; - pixels[i+2] *= b; - } - - context.putImageData(pixelData, 0, 0); -}; - -/** - * Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel - * @method roundColor - * @param color {number} the color to round, should be a hex color - */ -PIXI.CanvasTinter.roundColor = function(color) -{ - var step = PIXI.CanvasTinter.cacheStepsPerColorChannel; - - var rgbValues = PIXI.hex2rgb(color); - - rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step); - rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step); - rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step); - - return PIXI.rgb2hex(rgbValues); -}; - -/** - * - * Number of steps which will be used as a cap when rounding colors - * - * @property cacheStepsPerColorChannel - * @type Number - */ -PIXI.CanvasTinter.cacheStepsPerColorChannel = 8; -/** - * - * Number of steps which will be used as a cap when rounding colors - * - * @property convertTintToImage - * @type Boolean - */ -PIXI.CanvasTinter.convertTintToImage = false; - -/** - * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method - * - * @property canUseMultiply - * @type Boolean - */ -PIXI.CanvasTinter.canUseMultiply = PIXI.canUseNewCanvasBlendModes(); - -PIXI.CanvasTinter.tintMethod = PIXI.CanvasTinter.canUseMultiply ? PIXI.CanvasTinter.tintWithMultiply : PIXI.CanvasTinter.tintWithPerPixel; - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. - * Dont forget to add the view to your DOM or you will not see anything :) - * - * @class CanvasRenderer - * @constructor - * @param width=800 {Number} the width of the canvas view - * @param height=600 {Number} the height of the canvas view - * @param [view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [transparent=false] {Boolean} the transparency of the render view, default false - */ -PIXI.CanvasRenderer = function(width, height, view, transparent) -{ - PIXI.defaultRenderer = PIXI.defaultRenderer || this; - - this.type = PIXI.CANVAS_RENDERER; - - /** - * This sets if the CanvasRenderer will clear the canvas or not before the new render pass. - * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color. - * If the Stage is transparent Pixi will use clearRect to clear the canvas every frame. - * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set. - * - * @property clearBeforeRender - * @type Boolean - * @default - */ - this.clearBeforeRender = true; - - /** - * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. - * Handy for crisp pixel art and speed on legacy devices. - * - * @property roundPixels - * @type Boolean - * @default - */ - this.roundPixels = false; - - /** - * Whether the render view is transparent - * - * @property transparent - * @type Boolean - */ - this.transparent = !!transparent; - - if(!PIXI.blendModesCanvas) - { - PIXI.blendModesCanvas = []; - - if(PIXI.canUseNewCanvasBlendModes()) - { - PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? - PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; - PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; - PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "overlay"; - PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "darken"; - PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "lighten"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn"; - PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light"; - PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light"; - PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference"; - PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion"; - PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "hue"; - PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "color"; - PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity"; - } - else - { - // this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough" - PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? - PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over"; - } - } - - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; - - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; - - /** - * The canvas element that everything is drawn to - * - * @property view - * @type HTMLCanvasElement - */ - this.view = view || document.createElement( "canvas" ); - - /** - * The canvas 2d context that everything is drawn with - * @property context - * @type HTMLCanvasElement 2d Context - */ - this.context = this.view.getContext( "2d", { alpha: this.transparent } ); - - this.refresh = true; - // hack to enable some hardware acceleration! - //this.view.style["transform"] = "translatez(0)"; - - this.view.width = this.width; - this.view.height = this.height; - this.count = 0; - - /** - * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer - * @property CanvasMaskManager - * @type CanvasMaskManager - */ - this.maskManager = new PIXI.CanvasMaskManager(); - - /** - * The render session is just a bunch of parameter used for rendering - * @property renderSession - * @type Object - */ - this.renderSession = { - context: this.context, - maskManager: this.maskManager, - scaleMode: null, - smoothProperty: null - }; - - if("imageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "imageSmoothingEnabled"; - else if("webkitImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "webkitImageSmoothingEnabled"; - else if("mozImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "mozImageSmoothingEnabled"; - else if("oImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "oImageSmoothingEnabled"; -}; - -// constructor -PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; - -/** - * Renders the stage to its canvas view - * - * @method render - * @param stage {Stage} the Stage element to be rendered - */ -PIXI.CanvasRenderer.prototype.render = function(stage) -{ - // update textures if need be - PIXI.texturesToUpdate.length = 0; - PIXI.texturesToDestroy.length = 0; - - stage.updateTransform(); - - this.context.setTransform(1,0,0,1,0,0); - this.context.globalAlpha = 1; - - if (!this.transparent && this.clearBeforeRender) - { - this.context.fillStyle = stage.backgroundColorString; - this.context.fillRect(0, 0, this.width, this.height); - } - else if (this.transparent && this.clearBeforeRender) - { - this.context.clearRect(0, 0, this.width, this.height); - } - - this.renderDisplayObject(stage); - - // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - - // remove frame updates.. - if(PIXI.Texture.frameUpdates.length > 0) - { - PIXI.Texture.frameUpdates.length = 0; - } -}; - -/** - * Resizes the canvas view to the specified width and height - * - * @method resize - * @param width {Number} the new width of the canvas view - * @param height {Number} the new height of the canvas view - */ -PIXI.CanvasRenderer.prototype.resize = function(width, height) -{ - this.width = width; - this.height = height; - - this.view.width = width; - this.view.height = height; -}; - -/** - * Renders a display object - * - * @method renderDisplayObject - * @param displayObject {DisplayObject} The displayObject to render - * @param context {Context2D} the context 2d method of the canvas - * @private - */ -PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context) -{ - // no longer recursive! - //var transform; - //var context = this.context; - - this.renderSession.context = context || this.context; - displayObject._renderCanvas(this.renderSession); -}; - -/** - * Renders a flat strip - * - * @method renderStripFlat - * @param strip {Strip} The Strip to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) -{ - var context = this.context; - var verticies = strip.verticies; - - var length = verticies.length/2; - this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - } - - context.fillStyle = "#FF0000"; - context.fill(); - context.closePath(); -}; - -/** - * Renders a strip - * - * @method renderStrip - * @param strip {Strip} The Strip to render - * @private - */ -PIXI.CanvasRenderer.prototype.renderStrip = function(strip) -{ - var context = this.context; - - // draw triangles!! - var verticies = strip.verticies; - var uvs = strip.uvs; - - var length = verticies.length/2; - this.count++; - - for (var i = 1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; - var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; - - context.save(); - context.beginPath(); - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - context.closePath(); - - context.clip(); - - // Compute matrix transform - var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; - var deltaA = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; - var deltaB = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; - var deltaC = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; - var deltaD = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; - var deltaE = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; - var deltaF = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; - - context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); - - context.drawImage(strip.texture.baseTexture.source, 0, 0); - context.restore(); - } -}; - -/** - * Creates a Canvas element of the given size - * - * @method CanvasBuffer - * @param width {Number} the width for the newly created canvas - * @param height {Number} the height for the newly created canvas - * @static - * @private - */ -PIXI.CanvasBuffer = function(width, height) -{ - this.width = width; - this.height = height; - - this.canvas = document.createElement( "canvas" ); - this.context = this.canvas.getContext( "2d" ); - - this.canvas.width = width; - this.canvas.height = height; -}; - -/** - * Clears the canvas that was created by the CanvasBuffer class - * - * @method clear - * @private - */ -PIXI.CanvasBuffer.prototype.clear = function() -{ - this.context.clearRect(0,0, this.width, this.height); -}; - -/** - * Resizes the canvas that was created by the CanvasBuffer class to the specified width and height - * - * @method resize - * @param width {Number} the new width of the canvas - * @param height {Number} the new height of the canvas - * @private - */ - -PIXI.CanvasBuffer.prototype.resize = function(width, height) -{ - this.width = this.canvas.width = width; - this.height = this.canvas.height = height; -}; - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * A set of functions used by the canvas renderer to draw the primitive graphics data - * - * @class CanvasGraphics - */ -PIXI.CanvasGraphics = function() -{ - -}; - - -/* - * Renders the graphics object - * - * @static - * @private - * @method renderGraphics - * @param graphics {Graphics} the actual graphics object to render - * @param context {Context2D} the 2d drawing method of the canvas - */ -PIXI.CanvasGraphics.renderGraphics = function(graphics, context) -{ - var worldAlpha = graphics.worldAlpha; - var color = ''; - - for (var i = 0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; - - context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); - - context.lineWidth = data.lineWidth; - - if(data.type === PIXI.Graphics.POLY) - { - context.beginPath(); - - context.moveTo(points[0], points[1]); - - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } - - // if the first and last point are the same close the path - much neater :) - if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) - { - context.closePath(); - } - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type === PIXI.Graphics.RECT) - { - - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fillRect(points[0], points[1], points[2], points[3]); - - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeRect(points[0], points[1], points[2], points[3]); - } - - } - else if(data.type === PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type === PIXI.Graphics.ELIP) - { - - // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - - var ellipseData = data.points; - - var w = ellipseData[2] * 2; - var h = ellipseData[3] * 2; - - var x = ellipseData[0] - w/2; - var y = ellipseData[1] - h/2; - - context.beginPath(); - - var kappa = 0.5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle - - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - - context.closePath(); - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - } -}; - -/* - * Renders a graphics mask - * - * @static - * @private - * @method renderGraphicsMask - * @param graphics {Graphics} the graphics which will be used as a mask - * @param context {Context2D} the context 2d method of the canvas - */ -PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) -{ - var len = graphics.graphicsData.length; - - if(len === 0) return; - - if(len > 1) - { - len = 1; - window.console.log('Pixi.js warning: masks in canvas can only mask using the first path in the graphics object'); - } - - for (var i = 0; i < 1; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; - - if(data.type === PIXI.Graphics.POLY) - { - context.beginPath(); - context.moveTo(points[0], points[1]); - - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } - - // if the first and last point are the same close the path - much neater :) - if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) - { - context.closePath(); - } - - } - else if(data.type === PIXI.Graphics.RECT) - { - context.beginPath(); - context.rect(points[0], points[1], points[2], points[3]); - context.closePath(); - } - else if(data.type === PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); - } - else if(data.type === PIXI.Graphics.ELIP) - { - - // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var ellipseData = data.points; - - var w = ellipseData[2] * 2; - var h = ellipseData[3] * 2; - - var x = ellipseData[0] - w/2; - var y = ellipseData[1] - h/2; - - context.beginPath(); - - var kappa = 0.5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle - - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); - } - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * The Graphics class contains a set of methods that you can use to create primitive shapes and lines. - * It is important to know that with the webGL renderer only simple polygons can be filled at this stage - * Complex polygons will not be filled. Heres an example of a complex polygon: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png - * - * @class Graphics - * @extends DisplayObjectContainer - * @constructor - */ -PIXI.Graphics = function() -{ - PIXI.DisplayObjectContainer.call( this ); - - this.renderable = true; - - /** - * The alpha of the fill of this graphics object - * - * @property fillAlpha - * @type Number - */ - this.fillAlpha = 1; - - /** - * The width of any lines drawn - * - * @property lineWidth - * @type Number - */ - this.lineWidth = 0; - - /** - * The color of any lines drawn - * - * @property lineColor - * @type String - */ - this.lineColor = "black"; - - /** - * Graphics data - * - * @property graphicsData - * @type Array - * @private - */ - this.graphicsData = []; - - - /** - * The tint applied to the graphic shape. This is a hex value - * - * @property tint - * @type Number - * @default 0xFFFFFF - */ - this.tint = 0xFFFFFF;// * Math.random(); - - /** - * The blend mode to be applied to the graphic shape - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; - - /** - * Current path - * - * @property currentPath - * @type Object - * @private - */ - this.currentPath = {points:[]}; - - /** - * Array containing some WebGL-related properties used by the WebGL renderer - * - * @property _webGL - * @type Array - * @private - */ - this._webGL = []; - - /** - * Whether this shape is being used as a mask - * - * @property isMask - * @type isMask - */ - this.isMask = false; - - /** - * The bounds of the graphic shape as rectangle object - * - * @property bounds - * @type Rectangle - */ - this.bounds = null; - - /** - * the bounds' padding used for bounds calculation - * - * @property bounds - * @type Number - */ - this.boundsPadding = 10; -}; - -// constructor -PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); -PIXI.Graphics.prototype.constructor = PIXI.Graphics; - -/** - * If cacheAsBitmap is true the graphics object will then be rendered as if it was a sprite. - * This is useful if your graphics element does not change often as it will speed up the rendering of the object - * It is also usful as the graphics object will always be antialiased because it will be rendered using canvas - * Not recommended if you are constanly redrawing the graphics element. - * - * @property cacheAsBitmap - * @default false - * @type Boolean - * @private - */ -Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", { - get: function() { - return this._cacheAsBitmap; - }, - set: function(value) { - this._cacheAsBitmap = value; - - if(this._cacheAsBitmap) - { - this._generateCachedSprite(); - } - else - { - this.destroyCachedSprite(); - this.dirty = true; - } - - } -}); - - -/** - * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method. - * - * @method lineStyle - * @param lineWidth {Number} width of the line to draw, will update the object's stored style - * @param color {Number} color of the line to draw, will update the object's stored style - * @param alpha {Number} alpha of the line to draw, will update the object's stored style - */ -PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) -{ - if (!this.currentPath.points.length) this.graphicsData.pop(); - - this.lineWidth = lineWidth || 0; - this.lineColor = color || 0; - this.lineAlpha = (arguments.length < 3) ? 1 : alpha; - - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - - this.graphicsData.push(this.currentPath); - - return this; -}; - -/** - * Moves the current drawing position to (x, y). - * - * @method moveTo - * @param x {Number} the X coordinate to move to - * @param y {Number} the Y coordinate to move to - */ -PIXI.Graphics.prototype.moveTo = function(x, y) -{ - if (!this.currentPath.points.length) this.graphicsData.pop(); - - this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - - this.currentPath.points.push(x, y); - - this.graphicsData.push(this.currentPath); - - return this; -}; - -/** - * Draws a line using the current line style from the current drawing position to (x, y); - * the current drawing position is then set to (x, y). - * - * @method lineTo - * @param x {Number} the X coordinate to draw to - * @param y {Number} the Y coordinate to draw to - */ -PIXI.Graphics.prototype.lineTo = function(x, y) -{ - this.currentPath.points.push(x, y); - this.dirty = true; - - return this; -}; - -/** - * Specifies a simple one-color fill that subsequent calls to other Graphics methods - * (such as lineTo() or drawCircle()) use when drawing. - * - * @method beginFill - * @param color {Number} the color of the fill - * @param alpha {Number} the alpha of the fill - */ -PIXI.Graphics.prototype.beginFill = function(color, alpha) -{ - - this.filling = true; - this.fillColor = color || 0; - this.fillAlpha = (arguments.length < 2) ? 1 : alpha; - - return this; -}; - -/** - * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. - * - * @method endFill - */ -PIXI.Graphics.prototype.endFill = function() -{ - this.filling = false; - this.fillColor = null; - this.fillAlpha = 1; - - return this; -}; - -/** - * @method drawRect - * - * @param x {Number} The X coord of the top-left of the rectangle - * @param y {Number} The Y coord of the top-left of the rectangle - * @param width {Number} The width of the rectangle - * @param height {Number} The height of the rectangle - */ -PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) -{ - if (!this.currentPath.points.length) this.graphicsData.pop(); - - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.RECT}; - - this.graphicsData.push(this.currentPath); - this.dirty = true; - - return this; -}; - -/** - * Draws a circle. - * - * @method drawCircle - * @param x {Number} The X coordinate of the center of the circle - * @param y {Number} The Y coordinate of the center of the circle - * @param radius {Number} The radius of the circle - */ -PIXI.Graphics.prototype.drawCircle = function( x, y, radius) -{ - - if (!this.currentPath.points.length) this.graphicsData.pop(); - - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; - - this.graphicsData.push(this.currentPath); - this.dirty = true; - - return this; -}; - -/** - * Draws an ellipse. - * - * @method drawEllipse - * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse - * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse - * @param width {Number} The width of the ellipse - * @param height {Number} The height of the ellipse - */ -PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height) -{ - - if (!this.currentPath.points.length) this.graphicsData.pop(); - - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.ELIP}; - - this.graphicsData.push(this.currentPath); - this.dirty = true; - - return this; -}; - -/** - * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. - * - * @method clear - */ -PIXI.Graphics.prototype.clear = function() -{ - this.lineWidth = 0; - this.filling = false; - - this.dirty = true; - this.clearDirty = true; - this.graphicsData = []; - - this.bounds = null; //new PIXI.Rectangle(); - - return this; -}; - -/** - * Useful function that returns a texture of the graphics object that can then be used to create sprites - * This can be quite useful if your geometry is complicated and needs to be reused multiple times. - * - * @method generateTexture - * @return {Texture} a texture of the graphics object - */ -PIXI.Graphics.prototype.generateTexture = function() -{ - var bounds = this.getBounds(); - - var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height); - var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); - - canvasBuffer.context.translate(-bounds.x,-bounds.y); - - PIXI.CanvasGraphics.renderGraphics(this, canvasBuffer.context); - - return texture; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Graphics.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(this.visible === false || this.alpha === 0 || this.isMask === true)return; - - if(this._cacheAsBitmap) - { - - if(this.dirty) - { - this._generateCachedSprite(); - // we will also need to update the texture on the gpu too! - PIXI.updateWebGLTexture(this._cachedSprite.texture.baseTexture, renderSession.gl); - - this.dirty = false; - } - - PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession); - - return; - } - else - { - renderSession.spriteBatch.stop(); - - if(this._mask)renderSession.maskManager.pushMask(this.mask, renderSession); - if(this._filters)renderSession.filterManager.pushFilter(this._filterBlock); - - // check blend mode - if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) - { - renderSession.spriteBatch.currentBlendMode = this.blendMode; - var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; - renderSession.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); - } - - PIXI.WebGLGraphics.renderGraphics(this, renderSession); - - // only render if it has children! - if(this.children.length) - { - renderSession.spriteBatch.start(); - - // simple render children! - for(var i=0, j=this.children.length; i maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - return bounds; -}; - -/** - * Update the bounds of the object - * - * @method updateBounds - */ -PIXI.Graphics.prototype.updateBounds = function() -{ - - var minX = Infinity; - var maxX = -Infinity; - - var minY = Infinity; - var maxY = -Infinity; - - var points, x, y, w, h; - - for (var i = 0; i < this.graphicsData.length; i++) { - var data = this.graphicsData[i]; - var type = data.type; - var lineWidth = data.lineWidth; - - points = data.points; - - if(type === PIXI.Graphics.RECT) - { - x = points[0] - lineWidth/2; - y = points[1] - lineWidth/2; - w = points[2] + lineWidth; - h = points[3] + lineWidth; - - minX = x < minX ? x : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y < minY ? x : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) - { - x = points[0]; - y = points[1]; - w = points[2] + lineWidth/2; - h = points[3] + lineWidth/2; - - minX = x - w < minX ? x - w : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y - h < minY ? y - h : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else - { - // POLY - for (var j = 0; j < points.length; j+=2) - { - - x = points[j]; - y = points[j+1]; - minX = x-lineWidth < minX ? x-lineWidth : minX; - maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - - minY = y-lineWidth < minY ? y-lineWidth : minY; - maxY = y+lineWidth > maxY ? y+lineWidth : maxY; - } - } - } - - var padding = this.boundsPadding; - this.bounds = new PIXI.Rectangle(minX - padding, minY - padding, (maxX - minX) + padding * 2, (maxY - minY) + padding * 2); -}; - - -/** - * Generates the cached sprite when the sprite has cacheAsBitmap = true - * - * @method _generateCachedSprite - * @private - */ -PIXI.Graphics.prototype._generateCachedSprite = function() -{ - var bounds = this.getLocalBounds(); - - if(!this._cachedSprite) - { - var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height); - var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); - - this._cachedSprite = new PIXI.Sprite(texture); - this._cachedSprite.buffer = canvasBuffer; - - this._cachedSprite.worldTransform = this.worldTransform; - } - else - { - this._cachedSprite.buffer.resize(bounds.width, bounds.height); - } - - // leverage the anchor to account for the offset of the element - this._cachedSprite.anchor.x = -( bounds.x / bounds.width ); - this._cachedSprite.anchor.y = -( bounds.y / bounds.height ); - - // this._cachedSprite.buffer.context.save(); - this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y); - - PIXI.CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context); - // this._cachedSprite.buffer.context.restore(); -}; - -PIXI.Graphics.prototype.destroyCachedSprite = function() -{ - this._cachedSprite.texture.destroy(true); - - // let the gc collect the unused sprite - // TODO could be object pooled! - this._cachedSprite = null; -}; - - -// SOME TYPES: -PIXI.Graphics.POLY = 0; -PIXI.Graphics.RECT = 1; -PIXI.Graphics.CIRC = 2; -PIXI.Graphics.ELIP = 3; - -/** - * @author Mat Groves http://matgroves.com/ - */ - - /** - * - * @class Strip - * @extends DisplayObjectContainer - * @constructor - * @param texture {Texture} The texture to use - * @param width {Number} the width - * @param height {Number} the height - * - */ -PIXI.Strip = function(texture, width, height) -{ - PIXI.DisplayObjectContainer.call( this ); - this.texture = texture; - this.blendMode = PIXI.blendModes.NORMAL; - - try - { - this.uvs = new Float32Array([0, 1, - 1, 1, - 1, 0, 0,1]); - - this.verticies = new Float32Array([0, 0, - 0,0, - 0,0, 0, - 0, 0]); - - this.colors = new Float32Array([1, 1, 1, 1]); - - this.indices = new Uint16Array([0, 1, 2, 3]); - } - catch(error) - { - this.uvs = [0, 1, - 1, 1, - 1, 0, 0,1]; - - this.verticies = [0, 0, - 0,0, - 0,0, 0, - 0, 0]; - - this.colors = [1, 1, 1, 1]; - - this.indices = [0, 1, 2, 3]; - } - - - /* - this.uvs = new Float32Array() - this.verticies = new Float32Array() - this.colors = new Float32Array() - this.indices = new Uint16Array() - */ - - this.width = width; - this.height = height; - - // load the texture! - if(texture.baseTexture.hasLoaded) - { - this.width = this.texture.frame.width; - this.height = this.texture.frame.height; - this.updateFrame = true; - } - else - { - this.onTextureUpdateBind = this.onTextureUpdate.bind(this); - this.texture.addEventListener( 'update', this.onTextureUpdateBind ); - } - - this.renderable = true; -}; - -// constructor -PIXI.Strip.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); -PIXI.Strip.prototype.constructor = PIXI.Strip; - -/* - * Sets the texture that the Strip will use - * - * @method setTexture - * @param texture {Texture} the texture that will be used - * @private - */ -PIXI.Strip.prototype.setTexture = function(texture) -{ - //TODO SET THE TEXTURES - //TODO VISIBILITY - - // stop current texture - this.texture = texture; - this.width = texture.frame.width; - this.height = texture.frame.height; - this.updateFrame = true; -}; - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @method onTextureUpdate - * @param event - * @private - */ -PIXI.Strip.prototype.onTextureUpdate = function() -{ - this.updateFrame = true; -}; -/* @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * - * @class Rope - * @constructor - * @param texture {Texture} The texture to use - * @param points {Array} - * - */ -PIXI.Rope = function(texture, points) -{ - PIXI.Strip.call( this, texture ); - this.points = points; - - try - { - this.verticies = new Float32Array(points.length * 4); - this.uvs = new Float32Array(points.length * 4); - this.colors = new Float32Array(points.length * 2); - this.indices = new Uint16Array(points.length * 2); - } - catch(error) - { - this.verticies = new Array(points.length * 4); - this.uvs = new Array(points.length * 4); - this.colors = new Array(points.length * 2); - this.indices = new Array(points.length * 2); - } - - this.refresh(); -}; - - -// constructor -PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype ); -PIXI.Rope.prototype.constructor = PIXI.Rope; - -/* - * Refreshes - * - * @method refresh - */ -PIXI.Rope.prototype.refresh = function() -{ - var points = this.points; - if(points.length < 1) return; - - var uvs = this.uvs; - - var lastPoint = points[0]; - var indices = this.indices; - var colors = this.colors; - - this.count-=0.2; - - - uvs[0] = 0; - uvs[1] = 1; - uvs[2] = 0; - uvs[3] = 1; - - colors[0] = 1; - colors[1] = 1; - - indices[0] = 0; - indices[1] = 1; - - var total = points.length, - point, index, amount; - - for (var i = 1; i < total; i++) - { - - point = points[i]; - index = i * 4; - // time to do some smart drawing! - amount = i / (total-1); - - if(i%2) - { - uvs[index] = amount; - uvs[index+1] = 0; - - uvs[index+2] = amount; - uvs[index+3] = 1; - - } - else - { - uvs[index] = amount; - uvs[index+1] = 0; - - uvs[index+2] = amount; - uvs[index+3] = 1; - } - - index = i * 2; - colors[index] = 1; - colors[index+1] = 1; - - index = i * 2; - indices[index] = index; - indices[index + 1] = index + 1; - - lastPoint = point; - } -}; - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.Rope.prototype.updateTransform = function() -{ - - var points = this.points; - if(points.length < 1)return; - - var lastPoint = points[0]; - var nextPoint; - var perp = {x:0, y:0}; - - this.count-=0.2; - - var verticies = this.verticies; - verticies[0] = lastPoint.x + perp.x; - verticies[1] = lastPoint.y + perp.y; //+ 200 - verticies[2] = lastPoint.x - perp.x; - verticies[3] = lastPoint.y - perp.y;//+200 - // time to do some smart drawing! - - var total = points.length, - point, index, ratio, perpLength, num; - - for (var i = 1; i < total; i++) - { - point = points[i]; - index = i * 4; - - if(i < points.length-1) - { - nextPoint = points[i+1]; - } - else - { - nextPoint = point; - } - - perp.y = -(nextPoint.x - lastPoint.x); - perp.x = nextPoint.y - lastPoint.y; - - ratio = (1 - (i / (total-1))) * 10; - - if(ratio > 1) ratio = 1; - - perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); - num = this.texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; - perp.x /= perpLength; - perp.y /= perpLength; - - perp.x *= num; - perp.y *= num; - - verticies[index] = point.x + perp.x; - verticies[index+1] = point.y + perp.y; - verticies[index+2] = point.x - perp.x; - verticies[index+3] = point.y - perp.y; - - lastPoint = point; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); -}; -/* - * Sets the texture that the Rope will use - * - * @method setTexture - * @param texture {Texture} the texture that will be used - */ -PIXI.Rope.prototype.setTexture = function(texture) -{ - // stop current texture - this.texture = texture; - this.updateFrame = true; -}; - -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * A tiling sprite is a fast way of rendering a tiling image - * - * @class TilingSprite - * @extends DisplayObjectContainer - * @constructor - * @param texture {Texture} the texture of the tiling sprite - * @param width {Number} the width of the tiling sprite - * @param height {Number} the height of the tiling sprite - */ -PIXI.TilingSprite = function(texture, width, height) -{ - PIXI.Sprite.call( this, texture); - - /** - * The with of the tiling sprite - * - * @property width - * @type Number - */ - this.width = width || 100; - /** - * The height of the tiling sprite - * - * @property height - * @type Number - */ - this.height = height || 100; - - /** - * The scaling of the image that is being tiled - * - * @property tileScale - * @type Point - */ - this.tileScale = new PIXI.Point(1,1); - - /** - * A point that represents the scale of the texture object - * - * @property tileScaleOffset - * @type Point - */ - this.tileScaleOffset = new PIXI.Point(1,1); - - /** - * The offset position of the image that is being tiled - * - * @property tilePosition - * @type Point - */ - this.tilePosition = new PIXI.Point(0,0); - - - /** - * Whether this sprite is renderable or not - * - * @property renderable - * @type Boolean - * @default true - */ - this.renderable = true; - - /** - * The tint applied to the sprite. This is a hex value - * - * @property tint - * @type Number - * @default 0xFFFFFF - */ - this.tint = 0xFFFFFF; - - /** - * The blend mode to be applied to the sprite - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; -}; - -// constructor -PIXI.TilingSprite.prototype = Object.create(PIXI.Sprite.prototype); -PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite; - - -/** - * The width of the sprite, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.TilingSprite.prototype, 'width', { - get: function() { - return this._width; - }, - set: function(value) { - - this._width = value; - } -}); - -/** - * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.TilingSprite.prototype, 'height', { - get: function() { - return this._height; - }, - set: function(value) { - this._height = value; - } -}); - -/** - * When the texture is updated, this event will be fired to update the scale and frame - * - * @method onTextureUpdate - * @param event - * @private - */ -PIXI.TilingSprite.prototype.onTextureUpdate = function() -{ - this.updateFrame = true; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.TilingSprite.prototype._renderWebGL = function(renderSession) -{ - - if(this.visible === false || this.alpha === 0)return; - - var i,j; - - if(this.mask || this.filters) - { - if(this.mask) - { - renderSession.spriteBatch.stop(); - renderSession.maskManager.pushMask(this.mask, renderSession); - renderSession.spriteBatch.start(); - } - - if(this.filters) - { - renderSession.spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - - if(!this.tilingTexture)this.generateTilingTexture(true); - else renderSession.spriteBatch.renderTilingSprite(this); - - // simple render children! - for(i=0,j=this.children.length; i maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** -* -* @method generateTilingTexture -* -* @param forcePowerOfTwo {Boolean} Whether we want to force the texture to be a power of two -*/ -PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo) -{ - var texture = this.texture; - - if(!texture.baseTexture.hasLoaded)return; - - var baseTexture = texture.baseTexture; - var frame = texture.frame; - - var targetWidth, targetHeight; - - // check that the frame is the same size as the base texture. - - var isFrame = frame.width !== baseTexture.width || frame.height !== baseTexture.height; - - this.tilingTexture = texture; - - var newTextureRequired = false; - - if(!forcePowerOfTwo) - { - if(isFrame) - { - targetWidth = frame.width; - targetHeight = frame.height; - - newTextureRequired = true; - } - } - else - { - targetWidth = PIXI.getNextPowerOfTwo(texture.frame.width); - targetHeight = PIXI.getNextPowerOfTwo(texture.frame.height); - - if(frame.width !== targetWidth && frame.height !== targetHeight)newTextureRequired = true; - } - - if(newTextureRequired) - { - var canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight); - - canvasBuffer.context.drawImage(texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - 0, - 0, - targetWidth, - targetHeight); - - this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); - - this.tileScaleOffset.x = frame.width / targetWidth; - this.tileScaleOffset.y = frame.height / targetHeight; - } - - - this.tilingTexture.baseTexture._powerOf2 = true; -}; -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi - * - * Awesome JS run time provided by EsotericSoftware - * https://github.com/EsotericSoftware/spine-runtimes - * - */ - -/* - * Awesome JS run time provided by EsotericSoftware - * - * https://github.com/EsotericSoftware/spine-runtimes - * - */ - - - -var spine = {}; - -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 -}; - -spine.SlotData = function (name, boneData) { - this.name = name; - this.boneData = boneData; -}; -spine.SlotData.prototype = { - r: 1, g: 1, b: 1, a: 1, - attachmentName: null -}; - -spine.Bone = function (boneData, parent) { - this.data = boneData; - this.parent = parent; - this.setToSetupPose(); -}; -spine.Bone.yDown = false; -spine.Bone.prototype = { - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - m00: 0, m01: 0, worldX: 0, // a b x - m10: 0, m11: 0, worldY: 0, // c d y - worldRotation: 0, - worldScaleX: 1, worldScaleY: 1, - updateWorldTransform: function (flipX, flipY) { - var parent = this.parent; - if (parent != null) { - this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX; - this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY; - this.worldScaleX = parent.worldScaleX * this.scaleX; - this.worldScaleY = parent.worldScaleY * this.scaleY; - this.worldRotation = parent.worldRotation + this.rotation; - } else { - this.worldX = this.x; - this.worldY = this.y; - this.worldScaleX = this.scaleX; - this.worldScaleY = this.scaleY; - this.worldRotation = this.rotation; - } - var radians = this.worldRotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - this.m00 = cos * this.worldScaleX; - this.m10 = sin * this.worldScaleX; - this.m01 = -sin * this.worldScaleY; - this.m11 = cos * this.worldScaleY; - if (flipX) { - this.m00 = -this.m00; - this.m01 = -this.m01; - } - if (flipY) { - this.m10 = -this.m10; - this.m11 = -this.m11; - } - if (spine.Bone.yDown) { - this.m10 = -this.m10; - this.m11 = -this.m11; - } - }, - setToSetupPose: function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - } -}; - -spine.Slot = function (slotData, skeleton, bone) { - this.data = slotData; - this.skeleton = skeleton; - this.bone = bone; - this.setToSetupPose(); -}; -spine.Slot.prototype = { - r: 1, g: 1, b: 1, a: 1, - _attachmentTime: 0, - attachment: null, - setAttachment: function (attachment) { - this.attachment = attachment; - this._attachmentTime = this.skeleton.time; - }, - setAttachmentTime: function (time) { - this._attachmentTime = this.skeleton.time - time; - }, - getAttachmentTime: function () { - return this.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.skeleton.data.slots; - for (var i = 0, n = slotDatas.length; i < n; i++) { - if (slotDatas[i] == data) { - this.setAttachment(!data.attachmentName ? null : this.skeleton.getAttachmentBySlotIndex(i, data.attachmentName)); - break; - } - } - } -}; - -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), 10); - 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, time, loop) { - if (loop && this.duration) time %= this.duration; - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, time, 1); - }, - mix: function (skeleton, time, loop, alpha) { - if (loop && this.duration) time %= this.duration; - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, time, alpha); - } -}; - -spine.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.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 = []; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... - this.curves.length = (frameCount - 1) * 6; -}; -spine.Curves.prototype = { - setLinear: function (frameIndex) { - this.curves[frameIndex * 6] = 0/*LINEAR*/; - }, - setStepped: function (frameIndex) { - this.curves[frameIndex * 6] = -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 subdiv_step = 1 / 10/*BEZIER_SEGMENTS*/; - var subdiv_step2 = subdiv_step * subdiv_step; - var subdiv_step3 = subdiv_step2 * subdiv_step; - var pre1 = 3 * subdiv_step; - var pre2 = 3 * subdiv_step2; - var pre4 = 6 * subdiv_step2; - var pre5 = 6 * subdiv_step3; - var tmp1x = -cx1 * 2 + cx2; - var tmp1y = -cy1 * 2 + cy2; - var tmp2x = (cx1 - cx2) * 3 + 1; - var tmp2y = (cy1 - cy2) * 3 + 1; - var i = frameIndex * 6; - var curves = this.curves; - curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; - curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; - curves[i + 2] = tmp1x * pre4 + tmp2x * pre5; - curves[i + 3] = tmp1y * pre4 + tmp2y * pre5; - curves[i + 4] = tmp2x * pre5; - curves[i + 5] = tmp2y * pre5; - }, - getCurvePercent: function (frameIndex, percent) { - percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent); - var curveIndex = frameIndex * 6; - var curves = this.curves; - var dfx = curves[curveIndex]; - if (!dfx/*LINEAR*/) return percent; - if (dfx == -1/*STEPPED*/) return 0; - var dfy = curves[curveIndex + 1]; - var ddfx = curves[curveIndex + 2]; - var ddfy = curves[curveIndex + 3]; - var dddfx = curves[curveIndex + 4]; - var dddfy = curves[curveIndex + 5]; - var x = dfx, y = dfy; - var i = 10/*BEZIER_SEGMENTS*/ - 2; - while (true) { - if (x >= percent) { - var lastX = x - dfx; - var lastY = y - dfy; - return lastY + (y - lastY) * (percent - lastX) / (x - lastX); - } - if (!i) break; - i--; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } - 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, time, alpha) { - var frames = this.frames, - amount; - - 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. - 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 last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 2); - var lastFrameValue = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent); - - amount = frames[frameIndex + 1/*FRAME_VALUE*/] - lastFrameValue; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - amount = bone.data.rotation + (lastFrameValue + 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, time, 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 last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 3); - var lastFrameX = frames[frameIndex - 2]; - var lastFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.x) * alpha; - bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * 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, time, 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 - 1 + frames[frames.length - 2] - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - 1 + frames[frames.length - 1] - bone.scaleY) * alpha; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 3); - var lastFrameX = frames[frameIndex - 2]; - var lastFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * 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 / 2; - }, - setFrame: function (frameIndex, time, x, y) { - 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, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var slot = skeleton.slots[this.slotIndex]; - - if (time >= frames[frames.length - 5]) { // Time is after last frame. - var i = frames.length - 1; - slot.r = frames[i - 3]; - slot.g = frames[i - 2]; - slot.b = frames[i - 1]; - slot.a = frames[i]; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 5); - var lastFrameR = frames[frameIndex - 4]; - var lastFrameG = frames[frameIndex - 3]; - var lastFrameB = frames[frameIndex - 2]; - var lastFrameA = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent); - - var r = lastFrameR + (frames[frameIndex + 1/*FRAME_R*/] - lastFrameR) * percent; - var g = lastFrameG + (frames[frameIndex + 2/*FRAME_G*/] - lastFrameG) * percent; - var b = lastFrameB + (frames[frameIndex + 3/*FRAME_B*/] - lastFrameB) * percent; - var a = lastFrameA + (frames[frameIndex + 4/*FRAME_A*/] - lastFrameA) * percent; - 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 = []; // time, ... - 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, time, 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.binarySearch(frames, time, 1) - 1; - - var attachmentName = this.attachmentNames[frameIndex]; - skeleton.slots[this.slotIndex].setAttachment(!attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName)); - } -}; - -spine.SkeletonData = function () { - this.bones = []; - this.slots = []; - this.skins = []; - this.animations = []; -}; -spine.SkeletonData.prototype = { - defaultSkin: 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. */ - 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; - } -}; - -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, parent)); - } - - this.slots = []; - this.drawOrder = []; - for (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, this, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } -}; -spine.Skeleton.prototype = { - x: 0, y: 0, - skin: null, - r: 1, g: 1, b: 1, a: 1, - time: 0, - flipX: false, flipY: false, - /** Updates the world transform for each bone. */ - updateWorldTransform: function () { - var flipX = this.flipX; - var flipY = this.flipY; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].updateWorldTransform(flipX, flipY); - }, - /** 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(); - }, - setSlotsToSetupPose: function () { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; 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 not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments - * from the new skin are attached if the corresponding attachment from the old skin was attached. - * @param newSkin May be null. */ - setSkin: function (newSkin) { - if (this.skin && newSkin) newSkin._attachAll(this, this.skin); - 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.size; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName) { - attachment = this.getAttachment(i, attachmentName); - if (attachment == null) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName; - } - slot.setAttachment(attachment); - return; - } - } - throw "Slot not found: " + slotName; - }, - update: function (delta) { - time += delta; - } -}; - -spine.AttachmentType = { - region: 0 -}; - -spine.RegionAttachment = function () { - this.offset = []; - this.offset.length = 8; - this.uvs = []; - this.uvs.length = 8; -}; -spine.RegionAttachment.prototype = { - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - width: 0, height: 0, - 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 * Math.PI / 180; - 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; - var m01 = bone.m01; - var m10 = bone.m10; - var 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.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 time = this.animationToMixTime[from.name + ":" + to.name]; - return time ? time : this.defaultMix; - } -}; - -spine.AnimationState = function (stateData) { - this.data = stateData; - this.queue = []; -}; -spine.AnimationState.prototype = { - current: null, - previous: null, - currentTime: 0, - previousTime: 0, - currentLoop: false, - previousLoop: false, - mixTime: 0, - mixDuration: 0, - update: function (delta) { - this.currentTime += delta; - this.previousTime += delta; - this.mixTime += delta; - - if (this.queue.length > 0) { - var entry = this.queue[0]; - if (this.currentTime >= entry.delay) { - this._setAnimation(entry.animation, entry.loop); - this.queue.shift(); - } - } - }, - apply: function (skeleton) { - if (!this.current) return; - if (this.previous) { - this.previous.apply(skeleton, this.previousTime, this.previousLoop); - var alpha = this.mixTime / this.mixDuration; - if (alpha >= 1) { - alpha = 1; - this.previous = null; - } - this.current.mix(skeleton, this.currentTime, this.currentLoop, alpha); - } else - this.current.apply(skeleton, this.currentTime, this.currentLoop); - }, - clearAnimation: function () { - this.previous = null; - this.current = null; - this.queue.length = 0; - }, - _setAnimation: function (animation, loop) { - this.previous = null; - if (animation && this.current) { - this.mixDuration = this.data.getMix(this.current, animation); - if (this.mixDuration > 0) { - this.mixTime = 0; - this.previous = this.current; - this.previousTime = this.currentTime; - this.previousLoop = this.currentLoop; - } - } - this.current = animation; - this.currentLoop = loop; - this.currentTime = 0; - }, - /** @see #setAnimation(Animation, Boolean) */ - setAnimationByName: function (animationName, loop) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw "Animation not found: " + animationName; - this.setAnimation(animation, loop); - }, - /** Set the current animation. Any queued animations are cleared and the current animation time is set to 0. - * @param animation May be null. */ - setAnimation: function (animation, loop) { - this.queue.length = 0; - this._setAnimation(animation, loop); - }, - /** @see #addAnimation(Animation, Boolean, Number) */ - addAnimationByName: function (animationName, loop, delay) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw "Animation not found: " + animationName; - this.addAnimation(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 (animation, loop, delay) { - var entry = {}; - entry.animation = animation; - entry.loop = loop; - - if (!delay || delay <= 0) { - var previousAnimation = this.queue.length ? this.queue[this.queue.length - 1].animation : this.current; - if (previousAnimation != null) - delay = previousAnimation.duration - this.data.getMix(previousAnimation, animation) + (delay || 0); - else - delay = 0; - } - entry.delay = delay; - - this.queue.push(entry); - }, - /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */ - isComplete: function () { - return !this.current || this.currentTime >= this.current.duration; - } -}; - -spine.SkeletonJson = function (attachmentLoader) { - this.attachmentLoader = attachmentLoader; -}; -spine.SkeletonJson.prototype = { - scale: 1, - readSkeletonData: function (root) { - /*jshint -W069*/ - var skeletonData = new spine.SkeletonData(), - boneData; - - // 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"]; - } - 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["scaleX"] || 1; - boneData.scaleY = boneMap["scaleY"] || 1; - skeletonData.bones.push(boneData); - } - - // Slots. - var slots = root["slots"]; - for (i = 0, n = slots.length; i < n; i++) { - var slotMap = slots[i]; - 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 = spine.SkeletonJson.toColor(color, 0); - slotData.g = spine.SkeletonJson.toColor(color, 1); - slotData.b = spine.SkeletonJson.toColor(color, 2); - slotData.a = spine.SkeletonJson.toColor(color, 3); - } - - slotData.attachmentName = slotMap["attachment"]; - - 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 != null) skin.addAttachment(slotIndex, attachmentName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") skeletonData.defaultSkin = skin; - } - - // 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) { - /*jshint -W069*/ - name = map["name"] || name; - - var type = spine.AttachmentType[map["type"] || "region"]; - - if (type == spine.AttachmentType.region) { - var attachment = new spine.RegionAttachment(); - attachment.x = (map["x"] || 0) * this.scale; - attachment.y = (map["y"] || 0) * this.scale; - attachment.scaleX = map["scaleX"] || 1; - attachment.scaleY = map["scaleY"] || 1; - attachment.rotation = map["rotation"] || 0; - attachment.width = (map["width"] || 32) * this.scale; - attachment.height = (map["height"] || 32) * this.scale; - attachment.updateOffset(); - - attachment.rendererObject = {}; - attachment.rendererObject.name = name; - attachment.rendererObject.scale = {}; - attachment.rendererObject.scale.x = attachment.scaleX; - attachment.rendererObject.scale.y = attachment.scaleY; - attachment.rendererObject.rotation = -attachment.rotation * Math.PI / 180; - return attachment; - } - - throw "Unknown attachment type: " + type; - }, - - readAnimation: function (name, map, skeletonData) { - /*jshint -W069*/ - var timelines = []; - var duration = 0; - var frameIndex, timeline, timelineName, valueMap, values, - i, n; - - 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 (timelineName in boneMap) { - if (!boneMap.hasOwnProperty(timelineName)) continue; - values = boneMap[timelineName]; - if (timelineName == "rotate") { - timeline = new spine.RotateTimeline(values.length); - timeline.boneIndex = boneIndex; - - frameIndex = 0; - for (i = 0, n = values.length; i < n; i++) { - valueMap = values[i]; - timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); - - } else if (timelineName == "translate" || timelineName == "scale") { - 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; - - frameIndex = 0; - for (i = 0, n = values.length; i < n; i++) { - valueMap = values[i]; - var x = (valueMap["x"] || 0) * timelineScale; - var y = (valueMap["y"] || 0) * timelineScale; - timeline.setFrame(frameIndex, valueMap["time"], x, y); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]); - - } else - throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"; - } - } - var slots = map["slots"]; - for (var slotName in slots) { - if (!slots.hasOwnProperty(slotName)) continue; - var slotMap = slots[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - - for (timelineName in slotMap) { - if (!slotMap.hasOwnProperty(timelineName)) continue; - values = slotMap[timelineName]; - if (timelineName == "color") { - timeline = new spine.ColorTimeline(values.length); - timeline.slotIndex = slotIndex; - - frameIndex = 0; - for (i = 0, n = values.length; i < n; i++) { - valueMap = values[i]; - var color = valueMap["color"]; - var r = spine.SkeletonJson.toColor(color, 0); - var g = spine.SkeletonJson.toColor(color, 1); - var b = spine.SkeletonJson.toColor(color, 2); - var a = spine.SkeletonJson.toColor(color, 3); - timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]); - - } else if (timelineName == "attachment") { - timeline = new spine.AttachmentTimeline(values.length); - timeline.slotIndex = slotIndex; - - frameIndex = 0; - for (i = 0, n = values.length; i < n; i++) { - valueMap = values[i]; - timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - - } else - throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"; - } - } - skeletonData.animations.push(new spine.Animation(name, timelines, duration)); - } -}; -spine.SkeletonJson.readCurve = function (timeline, frameIndex, valueMap) { - /*jshint -W069*/ - var curve = valueMap["curve"]; - if (!curve) return; - if (curve == "stepped") - timeline.curves.setStepped(frameIndex); - else if (curve instanceof Array) - timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); -}; -spine.SkeletonJson.toColor = function (hexString, colorIndex) { - if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString; - return parseInt(hexString.substring(colorIndex * 2, 2), 16) / 255; -}; - -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; - - page.format = spine.Atlas.Format[reader.readValue()]; - - 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.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], 10); - var y = parseInt(tuple[1], 10); - - reader.readTuple(tuple); - var width = parseInt(tuple[0], 10); - var height = parseInt(tuple[1], 10); - - 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], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; - - if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits - region.pads = [parseInt(tuple[0], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; - - reader.readTuple(tuple); - } - } - - region.originalWidth = parseInt(tuple[0], 10); - region.originalHeight = parseInt(tuple[1], 10); - - reader.readTuple(tuple); - region.offsetX = parseInt(tuple[0], 10); - region.offsetY = parseInt(tuple[1], 10); - - region.index = parseInt(reader.readValue(), 10); - - 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 (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) { - if (!i) throw "Invalid line: " + line; - 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 = { - newAttachment: function (skin, type, name) { - switch (type) { - case spine.AttachmentType.region: - var region = this.atlas.findRegion(name); - if (!region) throw "Region not found in atlas: " + name + " (" + type + ")"; - 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; - } - throw "Unknown attachment type: " + type; - } -} - -spine.Bone.yDown = true; -PIXI.AnimCache = {}; - -/** - * A class that enables the you to import and run your spine animations in pixi. - * Spine animation data needs to be loaded using the PIXI.AssetLoader or PIXI.SpineLoader before it can be used by this class - * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source - * - * @class Spine - * @extends DisplayObjectContainer - * @constructor - * @param url {String} The url of the spine anim file to be used - */ -PIXI.Spine = function (url) { - PIXI.DisplayObjectContainer.call(this); - - this.spineData = PIXI.AnimCache[url]; - - if (!this.spineData) { - throw new Error("Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: " + url); - } - - this.skeleton = new spine.Skeleton(this.spineData); - this.skeleton.updateWorldTransform(); - - this.stateData = new spine.AnimationStateData(this.spineData); - this.state = new spine.AnimationState(this.stateData); - - this.slotContainers = []; - - for (var i = 0, n = this.skeleton.drawOrder.length; i < n; i++) { - var slot = this.skeleton.drawOrder[i]; - var attachment = slot.attachment; - var slotContainer = new PIXI.DisplayObjectContainer(); - this.slotContainers.push(slotContainer); - this.addChild(slotContainer); - if (!(attachment instanceof spine.RegionAttachment)) { - continue; - } - var spriteName = attachment.rendererObject.name; - var sprite = this.createSprite(slot, attachment.rendererObject); - slot.currentSprite = sprite; - slot.currentSpriteName = spriteName; - slotContainer.addChild(sprite); - } -}; - -PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); -PIXI.Spine.prototype.constructor = PIXI.Spine; - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.Spine.prototype.updateTransform = function () { - this.lastTime = this.lastTime || Date.now(); - var timeDelta = (Date.now() - this.lastTime) * 0.001; - this.lastTime = Date.now(); - this.state.update(timeDelta); - this.state.apply(this.skeleton); - this.skeleton.updateWorldTransform(); - - var drawOrder = this.skeleton.drawOrder; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = drawOrder[i]; - var attachment = slot.attachment; - var slotContainer = this.slotContainers[i]; - if (!(attachment instanceof spine.RegionAttachment)) { - slotContainer.visible = false; - continue; - } - - if (attachment.rendererObject) { - if (!slot.currentSpriteName || slot.currentSpriteName != attachment.name) { - var spriteName = attachment.rendererObject.name; - if (slot.currentSprite !== undefined) { - slot.currentSprite.visible = false; - } - slot.sprites = slot.sprites || {}; - if (slot.sprites[spriteName] !== undefined) { - slot.sprites[spriteName].visible = true; - } else { - var sprite = this.createSprite(slot, attachment.rendererObject); - slotContainer.addChild(sprite); - } - slot.currentSprite = slot.sprites[spriteName]; - slot.currentSpriteName = spriteName; - } - } - slotContainer.visible = true; - - var bone = slot.bone; - - slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01; - slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11; - slotContainer.scale.x = bone.worldScaleX; - slotContainer.scale.y = bone.worldScaleY; - - slotContainer.rotation = -(slot.bone.worldRotation * Math.PI / 180); - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); -}; - - -PIXI.Spine.prototype.createSprite = function (slot, descriptor) { - var name = PIXI.TextureCache[descriptor.name] ? descriptor.name : descriptor.name + ".png"; - var sprite = new PIXI.Sprite(PIXI.Texture.fromFrame(name)); - sprite.scale = descriptor.scale; - sprite.rotation = descriptor.rotation; - sprite.anchor.x = sprite.anchor.y = 0.5; - - slot.sprites = slot.sprites || {}; - slot.sprites[descriptor.name] = sprite; - return sprite; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.BaseTextureCache = {}; -PIXI.texturesToUpdate = []; -PIXI.texturesToDestroy = []; - -PIXI.BaseTextureCacheIdGenerator = 0; - -/** - * A texture stores the information that represents an image. All textures have a base texture - * - * @class BaseTexture - * @uses EventTarget - * @constructor - * @param source {String} the source object (image or canvas) - * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts - */ -PIXI.BaseTexture = function(source, scaleMode) -{ - PIXI.EventTarget.call( this ); - - /** - * [read-only] The width of the base texture set when the image has loaded - * - * @property width - * @type Number - * @readOnly - */ - this.width = 100; - - /** - * [read-only] The height of the base texture set when the image has loaded - * - * @property height - * @type Number - * @readOnly - */ - this.height = 100; - - /** - * The scale mode to apply when scaling this texture - * @property scaleMode - * @type PIXI.scaleModes - * @default PIXI.scaleModes.LINEAR - */ - this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; - - /** - * [read-only] Describes if the base texture has loaded or not - * - * @property hasLoaded - * @type Boolean - * @readOnly - */ - this.hasLoaded = false; - - /** - * The source that is loaded to create the texture - * - * @property source - * @type Image - */ - this.source = source; - - if(!source)return; - - if(this.source.complete || this.source.getContext) - { - this.hasLoaded = true; - this.width = this.source.width; - this.height = this.source.height; - - PIXI.texturesToUpdate.push(this); - } - else - { - - var scope = this; - this.source.onload = function() { - - scope.hasLoaded = true; - scope.width = scope.source.width; - scope.height = scope.source.height; - - // add it to somewhere... - PIXI.texturesToUpdate.push(scope); - scope.dispatchEvent( { type: 'loaded', content: scope } ); - }; - } - - this.imageUrl = null; - this._powerOf2 = false; - - //TODO will be used for futer pixi 1.5... - this.id = PIXI.BaseTextureCacheIdGenerator++; - - // used for webGL - this._glTextures = []; - -}; - -PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; - -/** - * Destroys this base texture - * - * @method destroy - */ -PIXI.BaseTexture.prototype.destroy = function() -{ - if(this.imageUrl) - { - delete PIXI.BaseTextureCache[this.imageUrl]; - this.imageUrl = null; - this.source.src = null; - } - this.source = null; - PIXI.texturesToDestroy.push(this); -}; - -/** - * Changes the source image of the texture - * - * @method updateSourceImage - * @param newSrc {String} the path of the image - */ -PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) -{ - this.hasLoaded = false; - this.source.src = null; - this.source.src = newSrc; -}; - -/** - * Helper function that returns a base texture based on an image url - * If the image is not in the base texture cache it will be created and loaded - * - * @static - * @method fromImage - * @param imageUrl {String} The image url of the texture - * @param crossorigin {Boolean} - * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts - * @return BaseTexture - */ -PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) -{ - var baseTexture = PIXI.BaseTextureCache[imageUrl]; - crossorigin = !crossorigin; - - if(!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - var image = new Image();//document.createElement('img'); - if (crossorigin) - { - image.crossOrigin = ''; - } - image.src = imageUrl; - baseTexture = new PIXI.BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - PIXI.BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; -}; - -PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode) -{ - if(!canvas._pixiId) - { - canvas._pixiId = 'canvas_' + PIXI.TextureCacheIdGenerator++; - } - - var baseTexture = PIXI.BaseTextureCache[canvas._pixiId]; - - if(!baseTexture) - { - baseTexture = new PIXI.BaseTexture(canvas, scaleMode); - PIXI.BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; -}; - - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.TextureCache = {}; -PIXI.FrameCache = {}; - -PIXI.TextureCacheIdGenerator = 0; - -/** - * A texture stores the information that represents an image or part of an image. It cannot be added - * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used - * - * @class Texture - * @uses EventTarget - * @constructor - * @param baseTexture {BaseTexture} The base texture source to create the texture from - * @param frame {Rectangle} The rectangle frame of the texture to show - */ -PIXI.Texture = function(baseTexture, frame) -{ - PIXI.EventTarget.call( this ); - - if(!frame) - { - this.noFrame = true; - frame = new PIXI.Rectangle(0,0,1,1); - } - - if(baseTexture instanceof PIXI.Texture) - baseTexture = baseTexture.baseTexture; - - /** - * The base texture of that this texture uses - * - * @property baseTexture - * @type BaseTexture - */ - this.baseTexture = baseTexture; - - /** - * The frame specifies the region of the base texture that this texture uses - * - * @property frame - * @type Rectangle - */ - this.frame = frame; - - /** - * The trim point - * - * @property trim - * @type Rectangle - */ - this.trim = null; - - this.scope = this; - - if(baseTexture.hasLoaded) - { - if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); - - this.setFrame(frame); - } - else - { - var scope = this; - baseTexture.addEventListener('loaded', function(){ scope.onBaseTextureLoaded(); }); - } -}; - -PIXI.Texture.prototype.constructor = PIXI.Texture; - -/** - * Called when the base texture is loaded - * - * @method onBaseTextureLoaded - * @param event - * @private - */ -PIXI.Texture.prototype.onBaseTextureLoaded = function() -{ - var baseTexture = this.baseTexture; - baseTexture.removeEventListener( 'loaded', this.onLoaded ); - - if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); - - this.setFrame(this.frame); - - this.scope.dispatchEvent( { type: 'update', content: this } ); -}; - -/** - * Destroys this texture - * - * @method destroy - * @param destroyBase {Boolean} Whether to destroy the base texture as well - */ -PIXI.Texture.prototype.destroy = function(destroyBase) -{ - if(destroyBase) this.baseTexture.destroy(); -}; - -/** - * Specifies the rectangle region of the baseTexture - * - * @method setFrame - * @param frame {Rectangle} The frame of the texture to set it to - */ -PIXI.Texture.prototype.setFrame = function(frame) -{ - this.frame = frame; - this.width = frame.width; - this.height = frame.height; - - if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) - { - throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); - } - - this.updateFrame = true; - - PIXI.Texture.frameUpdates.push(this); - - - //this.dispatchEvent( { type: 'update', content: this } ); -}; - -PIXI.Texture.prototype._updateWebGLuvs = function() -{ - if(!this._uvs)this._uvs = new PIXI.TextureUvs(); - - var frame = this.frame; - var tw = this.baseTexture.width; - var th = this.baseTexture.height; - - this._uvs.x0 = frame.x / tw; - this._uvs.y0 = frame.y / th; - - this._uvs.x1 = (frame.x + frame.width) / tw; - this._uvs.y1 = frame.y / th; - - this._uvs.x2 = (frame.x + frame.width) / tw; - this._uvs.y2 = (frame.y + frame.height) / th; - - this._uvs.x3 = frame.x / tw; - this._uvs.y3 = (frame.y + frame.height) / th; -}; - -/** - * Helper function that returns a texture based on an image url - * If the image is not in the texture cache it will be created and loaded - * - * @static - * @method fromImage - * @param imageUrl {String} The image url of the texture - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - * @return Texture - */ -PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) -{ - var texture = PIXI.TextureCache[imageUrl]; - - if(!texture) - { - texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin, scaleMode)); - PIXI.TextureCache[imageUrl] = texture; - } - - return texture; -}; - -/** - * Helper function that returns a texture based on a frame id - * If the frame id is not in the texture cache an error will be thrown - * - * @static - * @method fromFrame - * @param frameId {String} The frame id of the texture - * @return Texture - */ -PIXI.Texture.fromFrame = function(frameId) -{ - var texture = PIXI.TextureCache[frameId]; - if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache '); - return texture; -}; - -/** - * Helper function that returns a texture based on a canvas element - * If the canvas is not in the texture cache it will be created and loaded - * - * @static - * @method fromCanvas - * @param canvas {Canvas} The canvas element source of the texture - * @return Texture - */ -PIXI.Texture.fromCanvas = function(canvas, scaleMode) -{ - var baseTexture = PIXI.BaseTexture.fromCanvas(canvas, scaleMode); - - return new PIXI.Texture( baseTexture ); - -}; - - -/** - * Adds a texture to the textureCache. - * - * @static - * @method addTextureToCache - * @param texture {Texture} - * @param id {String} the id that the texture will be stored against. - */ -PIXI.Texture.addTextureToCache = function(texture, id) -{ - PIXI.TextureCache[id] = texture; -}; - -/** - * Remove a texture from the textureCache. - * - * @static - * @method removeTextureFromCache - * @param id {String} the id of the texture to be removed - * @return {Texture} the texture that was removed - */ -PIXI.Texture.removeTextureFromCache = function(id) -{ - var texture = PIXI.TextureCache[id]; - PIXI.TextureCache[id] = null; - return texture; -}; - -// this is more for webGL.. it contains updated frames.. -PIXI.Texture.frameUpdates = []; - -PIXI.TextureUvs = function() -{ - this.x0 = 0; - this.y0 = 0; - - this.x1 = 0; - this.y1 = 0; - - this.x2 = 0; - this.y2 = 0; - - this.x3 = 0; - this.y4 = 0; - - -}; - - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it. - - __Hint__: All DisplayObjects (exmpl. Sprites) that render on RenderTexture should be preloaded. - Otherwise black rectangles will be drawn instead. - - RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example: - - var renderTexture = new PIXI.RenderTexture(800, 600); - var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); - sprite.position.x = 800/2; - sprite.position.y = 600/2; - sprite.anchor.x = 0.5; - sprite.anchor.y = 0.5; - renderTexture.render(sprite); - - Sprite in this case will be rendered to 0,0 position. To render this sprite at center DisplayObjectContainer should be used: - - var doc = new PIXI.DisplayObjectContainer(); - doc.addChild(sprite); - renderTexture.render(doc); // Renders to center of renderTexture - - * @class RenderTexture - * @extends Texture - * @constructor - * @param width {Number} The width of the render texture - * @param height {Number} The height of the render texture - */ -PIXI.RenderTexture = function(width, height, renderer) -{ - PIXI.EventTarget.call( this ); - - /** - * The with of the render texture - * - * @property width - * @type Number - */ - this.width = width || 100; - /** - * The height of the render texture - * - * @property height - * @type Number - */ - this.height = height || 100; - - /** - * The framing rectangle of the render texture - * - * @property frame - * @type Rectangle - */ - this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); - - /** - * The base texture object that this texture uses - * - * @property baseTexture - * @type BaseTexture - */ - this.baseTexture = new PIXI.BaseTexture(); - this.baseTexture.width = this.width; - this.baseTexture.height = this.height; - this.baseTexture._glTextures = []; - - this.baseTexture.hasLoaded = true; - - // each render texture can only belong to one renderer at the moment if its webGL - this.renderer = renderer || PIXI.defaultRenderer; - - if(this.renderer.type === PIXI.WEBGL_RENDERER) - { - var gl = this.renderer.gl; - - this.textureBuffer = new PIXI.FilterTexture(gl, this.width, this.height); - this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; - - this.render = this.renderWebGL; - this.projection = new PIXI.Point(this.width/2 , -this.height/2); - } - else - { - this.render = this.renderCanvas; - this.textureBuffer = new PIXI.CanvasBuffer(this.width, this.height); - this.baseTexture.source = this.textureBuffer.canvas; - } - - PIXI.Texture.frameUpdates.push(this); - - -}; - -PIXI.RenderTexture.prototype = Object.create(PIXI.Texture.prototype); -PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; - -PIXI.RenderTexture.prototype.resize = function(width, height) -{ - this.width = width; - this.height = height; - - this.frame.width = this.width; - this.frame.height = this.height; - - if(this.renderer.type === PIXI.WEBGL_RENDERER) - { - this.projection.x = this.width / 2; - this.projection.y = -this.height / 2; - - var gl = this.renderer.gl; - gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTextures[gl.id]); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - else - { - this.textureBuffer.resize(this.width, this.height); - } - - PIXI.Texture.frameUpdates.push(this); -}; - -/** - * This function will draw the display object to the texture. - * - * @method renderWebGL - * @param displayObject {DisplayObject} The display object to render this texture on - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) -{ - //TOOD replace position with matrix.. - var gl = this.renderer.gl; - - gl.colorMask(true, true, true, true); - - gl.viewport(0, 0, this.width, this.height); - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer ); - - if(clear)this.textureBuffer.clear(); - - // THIS WILL MESS WITH HIT TESTING! - var children = displayObject.children; - - //TODO -? create a new one??? dont think so! - var originalWorldTransform = displayObject.worldTransform; - displayObject.worldTransform = PIXI.RenderTexture.tempMatrix; - // modify to flip... - displayObject.worldTransform.d = -1; - displayObject.worldTransform.ty = this.projection.y * -2; - - if(position) - { - displayObject.worldTransform.tx = position.x; - displayObject.worldTransform.ty -= position.y; - } - - for(var i=0,j=children.length; i} assetURLs an array of image/sprite sheet urls that you would like loaded - * supported. Supported image formats include 'jpeg', 'jpg', 'png', 'gif'. Supported - * sprite sheet data formats only include 'JSON' at this time. Supported bitmap font - * data formats include 'xml' and 'fnt'. - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.AssetLoader = function(assetURLs, crossorigin) -{ - PIXI.EventTarget.call(this); - - /** - * The array of asset URLs that are going to be loaded - * - * @property assetURLs - * @type Array - */ - this.assetURLs = assetURLs; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * Maps file extension to loader types - * - * @property loadersByType - * @type Object - */ - this.loadersByType = { - 'jpg': PIXI.ImageLoader, - 'jpeg': PIXI.ImageLoader, - 'png': PIXI.ImageLoader, - 'gif': PIXI.ImageLoader, - 'json': PIXI.JsonLoader, - 'atlas': PIXI.AtlasLoader, - 'anim': PIXI.SpineLoader, - 'xml': PIXI.BitmapFontLoader, - 'fnt': PIXI.BitmapFontLoader - }; -}; - -/** - * Fired when an item has loaded - * @event onProgress - */ - -/** - * Fired when all the assets have loaded - * @event onComplete - */ - -// constructor -PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader; - -/** - * Given a filename, returns its extension, wil - * - * @method _getDataType - * @param str {String} the name of the asset - */ -PIXI.AssetLoader.prototype._getDataType = function(str) -{ - var test = 'data:'; - //starts with 'data:' - var start = str.slice(0, test.length).toLowerCase(); - if (start === test) { - var data = str.slice(test.length); - - var sepIdx = data.indexOf(','); - if (sepIdx === -1) //malformed data URI scheme - return null; - - //e.g. 'image/gif;base64' => 'image/gif' - var info = data.slice(0, sepIdx).split(';')[0]; - - //We might need to handle some special cases here... - //standardize text/plain to 'txt' file extension - if (!info || info.toLowerCase() === 'text/plain') - return 'txt'; - - //User specified mime type, try splitting it by '/' - return info.split('/').pop().toLowerCase(); - } - - return null; -}; - -/** - * Starts loading the assets sequentially - * - * @method load - */ -PIXI.AssetLoader.prototype.load = function() -{ - var scope = this; - - function onLoad(evt) { - scope.onAssetLoaded(evt.loader); - } - - this.loadCount = this.assetURLs.length; - - for (var i=0; i < this.assetURLs.length; i++) - { - var fileName = this.assetURLs[i]; - //first see if we have a data URI scheme.. - var fileType = this._getDataType(fileName); - - //if not, assume it's a file URI - if (!fileType) - fileType = fileName.split('?').shift().split('.').pop().toLowerCase(); - - var Constructor = this.loadersByType[fileType]; - if(!Constructor) - throw new Error(fileType + ' is an unsupported file type'); - - var loader = new Constructor(fileName, this.crossorigin); - - loader.addEventListener('loaded', onLoad); - loader.load(); - } -}; - -/** - * Invoked after each file is loaded - * - * @method onAssetLoaded - * @private - */ -PIXI.AssetLoader.prototype.onAssetLoaded = function(loader) -{ - this.loadCount--; - this.dispatchEvent({ type: 'onProgress', content: this, loader: loader }); - if (this.onProgress) this.onProgress(loader); - - if (!this.loadCount) - { - this.dispatchEvent({type: 'onComplete', content: this}); - if(this.onComplete) this.onComplete(); - } -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The json file loader is used to load in JSON data and parse it - * When loaded this class will dispatch a 'loaded' event - * If loading fails this class will dispatch an 'error' event - * - * @class JsonLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.JsonLoader = function (url, crossorigin) { - PIXI.EventTarget.call(this); - - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ''); - - /** - * [read-only] Whether the data has loaded yet - * - * @property loaded - * @type Boolean - * @readOnly - */ - this.loaded = false; - -}; - -// constructor -PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader; - -/** - * Loads the JSON data - * - * @method load - */ -PIXI.JsonLoader.prototype.load = function () { - this.ajaxRequest = new PIXI.AjaxRequest(this.crossorigin); - var scope = this; - this.ajaxRequest.onreadystatechange = function () { - scope.onJSONLoaded(); - }; - - this.ajaxRequest.open('GET', this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); - this.ajaxRequest.send(null); -}; - -/** - * Invoke when JSON file is loaded - * - * @method onJSONLoaded - * @private - */ -PIXI.JsonLoader.prototype.onJSONLoaded = function () { - if (this.ajaxRequest.readyState === 4) { - if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1) { - this.json = JSON.parse(this.ajaxRequest.responseText); - - if(this.json.frames) - { - // sprite sheet - var scope = this; - var textureUrl = this.baseUrl + this.json.meta.image; - var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); - var frameData = this.json.frames; - - this.texture = image.texture.baseTexture; - image.addEventListener('loaded', function() { - scope.onLoaded(); - }); - - for (var i in frameData) { - var rect = frameData[i].frame; - if (rect) { - PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { - x: rect.x, - y: rect.y, - width: rect.w, - height: rect.h - }); - - // check to see ifthe sprite ha been trimmed.. - if (frameData[i].trimmed) { - - var texture = PIXI.TextureCache[i]; - - var actualSize = frameData[i].sourceSize; - var realSize = frameData[i].spriteSourceSize; - - texture.trim = new PIXI.Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h); - } - } - } - - image.load(); - - } - else if(this.json.bones) - { - // spine animation - var spineJsonParser = new spine.SkeletonJson(); - var skeletonData = spineJsonParser.readSkeletonData(this.json); - PIXI.AnimCache[this.url] = skeletonData; - this.onLoaded(); - } - else - { - this.onLoaded(); - } - } - else - { - this.onError(); - } - } -}; - -/** - * Invoke when json file loaded - * - * @method onLoaded - * @private - */ -PIXI.JsonLoader.prototype.onLoaded = function () { - this.loaded = true; - this.dispatchEvent({ - type: 'loaded', - content: this - }); -}; - -/** - * Invoke when error occured - * - * @method onError - * @private - */ -PIXI.JsonLoader.prototype.onError = function () { - this.dispatchEvent({ - type: 'error', - content: this - }); -}; -/** - * @author Martin Kelm http://mkelm.github.com - */ - -/** - * The atlas file loader is used to load in Atlas data and parse it - * When loaded this class will dispatch a 'loaded' event - * If loading fails this class will dispatch an 'error' event - * @class AtlasLoader - * @extends EventTarget - * @constructor - * @param {String} url the url of the JSON file - * @param {Boolean} crossorigin - */ - -PIXI.AtlasLoader = function (url, crossorigin) { - PIXI.EventTarget.call(this); - this.url = url; - this.baseUrl = url.replace(/[^\/]*$/, ''); - this.crossorigin = crossorigin; - this.loaded = false; - -}; - -// constructor -PIXI.AtlasLoader.constructor = PIXI.AtlasLoader; - - - /** - * Starts loading the JSON file - * - * @method load - */ -PIXI.AtlasLoader.prototype.load = function () { - this.ajaxRequest = new PIXI.AjaxRequest(); - this.ajaxRequest.onreadystatechange = this.onAtlasLoaded.bind(this); - - this.ajaxRequest.open('GET', this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); - this.ajaxRequest.send(null); -}; - -/** - * Invoke when JSON file is loaded - * @method onAtlasLoaded - * @private - */ -PIXI.AtlasLoader.prototype.onAtlasLoaded = function () { - if (this.ajaxRequest.readyState === 4) { - if (this.ajaxRequest.status === 200 || window.location.href.indexOf('http') === -1) { - this.atlas = { - meta : { - image : [] - }, - frames : [] - }; - var result = this.ajaxRequest.responseText.split(/\r?\n/); - var lineCount = -3; - - var currentImageId = 0; - var currentFrame = null; - var nameInNextLine = false; - - var i = 0, - j = 0, - selfOnLoaded = this.onLoaded.bind(this); - - // parser without rotation support yet! - for (i = 0; i < result.length; i++) { - result[i] = result[i].replace(/^\s+|\s+$/g, ''); - if (result[i] === '') { - nameInNextLine = i+1; - } - if (result[i].length > 0) { - if (nameInNextLine === i) { - this.atlas.meta.image.push(result[i]); - currentImageId = this.atlas.meta.image.length - 1; - this.atlas.frames.push({}); - lineCount = -3; - } else if (lineCount > 0) { - if (lineCount % 7 === 1) { // frame name - if (currentFrame != null) { //jshint ignore:line - this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; - } - currentFrame = { name: result[i], frame : {} }; - } else { - var text = result[i].split(' '); - if (lineCount % 7 === 3) { // position - currentFrame.frame.x = Number(text[1].replace(',', '')); - currentFrame.frame.y = Number(text[2]); - } else if (lineCount % 7 === 4) { // size - currentFrame.frame.w = Number(text[1].replace(',', '')); - currentFrame.frame.h = Number(text[2]); - } else if (lineCount % 7 === 5) { // real size - var realSize = { - x : 0, - y : 0, - w : Number(text[1].replace(',', '')), - h : Number(text[2]) - }; - - if (realSize.w > currentFrame.frame.w || realSize.h > currentFrame.frame.h) { - currentFrame.trimmed = true; - currentFrame.realSize = realSize; - } else { - currentFrame.trimmed = false; - } - } - } - } - lineCount++; - } - } - - if (currentFrame != null) { //jshint ignore:line - this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; - } - - if (this.atlas.meta.image.length > 0) { - this.images = []; - for (j = 0; j < this.atlas.meta.image.length; j++) { - // sprite sheet - var textureUrl = this.baseUrl + this.atlas.meta.image[j]; - var frameData = this.atlas.frames[j]; - this.images.push(new PIXI.ImageLoader(textureUrl, this.crossorigin)); - - for (i in frameData) { - var rect = frameData[i].frame; - if (rect) { - PIXI.TextureCache[i] = new PIXI.Texture(this.images[j].texture.baseTexture, { - x: rect.x, - y: rect.y, - width: rect.w, - height: rect.h - }); - if (frameData[i].trimmed) { - PIXI.TextureCache[i].realSize = frameData[i].realSize; - // trim in pixi not supported yet, todo update trim properties if it is done ... - PIXI.TextureCache[i].trim.x = 0; - PIXI.TextureCache[i].trim.y = 0; - } - } - } - } - - this.currentImageId = 0; - for (j = 0; j < this.images.length; j++) { - this.images[j].addEventListener('loaded', selfOnLoaded); - } - this.images[this.currentImageId].load(); - - } else { - this.onLoaded(); - } - - } else { - this.onError(); - } - } -}; - -/** - * Invoke when json file has loaded - * @method onLoaded - * @private - */ -PIXI.AtlasLoader.prototype.onLoaded = function () { - if (this.images.length - 1 > this.currentImageId) { - this.currentImageId++; - this.images[this.currentImageId].load(); - } else { - this.loaded = true; - this.dispatchEvent({ - type: 'loaded', - content: this - }); - } -}; - -/** - * Invoke when error occured - * @method onError - * @private - */ -PIXI.AtlasLoader.prototype.onError = function () { - this.dispatchEvent({ - type: 'error', - content: this - }); -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The sprite sheet loader is used to load in JSON sprite sheet data - * To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format - * There is a free version so thats nice, although the paid version is great value for money. - * It is highly recommended to use Sprite sheets (also know as a 'texture atlas') as it means sprites can be batched and drawn together for highly increased rendering speed. - * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() - * This loader will load the image file that the Spritesheet points to as well as the data. - * When loaded this class will dispatch a 'loaded' event - * - * @class SpriteSheetLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the sprite sheet JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.SpriteSheetLoader = function (url, crossorigin) { - /* - * i use texture packer to load the assets.. - * http://www.codeandweb.com/texturepacker - * make sure to set the format as 'JSON' - */ - PIXI.EventTarget.call(this); - - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ''); - - /** - * The texture being loaded - * - * @property texture - * @type Texture - */ - this.texture = null; - - /** - * The frames of the sprite sheet - * - * @property frames - * @type Object - */ - this.frames = {}; -}; - -// constructor -PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader; - -/** - * This will begin loading the JSON file - * - * @method load - */ -PIXI.SpriteSheetLoader.prototype.load = function () { - var scope = this; - var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.addEventListener('loaded', function (event) { - scope.json = event.content.json; - scope.onLoaded(); - }); - jsonLoader.load(); -}; - -/** - * Invoke when all files are loaded (json and texture) - * - * @method onLoaded - * @private - */ -PIXI.SpriteSheetLoader.prototype.onLoaded = function () { - this.dispatchEvent({ - type: 'loaded', - content: this - }); -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif') - * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() - * When loaded this class will dispatch a 'loaded' event - * - * @class ImageLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the image - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.ImageLoader = function(url, crossorigin) -{ - PIXI.EventTarget.call(this); - - /** - * The texture being loaded - * - * @property texture - * @type Texture - */ - this.texture = PIXI.Texture.fromImage(url, crossorigin); - - /** - * if the image is loaded with loadFramedSpriteSheet - * frames will contain the sprite sheet frames - * - */ - this.frames = []; -}; - -// constructor -PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader; - -/** - * Loads image or takes it from cache - * - * @method load - */ -PIXI.ImageLoader.prototype.load = function() -{ - if(!this.texture.baseTexture.hasLoaded) - { - var scope = this; - this.texture.baseTexture.addEventListener('loaded', function() - { - scope.onLoaded(); - }); - } - else - { - this.onLoaded(); - } -}; - -/** - * Invoked when image file is loaded or it is already cached and ready to use - * - * @method onLoaded - * @private - */ -PIXI.ImageLoader.prototype.onLoaded = function() -{ - this.dispatchEvent({type: 'loaded', content: this}); -}; - -/** - * Loads image and split it to uniform sized frames - * - * - * @method loadFramedSpriteSheet - * @param frameWidth {Number} width of each frame - * @param frameHeight {Number} height of each frame - * @param textureName {String} if given, the frames will be cached in - format - */ -PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName) -{ - this.frames = []; - var cols = Math.floor(this.texture.width / frameWidth); - var rows = Math.floor(this.texture.height / frameHeight); - - var i=0; - for (var y=0; y -1 ) - { - var args = [ - '%c %c %c Pixi.js ' + PIXI.VERSION + ' - ' + type + ' %c ' + ' %c ' + ' http://www.pixijs.com/ %c %c ♥%c♥%c♥ ', - 'background: #ff66a5', - 'background: #ff66a5', - 'color: #ff66a5; background: #030307;', - 'background: #ff66a5', - 'background: #ffc3dc', - 'background: #ff66a5', - 'color: #ff2424; background: #fff', - 'color: #ff2424; background: #fff', - 'color: #ff2424; background: #fff' - ]; - - console.log.apply(console, args); - } - else if (window['console']) - { - console.log('Pixi.js ' + PIXI.VERSION + ' - http://www.pixijs.com/'); - } - - PIXI.dontSayHello = true; -}; - +PIXI.DEG_TO_RAD = Math.PI / 180; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -260,22 +111,16 @@ PIXI.Point.prototype.clone = function() return new PIXI.Point(this.x, this.y); }; -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @method set - * @param [x=0] {Number} position of the point on the x axis - * @param [y=0] {Number} position of the point on the y axis - */ +// constructor +PIXI.Point.prototype.constructor = PIXI.Point; + PIXI.Point.prototype.set = function(x, y) { this.x = x || 0; this.y = y || ( (y !== 0) ? this.x : 0 ) ; }; -// constructor -PIXI.Point.prototype.constructor = PIXI.Point; + /** * @author Mat Groves http://matgroves.com/ */ @@ -285,8 +130,8 @@ PIXI.Point.prototype.constructor = PIXI.Point; * * @class Rectangle * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the rectangle - * @param y {Number} The Y coordinate of the upper-left corner of the rectangle + * @param x {Number} The X coord of the upper-left corner of the rectangle + * @param y {Number} The Y coord of the upper-left corner of the rectangle * @param width {Number} The overall width of this rectangle * @param height {Number} The overall height of this rectangle */ @@ -333,12 +178,12 @@ PIXI.Rectangle.prototype.clone = function() }; /** - * Checks whether the x and y coordinates given are contained within this Rectangle + * Checks whether the x and y coordinates passed to this function are contained within this Rectangle * * @method contains * @param x {Number} The X coordinate of the point to test * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Rectangle + * @return {Boolean} Whether the x/y coords are within this Rectangle */ PIXI.Rectangle.prototype.contains = function(x, y) { @@ -362,7 +207,7 @@ PIXI.Rectangle.prototype.contains = function(x, y) // constructor PIXI.Rectangle.prototype.constructor = PIXI.Rectangle; -PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); +PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); /** * @author Adrien Brault */ @@ -370,7 +215,7 @@ PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); /** * @class Polygon * @constructor - * @param points* {Array(Point)|Array(Number)|Point...|Number...} This can be an array of Points that form the polygon, + * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon, * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are @@ -379,21 +224,21 @@ PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); PIXI.Polygon = function(points) { //if points isn't an array, use arguments as the array - if(!(points instanceof Array))points = Array.prototype.slice.call(arguments); + if(!(points instanceof Array)) + points = Array.prototype.slice.call(arguments); //if this is a flat array of numbers, convert it to points - if(points[0] instanceof PIXI.Point) - { + if(typeof points[0] === 'number') { var p = []; - for(var i = 0, il = points.length; i < il; i++) - { - p.push(points[i].x, points[i].y); + for(var i = 0, il = points.length; i < il; i+=2) { + p.push( + new PIXI.Point(points[i], points[i + 1]) + ); } points = p; } - this.closed = true; this.points = points; }; @@ -405,7 +250,11 @@ PIXI.Polygon = function(points) */ PIXI.Polygon.prototype.clone = function() { - var points = this.points.slice(); + var points = []; + for (var i=0; i y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if(intersect) inside = !inside; @@ -439,7 +285,7 @@ PIXI.Polygon.prototype.contains = function(x, y) // constructor PIXI.Polygon.prototype.constructor = PIXI.Polygon; - + /** * @author Chad Engler */ @@ -449,8 +295,8 @@ PIXI.Polygon.prototype.constructor = PIXI.Polygon; * * @class Circle * @constructor - * @param x {Number} The X coordinate of the center of this circle - * @param y {Number} The Y coordinate of the center of this circle + * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this circle + * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this circle * @param radius {Number} The radius of the circle */ PIXI.Circle = function(x, y, radius) @@ -481,7 +327,7 @@ PIXI.Circle = function(x, y, radius) * Creates a clone of this Circle instance * * @method clone - * @return {Circle} a copy of the Circle + * @return {Circle} a copy of the polygon */ PIXI.Circle.prototype.clone = function() { @@ -489,12 +335,12 @@ PIXI.Circle.prototype.clone = function() }; /** - * Checks whether the x and y coordinates given are contained within this circle + * Checks whether the x, and y coordinates passed to this function are contained within this circle * * @method contains * @param x {Number} The X coordinate of the point to test * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Circle + * @return {Boolean} Whether the x/y coordinates are within this polygon */ PIXI.Circle.prototype.contains = function(x, y) { @@ -511,20 +357,10 @@ PIXI.Circle.prototype.contains = function(x, y) return (dx + dy <= r2); }; -/** -* Returns the framing rectangle of the circle as a PIXI.Rectangle object -* -* @method getBounds -* @return {Rectangle} the framing rectangle -*/ -PIXI.Circle.prototype.getBounds = function() -{ - return new PIXI.Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); -}; - // constructor PIXI.Circle.prototype.constructor = PIXI.Circle; + /** * @author Chad Engler */ @@ -534,10 +370,10 @@ PIXI.Circle.prototype.constructor = PIXI.Circle; * * @class Ellipse * @constructor - * @param x {Number} The X coordinate of the center of the ellipse - * @param y {Number} The Y coordinate of the center of the ellipse - * @param width {Number} The half width of this ellipse - * @param height {Number} The half height of this ellipse + * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse + * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse + * @param width {Number} The overall width of this ellipse + * @param height {Number} The overall height of this ellipse */ PIXI.Ellipse = function(x, y, width, height) { @@ -582,7 +418,7 @@ PIXI.Ellipse.prototype.clone = function() }; /** - * Checks whether the x and y coordinates given are contained within this ellipse + * Checks whether the x and y coordinates passed to this function are contained within this ellipse * * @method contains * @param x {Number} The X coordinate of the point to test @@ -612,178 +448,52 @@ PIXI.Ellipse.prototype.contains = function(x, y) */ PIXI.Ellipse.prototype.getBounds = function() { - return new PIXI.Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); + return new PIXI.Rectangle(this.x, this.y, this.width, this.height); }; // constructor PIXI.Ellipse.prototype.constructor = PIXI.Ellipse; - -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * The Rounded Rectangle object is an area defined by its position and has nice rounded corners, as indicated by its top-left corner point (x, y) and by its width and its height. - * - * @class RoundedRectangle - * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the rounded rectangle - * @param y {Number} The Y coordinate of the upper-left corner of the rounded rectangle - * @param width {Number} The overall width of this rounded rectangle - * @param height {Number} The overall height of this rounded rectangle - * @param radius {Number} The overall radius of this corners of this rounded rectangle - */ -PIXI.RoundedRectangle = function(x, y, width, height, radius) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; - - /** - * @property radius - * @type Number - * @default 20 - */ - this.radius = radius || 20; -}; - -/** - * Creates a clone of this Rounded Rectangle - * - * @method clone - * @return {RoundedRectangle} a copy of the rounded rectangle - */ -PIXI.RoundedRectangle.prototype.clone = function() -{ - return new PIXI.RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); -}; - -/** - * Checks whether the x and y coordinates given are contained within this Rounded Rectangle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Rounded Rectangle - */ -PIXI.RoundedRectangle.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; - - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } - - return false; -}; - -// constructor -PIXI.RoundedRectangle.prototype.constructor = PIXI.RoundedRectangle; - - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ -/** - * The Matrix class is now an object, which makes it a lot faster, - * here is a representation of it : - * | a | b | tx| - * | c | d | ty| - * | 0 | 0 | 1 | - * - * @class Matrix - * @constructor - */ +PIXI.determineMatrixArrayType = function() { + return (typeof Float32Array !== 'undefined') ? Float32Array : Array; +}; + +/* +* @class Matrix2 +* The Matrix2 class will choose the best type of array to use between +* a regular javascript Array and a Float32Array if the latter is available +* +*/ +PIXI.Matrix2 = PIXI.determineMatrixArrayType(); + +/* +* @class Matrix +* The Matrix class is now an object, which makes it a lot faster, +* here is a representation of it : +* | a | b | tx| +* | c | c | ty| +* | 0 | 0 | 1 | +* +*/ PIXI.Matrix = function() { - /** - * @property a - * @type Number - * @default 1 - */ this.a = 1; - - /** - * @property b - * @type Number - * @default 0 - */ this.b = 0; - - /** - * @property c - * @type Number - * @default 0 - */ this.c = 0; - - /** - * @property d - * @type Number - * @default 1 - */ this.d = 1; - - /** - * @property tx - * @type Number - * @default 0 - */ this.tx = 0; - - /** - * @property ty - * @type Number - * @default 0 - */ this.ty = 0; }; /** - * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows: - * - * a = array[0] - * b = array[1] - * c = array[3] - * d = array[4] - * tx = array[2] - * ty = array[5] + * Creates a pixi matrix object based on the array given as a parameter * * @method fromArray - * @param array {Array} The array that the matrix will be populated from. + * @param array {Array} The array that the matrix will be filled with */ PIXI.Matrix.prototype.fromArray = function(array) { @@ -796,199 +506,52 @@ PIXI.Matrix.prototype.fromArray = function(array) }; /** - * Creates an array from the current Matrix object. + * Creates an array from the current Matrix object * * @method toArray * @param transpose {Boolean} Whether we need to transpose the matrix or not - * @return {Array} the newly created array which contains the matrix + * @return array {Array} the newly created array which contains the matrix */ PIXI.Matrix.prototype.toArray = function(transpose) { - if(!this.array) this.array = new PIXI.Float32Array(9); + if(!this.array) this.array = new Float32Array(9); var array = this.array; if(transpose) { - array[0] = this.a; - array[1] = this.b; - array[2] = 0; - array[3] = this.c; - array[4] = this.d; - array[5] = 0; - array[6] = this.tx; - array[7] = this.ty; - array[8] = 1; + this.array[0] = this.a; + this.array[1] = this.c; + this.array[2] = 0; + this.array[3] = this.b; + this.array[4] = this.d; + this.array[5] = 0; + this.array[6] = this.tx; + this.array[7] = this.ty; + this.array[8] = 1; } else { - array[0] = this.a; - array[1] = this.c; - array[2] = this.tx; - array[3] = this.b; - array[4] = this.d; - array[5] = this.ty; - array[6] = 0; - array[7] = 0; - array[8] = 1; + this.array[0] = this.a; + this.array[1] = this.b; + this.array[2] = this.tx; + this.array[3] = this.c; + this.array[4] = this.d; + this.array[5] = this.ty; + this.array[6] = 0; + this.array[7] = 0; + this.array[8] = 1; } - return array; + return array;//[this.a, this.b, this.tx, this.c, this.d, this.ty, 0, 0, 1]; }; -/** - * Get a new position with the current transformation applied. - * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering) - * - * @method apply - * @param pos {Point} The origin - * @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input) - * @return {Point} The new point, transformed through this matrix - */ -PIXI.Matrix.prototype.apply = function(pos, newPos) -{ - newPos = newPos || new PIXI.Point(); - - newPos.x = this.a * pos.x + this.c * pos.y + this.tx; - newPos.y = this.b * pos.x + this.d * pos.y + this.ty; - - return newPos; -}; - -/** - * Get a new position with the inverse of the current transformation applied. - * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input) - * - * @method applyInverse - * @param pos {Point} The origin - * @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input) - * @return {Point} The new point, inverse-transformed through this matrix - */ -PIXI.Matrix.prototype.applyInverse = function(pos, newPos) -{ - newPos = newPos || new PIXI.Point(); - - var id = 1 / (this.a * this.d + this.c * -this.b); - - newPos.x = this.d * id * pos.x + -this.c * id * pos.y + (this.ty * this.c - this.tx * this.d) * id; - newPos.y = this.a * id * pos.y + -this.b * id * pos.x + (-this.ty * this.a + this.tx * this.b) * id; - - return newPos; -}; - -/** - * Translates the matrix on the x and y. - * - * @method translate - * @param {Number} x - * @param {Number} y - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.translate = function(x, y) -{ - this.tx += x; - this.ty += y; - - return this; -}; - -/** - * Applies a scale transformation to the matrix. - * - * @method scale - * @param {Number} x The amount to scale horizontally - * @param {Number} y The amount to scale vertically - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.scale = function(x, y) -{ - this.a *= x; - this.d *= y; - this.c *= x; - this.b *= y; - this.tx *= x; - this.ty *= y; - - return this; -}; - - -/** - * Applies a rotation transformation to the matrix. - * @method rotate - * @param {Number} angle The angle in radians. - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.rotate = function(angle) -{ - var cos = Math.cos( angle ); - var sin = Math.sin( angle ); - - var a1 = this.a; - var c1 = this.c; - var tx1 = this.tx; - - this.a = a1 * cos-this.b * sin; - this.b = a1 * sin+this.b * cos; - this.c = c1 * cos-this.d * sin; - this.d = c1 * sin+this.d * cos; - this.tx = tx1 * cos - this.ty * sin; - this.ty = tx1 * sin + this.ty * cos; - - return this; -}; - -/** - * Appends the given Matrix to this Matrix. - * - * @method append - * @param {Matrix} matrix - * @return {Matrix} This matrix. Good for chaining method calls. - */ -PIXI.Matrix.prototype.append = function(matrix) -{ - var a1 = this.a; - var b1 = this.b; - var c1 = this.c; - var d1 = this.d; - - this.a = matrix.a * a1 + matrix.b * c1; - this.b = matrix.a * b1 + matrix.b * d1; - this.c = matrix.c * a1 + matrix.d * c1; - this.d = matrix.c * b1 + matrix.d * d1; - - this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx; - this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty; - - return this; -}; - -/** - * Resets this Matix to an identity (default) matrix. - * - * @method identity - * @return {Matrix} This matrix. Good for chaining method calls. - */ -PIXI.Matrix.prototype.identity = function() -{ - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.tx = 0; - this.ty = 0; - - return this; -}; - -PIXI.identityMatrix = new PIXI.Matrix(); - +PIXI.identityMatrix = new PIXI.Matrix(); /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** * The base class for all objects that are rendered on the screen. - * This is an abstract class and should not be used on its own rather it should be extended. * * @class DisplayObject * @constructor @@ -1107,7 +670,7 @@ PIXI.DisplayObject = function() /** * This is the cursor that will be used when the mouse is over this object. To enable this the element must have interaction = true and buttonMode = true - * + * * @property defaultCursor * @type String * @@ -1118,38 +681,41 @@ PIXI.DisplayObject = function() * [read-only] Current transform of the object based on world (parent) factors * * @property worldTransform - * @type Matrix + * @type Mat3 * @readOnly * @private */ this.worldTransform = new PIXI.Matrix(); /** - * cached sin rotation and cos rotation + * [NYI] Unknown * - * @property _sr - * @type Number + * @property color + * @type Array<> * @private */ - this._sr = 0; + this.color = []; /** - * cached sin rotation and cos rotation + * [NYI] Holds whether or not this object is dynamic, for rendering optimization * - * @property _cr - * @type Number + * @property dynamic + * @type Boolean * @private */ + this.dynamic = true; + + // cached sin rotation and cos rotation + this._sr = 0; this._cr = 1; /** - * The area the filter is applied to like the hitArea this is used as more of an optimisation - * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle + * The area the filter is applied to * * @property filterArea * @type Rectangle */ - this.filterArea = null;//new PIXI.Rectangle(0,0,1,1); + this.filterArea = new PIXI.Rectangle(0,0,1,1); /** * The original, cached bounds of the object @@ -1159,7 +725,6 @@ PIXI.DisplayObject = function() * @private */ this._bounds = new PIXI.Rectangle(0, 0, 1, 1); - /** * The most up-to-date bounds of the object * @@ -1168,7 +733,6 @@ PIXI.DisplayObject = function() * @private */ this._currentBounds = null; - /** * The original, cached mask of the object * @@ -1178,29 +742,36 @@ PIXI.DisplayObject = function() */ this._mask = null; - /** - * Cached internal flag. - * - * @property _cacheAsBitmap - * @type Boolean - * @private - */ - this._cacheAsBitmap = false; - - /** - * Cached internal flag. - * - * @property _cacheIsDirty - * @type Boolean - * @private - */ - this._cacheIsDirty = false; - - /* * MOUSE Callbacks */ - + + /** + * A callback that is used when the users clicks on the displayObject with their mouse + * @method click + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user clicks the mouse down over the sprite + * @method mousedown + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases the mouse that was over the displayObject + * for this callback to be fired the mouse must have been pressed down over the displayObject + * @method mouseup + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject + * for this callback to be fired, The touch must have started over the displayObject + * @method mouseupoutside + * @param interactionData {InteractionData} + */ + /** * A callback that is used when the users mouse rolls over the displayObject * @method mouseover @@ -1213,59 +784,6 @@ PIXI.DisplayObject = function() * @param interactionData {InteractionData} */ - //Left button - /** - * A callback that is used when the users clicks on the displayObject with their mouse's left button - * @method click - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user clicks the mouse's left button down over the sprite - * @method mousedown - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's left button that was over the displayObject - * for this callback to be fired, the mouse's left button must have been pressed down over the displayObject - * @method mouseup - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's left button that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, the mouse's left button must have been pressed down over the displayObject - * @method mouseupoutside - * @param interactionData {InteractionData} - */ - - //Right button - /** - * A callback that is used when the users clicks on the displayObject with their mouse's right button - * @method rightclick - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user clicks the mouse's right button down over the sprite - * @method rightdown - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's right button that was over the displayObject - * for this callback to be fired the mouse's right button must have been pressed down over the displayObject - * @method rightup - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's right button that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, the mouse's right button must have been pressed down over the displayObject - * @method rightupoutside - * @param interactionData {InteractionData} - */ /* * TOUCH Callbacks @@ -1301,6 +819,19 @@ PIXI.DisplayObject = function() // constructor PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; +/** + * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default + * Instead of using this function you can now simply set the interactive property to true or false + * + * @method setInteractive + * @param interactive {Boolean} + * @deprecated Simply set the `interactive` property directly + */ +PIXI.DisplayObject.prototype.setInteractive = function(interactive) +{ + this.interactive = interactive; +}; + /** * Indicates if the sprite will have touch and mouse interactivity. It is false by default * @@ -1322,7 +853,7 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', { }); /** - * [read-only] Indicates if the sprite is globally visible. + * [read-only] Indicates if the sprite is globaly visible. * * @property worldVisible * @type Boolean @@ -1367,14 +898,12 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. * To remove filters simply set this property to 'null' * @property filters - * @type Array(Filter) + * @type Array An array of filters */ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { - get: function() { return this._filters; }, - set: function(value) { if(value) @@ -1398,36 +927,6 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { } }); -/** - * Set if this display object is cached as a bitmap. - * This basically takes a snap shot of the display object as it is at that moment. It can provide a performance benefit for complex static displayObjects. - * To remove simply set this property to 'null' - * @property cacheAsBitmap - * @type Boolean - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'cacheAsBitmap', { - - get: function() { - return this._cacheAsBitmap; - }, - - set: function(value) { - - if(this._cacheAsBitmap === value)return; - - if(value) - { - this._generateCachedSprite(); - } - else - { - this._destroyCachedSprite(); - } - - this._cacheAsBitmap = value; - } -}); - /* * Updates the object transform for rendering * @@ -1436,81 +935,48 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'cacheAsBitmap', { */ PIXI.DisplayObject.prototype.updateTransform = function() { - // create some matrix refs for easy access - var pt = this.parent.worldTransform; - var wt = this.worldTransform; - - // temporary matrix variables - var a, b, c, d, tx, ty; - - // so if rotation is between 0 then we can simplify the multiplication process.. - if(this.rotation % PIXI.PI_2) + // TODO OPTIMIZE THIS!! with dirty + if(this.rotation !== this.rotationCache) { - // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes - if(this.rotation !== this.rotationCache) - { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } - // get the matrix values of the displayobject based on its transform properties.. - a = this._cr * this.scale.x; - b = this._sr * this.scale.x; - c = -this._sr * this.scale.y; - d = this._cr * this.scale.y; - tx = this.position.x; - ty = this.position.y; - - // check for pivot.. not often used so geared towards that fact! - if(this.pivot.x || this.pivot.y) - { - tx -= this.pivot.x * a + this.pivot.y * c; - ty -= this.pivot.x * b + this.pivot.y * d; - } - - // concat the parent matrix with the objects transform. - wt.a = a * pt.a + b * pt.c; - wt.b = a * pt.b + b * pt.d; - wt.c = c * pt.a + d * pt.c; - wt.d = c * pt.b + d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; - - - } - else - { - // lets do the fast version as we know there is no rotation.. - a = this.scale.x; - d = this.scale.y; - - tx = this.position.x - this.pivot.x * a; - ty = this.position.y - this.pivot.y * d; - - wt.a = a * pt.a; - wt.b = a * pt.b; - wt.c = d * pt.c; - wt.d = d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; + this.rotationCache = this.rotation; + this._sr = Math.sin(this.rotation); + this._cr = Math.cos(this.rotation); } - // multiply the alphas.. + // var localTransform = this.localTransform//.toArray(); + var parentTransform = this.parent.worldTransform;//.toArray(); + var worldTransform = this.worldTransform;//.toArray(); + var px = this.pivot.x; + var py = this.pivot.y; + + var a00 = this._cr * this.scale.x, + a01 = -this._sr * this.scale.y, + a10 = this._sr * this.scale.x, + a11 = this._cr * this.scale.y, + a02 = this.position.x - a00 * px - py * a01, + a12 = this.position.y - a11 * py - px * a10, + b00 = parentTransform.a, b01 = parentTransform.b, + b10 = parentTransform.c, b11 = parentTransform.d; + + worldTransform.a = b00 * a00 + b01 * a10; + worldTransform.b = b00 * a01 + b01 * a11; + worldTransform.tx = b00 * a02 + b01 * a12 + parentTransform.tx; + + worldTransform.c = b10 * a00 + b11 * a10; + worldTransform.d = b10 * a01 + b11 * a11; + worldTransform.ty = b10 * a02 + b11 * a12 + parentTransform.ty; + this.worldAlpha = this.alpha * this.parent.worldAlpha; }; -// performance increase to avoid using call.. (10x faster) -PIXI.DisplayObject.prototype.displayObjectUpdateTransform = PIXI.DisplayObject.prototype.updateTransform; - /** * Retrieves the bounds of the displayObject as a rectangle object * * @method getBounds - * @param matrix {Matrix} * @return {Rectangle} the rectangular bounding area */ -PIXI.DisplayObject.prototype.getBounds = function(matrix) +PIXI.DisplayObject.prototype.getBounds = function( matrix ) { matrix = matrix;//just to get passed js hinting (and preserve inheritance) return PIXI.EmptyRectangle; @@ -1524,6 +990,8 @@ PIXI.DisplayObject.prototype.getBounds = function(matrix) */ PIXI.DisplayObject.prototype.getLocalBounds = function() { + //var matrixCache = this.worldTransform; + return this.getBounds(PIXI.identityMatrix);///PIXI.EmptyRectangle(); }; @@ -1539,159 +1007,11 @@ PIXI.DisplayObject.prototype.setStageReference = function(stage) if(this._interactive)this.stage.dirty = true; }; -/** - * Useful function that returns a texture of the displayObject object that can then be used to create sprites - * This can be quite useful if your displayObject is static / complicated and needs to be reused multiple times. - * - * @method generateTexture - * @param resolution {Number} The resolution of the texture being generated - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @param renderer {CanvasRenderer|WebGLRenderer} The renderer used to generate the texture. - * @return {Texture} a texture of the graphics object - */ -PIXI.DisplayObject.prototype.generateTexture = function(resolution, scaleMode, renderer) -{ - var bounds = this.getLocalBounds(); - - var renderTexture = new PIXI.RenderTexture(bounds.width | 0, bounds.height | 0, renderer, scaleMode, resolution); - - PIXI.DisplayObject._tempMatrix.tx = -bounds.x; - PIXI.DisplayObject._tempMatrix.ty = -bounds.y; - - renderTexture.render(this, PIXI.DisplayObject._tempMatrix); - - return renderTexture; -}; - -/** - * Generates and updates the cached sprite for this object. - * - * @method updateCache - */ -PIXI.DisplayObject.prototype.updateCache = function() -{ - this._generateCachedSprite(); -}; - -/** - * Calculates the global position of the display object - * - * @method toGlobal - * @param position {Point} The world origin to calculate from - * @return {Point} A point object representing the position of this object - */ -PIXI.DisplayObject.prototype.toGlobal = function(position) -{ - // don't need to u[date the lot - this.displayObjectUpdateTransform(); - return this.worldTransform.apply(position); -}; - -/** - * Calculates the local position of the display object relative to another point - * - * @method toLocal - * @param position {Point} The world origin to calculate from - * @param [from] {DisplayObject} The DisplayObject to calculate the global position from - * @return {Point} A point object representing the position of this object - */ -PIXI.DisplayObject.prototype.toLocal = function(position, from) -{ - // - if (from) - { - position = from.toGlobal(position); - } - - // don't need to u[date the lot - this.displayObjectUpdateTransform(); - return this.worldTransform.applyInverse(position); -}; - -/** - * Internal method. - * - * @method _renderCachedSprite - * @param renderSession {Object} The render session - * @private - */ -PIXI.DisplayObject.prototype._renderCachedSprite = function(renderSession) -{ - this._cachedSprite.worldAlpha = this.worldAlpha; - - if(renderSession.gl) - { - PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession); - } - else - { - PIXI.Sprite.prototype._renderCanvas.call(this._cachedSprite, renderSession); - } -}; - -/** - * Internal method. - * - * @method _generateCachedSprite - * @private - */ -PIXI.DisplayObject.prototype._generateCachedSprite = function() -{ - this._cacheAsBitmap = false; - var bounds = this.getLocalBounds(); - - if(!this._cachedSprite) - { - var renderTexture = new PIXI.RenderTexture(bounds.width | 0, bounds.height | 0);//, renderSession.renderer); - - this._cachedSprite = new PIXI.Sprite(renderTexture); - this._cachedSprite.worldTransform = this.worldTransform; - } - else - { - this._cachedSprite.texture.resize(bounds.width | 0, bounds.height | 0); - } - - //REMOVE filter! - var tempFilters = this._filters; - this._filters = null; - - this._cachedSprite.filters = tempFilters; - - PIXI.DisplayObject._tempMatrix.tx = -bounds.x; - PIXI.DisplayObject._tempMatrix.ty = -bounds.y; - - this._cachedSprite.texture.render(this, PIXI.DisplayObject._tempMatrix, true); - - this._cachedSprite.anchor.x = -( bounds.x / bounds.width ); - this._cachedSprite.anchor.y = -( bounds.y / bounds.height ); - - this._filters = tempFilters; - - this._cacheAsBitmap = true; -}; - -/** -* Destroys the cached sprite. -* -* @method _destroyCachedSprite -* @private -*/ -PIXI.DisplayObject.prototype._destroyCachedSprite = function() -{ - if(!this._cachedSprite)return; - - this._cachedSprite.texture.destroy(true); - - // TODO could be object pooled! - this._cachedSprite = null; -}; - /** * Renders the object using the WebGL renderer * * @method _renderWebGL -* @param renderSession {RenderSession} +* @param renderSession {RenderSession} * @private */ PIXI.DisplayObject.prototype._renderWebGL = function(renderSession) @@ -1705,7 +1025,7 @@ PIXI.DisplayObject.prototype._renderWebGL = function(renderSession) * Renders the object using the Canvas renderer * * @method _renderCanvas -* @param renderSession {RenderSession} +* @param renderSession {RenderSession} * @private */ PIXI.DisplayObject.prototype._renderCanvas = function(renderSession) @@ -1715,9 +1035,6 @@ PIXI.DisplayObject.prototype._renderCanvas = function(renderSession) renderSession = renderSession; }; - -PIXI.DisplayObject._tempMatrix = new PIXI.Matrix(); - /** * The position of the displayObject on the x axis relative to the local coordinates of the parent. * @@ -1747,11 +1064,12 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'y', { this.position.y = value; } }); - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ + /** * A DisplayObjectContainer represents a collection of display objects. * It is the base class of all display objects that act as a container for other objects. @@ -1768,47 +1086,34 @@ PIXI.DisplayObjectContainer = function() * [read-only] The array of children of this container. * * @property children - * @type Array(DisplayObject) + * @type Array * @readOnly */ this.children = []; - - // fast access to update transform.. - }; // constructor PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; - /** * The width of the displayObjectContainer, setting this will actually modify the scale to achieve the value set * * @property width * @type Number */ + + /* Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', { get: function() { return this.scale.x * this.getLocalBounds().width; }, set: function(value) { - - var width = this.getLocalBounds().width; - - if(width !== 0) - { - this.scale.x = value / width; - } - else - { - this.scale.x = 1; - } - - + this.scale.x = value / (this.getLocalBounds().width/this.scale.x); this._width = value; } }); +*/ /** * The height of the displayObjectContainer, setting this will actually modify the scale to achieve the value set @@ -1816,37 +1121,28 @@ Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', { * @property height * @type Number */ + +/* Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'height', { get: function() { return this.scale.y * this.getLocalBounds().height; }, set: function(value) { - - var height = this.getLocalBounds().height; - - if(height !== 0) - { - this.scale.y = value / height ; - } - else - { - this.scale.y = 1; - } - + this.scale.y = value / (this.getLocalBounds().height/this.scale.y); this._height = value; } }); +*/ /** * Adds a child to the container. * * @method addChild * @param child {DisplayObject} The DisplayObject to add to the container - * @return {DisplayObject} The child that was added. */ PIXI.DisplayObjectContainer.prototype.addChild = function(child) { - return this.addChildAt(child, this.children.length); + this.addChildAt(child, this.children.length); }; /** @@ -1855,7 +1151,6 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child) * @method addChildAt * @param child {DisplayObject} The child to add * @param index {Number} The index to place the child in - * @return {DisplayObject} The child that was added. */ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) { @@ -1871,21 +1166,20 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) this.children.splice(index, 0, child); if(this.stage)child.setStageReference(this.stage); - - return child; } else { - throw new Error(child + 'addChildAt: The index '+ index +' supplied is out of bounds ' + this.children.length); + throw new Error(child + ' The index '+ index +' supplied is out of bounds ' + this.children.length); } }; /** - * Swaps the position of 2 Display Objects within this container. + * [NYI] Swaps the depth of 2 displayObjects * * @method swapChildren * @param child {DisplayObject} * @param child2 {DisplayObject} + * @private */ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) { @@ -1893,8 +1187,8 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) return; } - var index1 = this.getChildIndex(child); - var index2 = this.getChildIndex(child2); + var index1 = this.children.indexOf(child); + var index2 = this.children.indexOf(child2); if(index1 < 0 || index2 < 0) { throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.'); @@ -1902,42 +1196,7 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) this.children[index1] = child2; this.children[index2] = child; - -}; - -/** - * Returns the index position of a child DisplayObject instance - * - * @method getChildIndex - * @param child {DisplayObject} The DisplayObject instance to identify - * @return {Number} The index position of the child display object to identify - */ -PIXI.DisplayObjectContainer.prototype.getChildIndex = function(child) -{ - var index = this.children.indexOf(child); - if (index === -1) - { - throw new Error('The supplied DisplayObject must be a child of the caller'); - } - return index; -}; - -/** - * Changes the position of an existing child in the display object container - * - * @method setChildIndex - * @param child {DisplayObject} The child DisplayObject instance for which you want to change the index number - * @param index {Number} The resulting index number for the child display object - */ -PIXI.DisplayObjectContainer.prototype.setChildIndex = function(child, index) -{ - if (index < 0 || index >= this.children.length) - { - throw new Error('The supplied index is out of bounds'); - } - var currentIndex = this.getChildIndex(child); - this.children.splice(currentIndex, 1); //remove from old position - this.children.splice(index, 0, child); //add at new position + }; /** @@ -1945,16 +1204,17 @@ PIXI.DisplayObjectContainer.prototype.setChildIndex = function(child, index) * * @method getChildAt * @param index {Number} The index to get the child from - * @return {DisplayObject} The child at the given index, if any. */ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) { - if (index < 0 || index >= this.children.length) + if(index >= 0 && index < this.children.length) { - throw new Error('getChildAt: Supplied index '+ index +' does not exist in the child list, or the supplied DisplayObject must be a child of the caller'); + return this.children[index]; + } + else + { + throw new Error('The supplied DisplayObjects must be a child of the caller ' + this); } - return this.children[index]; - }; /** @@ -1962,83 +1222,55 @@ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) * * @method removeChild * @param child {DisplayObject} The DisplayObject to remove - * @return {DisplayObject} The child that was removed. */ PIXI.DisplayObjectContainer.prototype.removeChild = function(child) { var index = this.children.indexOf( child ); - if(index === -1)return; - - return this.removeChildAt( index ); -}; - -/** - * Removes a child from the specified index position. - * - * @method removeChildAt - * @param index {Number} The index to get the child from - * @return {DisplayObject} The child that was removed. - */ -PIXI.DisplayObjectContainer.prototype.removeChildAt = function(index) -{ - var child = this.getChildAt( index ); - if(this.stage) - child.removeStageReference(); - - child.parent = undefined; - this.children.splice( index, 1 ); - return child; -}; - -/** -* Removes all children from this container that are within the begin and end indexes. -* -* @method removeChildren -* @param beginIndex {Number} The beginning position. Default value is 0. -* @param endIndex {Number} The ending position. Default value is size of the container. -*/ -PIXI.DisplayObjectContainer.prototype.removeChildren = function(beginIndex, endIndex) -{ - var begin = beginIndex || 0; - var end = typeof endIndex === 'number' ? endIndex : this.children.length; - var range = end - begin; - - if (range > 0 && range <= end) + if ( index !== -1 ) { - var removed = this.children.splice(begin, range); - for (var i = 0; i < removed.length; i++) { - var child = removed[i]; - if(this.stage) - child.removeStageReference(); - child.parent = undefined; - } - return removed; - } - else if (range === 0 && this.children.length === 0) - { - return []; + // update the stage reference.. + if(this.stage)child.removeStageReference(); + + child.parent = undefined; + this.children.splice( index, 1 ); } else { - throw new Error( 'removeChildren: Range Error, numeric values are outside the acceptable range' ); + throw new Error(child + ' The supplied DisplayObject must be a child of the caller ' + this); } }; + +/** +* Removes all the children +* +* @method removeAll +* NOT tested yet +*/ +/* PIXI.DisplayObjectContainer.prototype.removeAll = function() +{ + + + for(var i = 0 , j = this.children.length; i < j; i++) + { + this.removeChild(this.children[i]); + } + +}; +*/ /* - * Updates the transform on all children of this container for rendering + * Updates the container's childrens transform for rendering * * @method updateTransform * @private */ PIXI.DisplayObjectContainer.prototype.updateTransform = function() { + //this._currentBounds = null; + if(!this.visible)return; - this.displayObjectUpdateTransform(); - - //PIXI.DisplayObject.prototype.updateTransform.call( this ); - - if(this._cacheAsBitmap)return; + PIXI.DisplayObject.prototype.updateTransform.call( this ); for(var i=0,j=this.children.length; i maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; - var x3 = a * w0 + c * h0 + tx; - var y3 = d * h0 + b * w0 + ty; - - var x4 = a * w1 + c * h0 + tx; - var y4 = d * h0 + b * w1 + ty; - - minX = x1 < minX ? x1 : minX; - minX = x2 < minX ? x2 : minX; - minX = x3 < minX ? x3 : minX; - minX = x4 < minX ? x4 : minX; - - minY = y1 < minY ? y1 : minY; - minY = y2 < minY ? y2 : minY; - minY = y3 < minY ? y3 : minY; - minY = y4 < minY ? y4 : minY; - - maxX = x1 > maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - } + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; var bounds = this._bounds; @@ -2525,14 +1728,14 @@ PIXI.Sprite.prototype.getBounds = function(matrix) * Renders the object using the WebGL renderer * * @method _renderWebGL -* @param renderSession {RenderSession} +* @param renderSession {RenderSession} * @private */ PIXI.Sprite.prototype._renderWebGL = function(renderSession) { // if the sprite is not visible or the alpha is 0 then no need to render this element if(!this.visible || this.alpha <= 0)return; - + var i,j; // do a quick check to see if this element has a mask or a filter. @@ -2540,13 +1743,6 @@ PIXI.Sprite.prototype._renderWebGL = function(renderSession) { var spriteBatch = renderSession.spriteBatch; - // push filter first as we need to ensure the stencil buffer is correct for any masking - if(this._filters) - { - spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - if(this._mask) { spriteBatch.stop(); @@ -2554,6 +1750,12 @@ PIXI.Sprite.prototype._renderWebGL = function(renderSession) spriteBatch.start(); } + if(this._filters) + { + spriteBatch.flush(); + renderSession.filterManager.pushFilter(this._filterBlock); + } + // add this sprite to the batch spriteBatch.render(this); @@ -2566,9 +1768,9 @@ PIXI.Sprite.prototype._renderWebGL = function(renderSession) // time to stop the sprite batch as either a mask element or a filter draw will happen next spriteBatch.stop(); - if(this._mask)renderSession.maskManager.popMask(this._mask, renderSession); if(this._filters)renderSession.filterManager.popFilter(); - + if(this._mask)renderSession.maskManager.popMask(renderSession); + spriteBatch.start(); } else @@ -2580,127 +1782,141 @@ PIXI.Sprite.prototype._renderWebGL = function(renderSession) { this.children[i]._renderWebGL(renderSession); } - } + + + //TODO check culling }; /** * Renders the object using the Canvas renderer * * @method _renderCanvas -* @param renderSession {RenderSession} +* @param renderSession {RenderSession} * @private */ PIXI.Sprite.prototype._renderCanvas = function(renderSession) { - // If the sprite is not visible or the alpha is 0 then no need to render this element - if (this.visible === false || this.alpha === 0 || this.texture.crop.width <= 0 || this.texture.crop.height <= 0) return; + // if the sprite is not visible or the alpha is 0 then no need to render this element + if(this.visible === false || this.alpha === 0)return; + + var frame = this.texture.frame; + var context = renderSession.context; + var texture = this.texture; - if (this.blendMode !== renderSession.currentBlendMode) + if(this.blendMode !== renderSession.currentBlendMode) { renderSession.currentBlendMode = this.blendMode; - renderSession.context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; } - if (this._mask) + if(this._mask) { - renderSession.maskManager.pushMask(this._mask, renderSession); + renderSession.maskManager.pushMask(this._mask, renderSession.context); } - // Ignore null sources - if (this.texture.valid) + + + //ignore null sources + if(frame && frame.width && frame.height && texture.baseTexture.source) { - var resolution = this.texture.baseTexture.resolution / renderSession.resolution; + context.globalAlpha = this.worldAlpha; - renderSession.context.globalAlpha = this.worldAlpha; + var transform = this.worldTransform; - // If smoothingEnabled is supported and we need to change the smoothing property for this texture - if (renderSession.smoothProperty && renderSession.scaleMode !== this.texture.baseTexture.scaleMode) - { - renderSession.scaleMode = this.texture.baseTexture.scaleMode; - renderSession.context[renderSession.smoothProperty] = (renderSession.scaleMode === PIXI.scaleModes.LINEAR); - } - - // If the texture is trimmed we offset by the trim x/y, otherwise we use the frame dimensions - var dx = (this.texture.trim) ? this.texture.trim.x - this.anchor.x * this.texture.trim.width : this.anchor.x * -this.texture.frame.width; - var dy = (this.texture.trim) ? this.texture.trim.y - this.anchor.y * this.texture.trim.height : this.anchor.y * -this.texture.frame.height; - - // Allow for pixel rounding + // allow for trimming + if (renderSession.roundPixels) { - renderSession.context.setTransform( - this.worldTransform.a, - this.worldTransform.b, - this.worldTransform.c, - this.worldTransform.d, - (this.worldTransform.tx * renderSession.resolution) | 0, - (this.worldTransform.ty * renderSession.resolution) | 0); - - dx = dx | 0; - dy = dy | 0; + context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx || 0, transform.ty || 0); } else { - renderSession.context.setTransform( - this.worldTransform.a, - this.worldTransform.b, - this.worldTransform.c, - this.worldTransform.d, - this.worldTransform.tx * renderSession.resolution, - this.worldTransform.ty * renderSession.resolution); + context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); } - - - if (this.tint !== 0xFFFFFF) + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if(renderSession.smoothProperty && renderSession.scaleMode !== this.texture.baseTexture.scaleMode) { + renderSession.scaleMode = this.texture.baseTexture.scaleMode; + context[renderSession.smoothProperty] = (renderSession.scaleMode === PIXI.scaleModes.LINEAR); + } + + if(this.tint !== 0xFFFFFF) { - if (this.cachedTint !== this.tint) + + if(this.cachedTint !== this.tint) { - this.cachedTint = this.tint; + // no point tinting an image that has not loaded yet! + if(!texture.baseTexture.hasLoaded)return; - // TODO clean up caching - how to clean up the caches? + this.cachedTint = this.tint; + + //TODO clean up caching - how to clean up the caches? this.tintedTexture = PIXI.CanvasTinter.getTintedTexture(this, this.tint); + } - renderSession.context.drawImage( - this.tintedTexture, - 0, - 0, - this.texture.crop.width, - this.texture.crop.height, - dx / resolution, - dy / resolution, - this.texture.crop.width / resolution, - this.texture.crop.height / resolution); + context.drawImage(this.tintedTexture, + 0, + 0, + frame.width, + frame.height, + (this.anchor.x) * -frame.width, + (this.anchor.y) * -frame.height, + frame.width, + frame.height); } else { - renderSession.context.drawImage( - this.texture.baseTexture.source, - this.texture.crop.x, - this.texture.crop.y, - this.texture.crop.width, - this.texture.crop.height, - dx / resolution, - dy / resolution, - this.texture.crop.width / resolution, - this.texture.crop.height / resolution); + + + + if(texture.trim) + { + var trim = texture.trim; + + context.drawImage(this.texture.baseTexture.source, + frame.x, + frame.y, + frame.width, + frame.height, + trim.x - this.anchor.x * trim.width, + trim.y - this.anchor.y * trim.height, + frame.width, + frame.height); + } + else + { + + context.drawImage(this.texture.baseTexture.source, + frame.x, + frame.y, + frame.width, + frame.height, + (this.anchor.x) * -frame.width, + (this.anchor.y) * -frame.height, + frame.width, + frame.height); + } + } } // OVERWRITE - for (var i = 0, j = this.children.length; i < j; i++) + for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation */ PIXI.MovieClip = function(textures) { @@ -2934,7 +2147,7 @@ PIXI.MovieClip = function(textures) * The array of textures that make up the animation * * @property textures - * @type Array(Texture) + * @type Array */ this.textures = textures; @@ -2998,12 +2211,13 @@ PIXI.MovieClip.prototype.constructor = PIXI.MovieClip; * @readOnly */ Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', { - get: function() { + get: function() { - return this.textures.length; - } + return this.textures.length; + } }); + /** * Stops the MovieClip * @@ -3058,7 +2272,7 @@ PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber) */ PIXI.MovieClip.prototype.updateTransform = function() { - this.displayObjectContainerUpdateTransform(); + PIXI.Sprite.prototype.updateTransform.call(this); if(!this.playing)return; @@ -3066,8 +2280,6 @@ PIXI.MovieClip.prototype.updateTransform = function() var round = (this.currentFrame + 0.5) | 0; - this.currentFrame = this.currentFrame % this.textures.length; - if(this.loop || round < this.textures.length) { this.setTexture(this.textures[round % this.textures.length]); @@ -3081,84 +2293,26 @@ PIXI.MovieClip.prototype.updateTransform = function() } } }; - -/** - * A short hand way of creating a movieclip from an array of frame ids - * - * @static - * @method fromFrames - * @param frames {Array} the array of frames ids the movieclip will use as its texture frames - */ -PIXI.MovieClip.fromFrames = function(frames) -{ - var textures = []; - - for (var i = 0; i < frames.length; i++) - { - textures.push(new PIXI.Texture.fromFrame(frames[i])); - } - - return new PIXI.MovieClip(textures); -}; - -/** - * A short hand way of creating a movieclip from an array of image ids - * - * @static - * @method fromImages - * @param frames {Array} the array of image ids the movieclip will use as its texture frames - */ -PIXI.MovieClip.fromImages = function(images) -{ - var textures = []; - - for (var i = 0; i < images.length; i++) - { - textures.push(new PIXI.Texture.fromImage(images[i])); - } - - return new PIXI.MovieClip(textures); -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ -/** - * A target and pass info object for filters. - * - * @class FilterBlock - * @constructor - */ + PIXI.FilterBlock = function() { - /** - * The visible state of this FilterBlock. - * - * @property visible - * @type Boolean - */ this.visible = true; - - /** - * The renderable state of this FilterBlock. - * - * @property renderable - * @type Boolean - */ this.renderable = true; }; - -PIXI.FilterBlock.prototype.constructor = PIXI.FilterBlock; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 - * Modified by Tom Slezakowski http://www.tomslezakowski.com @TomSlezakowski (24/03/2014) - Added dropShadowColor. */ /** - * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string, - * or add a wordWrap property set to true and and wordWrapWidth property with a value in the style object. + * A Text Object will create a line(s) of text. To split a line you can use '\n' + * or add a wordWrap property set to true and and wordWrapWidth property with a value + * in the style object * * @class Text * @extends Sprite @@ -3172,10 +2326,6 @@ PIXI.FilterBlock.prototype.constructor = PIXI.FilterBlock; * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap, it needs wordWrap to be set to true - * @param [style.dropShadow=false] {Boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {String} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {Number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {Number} Set a distance of the drop shadow */ PIXI.Text = function(text, style) { @@ -3190,76 +2340,23 @@ PIXI.Text = function(text, style) /** * The canvas 2d context that everything is drawn with * @property context - * @type HTMLCanvasElement + * @type HTMLCanvasElement 2d Context */ this.context = this.canvas.getContext('2d'); - /** - * The resolution of the canvas. - * @property resolution - * @type Number - */ - this.resolution = 1; - PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas)); this.setText(text); this.setStyle(style); + this.updateText(); + this.dirty = false; }; // constructor PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype); PIXI.Text.prototype.constructor = PIXI.Text; -/** - * The width of the Text, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.Text.prototype, 'width', { - get: function() { - - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - - return this.scale.x * this.texture.frame.width; - }, - set: function(value) { - this.scale.x = value / this.texture.frame.width; - this._width = value; - } -}); - -/** - * The height of the Text, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.Text.prototype, 'height', { - get: function() { - - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - - return this.scale.y * this.texture.frame.height; - }, - set: function(value) { - this.scale.y = value / this.texture.frame.height; - this._height = value; - } -}); - /** * Set the style of the text * @@ -3272,10 +2369,6 @@ Object.defineProperty(PIXI.Text.prototype, 'height', { * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap - * @param [style.dropShadow=false] {Boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {String} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {Number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {Number} Set a distance of the drop shadow */ PIXI.Text.prototype.setStyle = function(style) { @@ -3287,26 +2380,21 @@ PIXI.Text.prototype.setStyle = function(style) style.strokeThickness = style.strokeThickness || 0; style.wordWrap = style.wordWrap || false; style.wordWrapWidth = style.wordWrapWidth || 100; - - style.dropShadow = style.dropShadow || false; - style.dropShadowAngle = style.dropShadowAngle || Math.PI / 6; - style.dropShadowDistance = style.dropShadowDistance || 4; - style.dropShadowColor = style.dropShadowColor || 'black'; - this.style = style; this.dirty = true; }; /** - * Set the copy for the text object. To split a line you can use '\n'. + * Set the copy for the text object. To split a line you can use '\n' * * @method setText - * @param text {String} The copy that you would like the text to display + * @param {String} text The copy that you would like the text to display */ PIXI.Text.prototype.setText = function(text) { this.text = text.toString() || ' '; this.dirty = true; + }; /** @@ -3317,8 +2405,6 @@ PIXI.Text.prototype.setText = function(text) */ PIXI.Text.prototype.updateText = function() { - this.texture.baseTexture.resolution = this.resolution; - this.context.font = this.style.font; var outputText = this.text; @@ -3333,103 +2419,52 @@ PIXI.Text.prototype.updateText = function() //calculate text width var lineWidths = []; var maxLineWidth = 0; - var fontProperties = this.determineFontProperties(this.style.font); for (var i = 0; i < lines.length; i++) { var lineWidth = this.context.measureText(lines[i]).width; lineWidths[i] = lineWidth; maxLineWidth = Math.max(maxLineWidth, lineWidth); } + this.canvas.width = maxLineWidth + this.style.strokeThickness; - var width = maxLineWidth + this.style.strokeThickness; - if(this.style.dropShadow)width += this.style.dropShadowDistance; - - this.canvas.width = ( width + this.context.lineWidth ) * this.resolution; - //calculate text height - var lineHeight = fontProperties.fontSize + this.style.strokeThickness; - - var height = lineHeight * lines.length; - if(this.style.dropShadow)height += this.style.dropShadowDistance; - - this.canvas.height = height * this.resolution; - - this.context.scale( this.resolution, this.resolution); + var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness; + this.canvas.height = lineHeight * lines.length; if(navigator.isCocoonJS) this.context.clearRect(0,0,this.canvas.width,this.canvas.height); - // used for debugging.. - //this.context.fillStyle ="#FF0000" - //this.context.fillRect(0, 0, this.canvas.width,this.canvas.height); - - this.context.font = this.style.font; - this.context.strokeStyle = this.style.stroke; - this.context.lineWidth = this.style.strokeThickness; - this.context.textBaseline = 'alphabetic'; - //this.context.lineJoin = 'round'; - - var linePositionX; - var linePositionY; - - if(this.style.dropShadow) - { - this.context.fillStyle = this.style.dropShadowColor; - - var xShadowOffset = Math.sin(this.style.dropShadowAngle) * this.style.dropShadowDistance; - var yShadowOffset = Math.cos(this.style.dropShadowAngle) * this.style.dropShadowDistance; - - for (i = 0; i < lines.length; i++) - { - linePositionX = this.style.strokeThickness / 2; - linePositionY = (this.style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent; - - if(this.style.align === 'right') - { - linePositionX += maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - linePositionX += (maxLineWidth - lineWidths[i]) / 2; - } - - if(this.style.fill) - { - this.context.fillText(lines[i], linePositionX + xShadowOffset, linePositionY + yShadowOffset); - } - - // if(dropShadow) - } - } - //set canvas text styles this.context.fillStyle = this.style.fill; - + this.context.font = this.style.font; + + this.context.strokeStyle = this.style.stroke; + this.context.lineWidth = this.style.strokeThickness; + + this.context.textBaseline = 'top'; + //draw lines line by line for (i = 0; i < lines.length; i++) { - linePositionX = this.style.strokeThickness / 2; - linePositionY = (this.style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent; + var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); if(this.style.align === 'right') { - linePositionX += maxLineWidth - lineWidths[i]; + linePosition.x += maxLineWidth - lineWidths[i]; } else if(this.style.align === 'center') { - linePositionX += (maxLineWidth - lineWidths[i]) / 2; + linePosition.x += (maxLineWidth - lineWidths[i]) / 2; } if(this.style.stroke && this.style.strokeThickness) { - this.context.strokeText(lines[i], linePositionX, linePositionY); + this.context.strokeText(lines[i], linePosition.x, linePosition.y); } if(this.style.fill) { - this.context.fillText(lines[i], linePositionX, linePositionY); + this.context.fillText(lines[i], linePosition.x, linePosition.y); } - - // if(dropShadow) } this.updateTexture(); @@ -3445,14 +2480,13 @@ PIXI.Text.prototype.updateTexture = function() { this.texture.baseTexture.width = this.canvas.width; this.texture.baseTexture.height = this.canvas.height; - this.texture.crop.width = this.texture.frame.width = this.canvas.width; - this.texture.crop.height = this.texture.frame.height = this.canvas.height; + this.texture.frame.width = this.canvas.width; + this.texture.frame.height = this.canvas.height; this._width = this.canvas.width; this._height = this.canvas.height; - // update the dirty base textures - this.texture.baseTexture.dirty(); + this.requiresUpdate = true; }; /** @@ -3464,140 +2498,63 @@ PIXI.Text.prototype.updateTexture = function() */ PIXI.Text.prototype._renderWebGL = function(renderSession) { - if(this.dirty) + if(this.requiresUpdate) { - this.resolution = renderSession.resolution; - - this.updateText(); - this.dirty = false; + this.requiresUpdate = false; + PIXI.updateWebGLTexture(this.texture.baseTexture, renderSession.gl); } PIXI.Sprite.prototype._renderWebGL.call(this, renderSession); }; /** -* Renders the object using the Canvas renderer -* -* @method _renderCanvas -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Text.prototype._renderCanvas = function(renderSession) + * Updates the transform of this object + * + * @method updateTransform + * @private + */ +PIXI.Text.prototype.updateTransform = function() { if(this.dirty) { - this.resolution = renderSession.resolution; - this.updateText(); this.dirty = false; } - - PIXI.Sprite.prototype._renderCanvas.call(this, renderSession); + + PIXI.Sprite.prototype.updateTransform.call(this); }; -/** -* Calculates the ascent, descent and fontSize of a given fontStyle -* -* @method determineFontProperties -* @param fontStyle {Object} -* @private -*/ -PIXI.Text.prototype.determineFontProperties = function(fontStyle) +/* + * http://stackoverflow.com/users/34441/ellisbben + * great solution to the problem! + * returns the height of the given font + * + * @method determineFontHeight + * @param fontStyle {Object} + * @private + */ +PIXI.Text.prototype.determineFontHeight = function(fontStyle) { - var properties = PIXI.Text.fontPropertiesCache[fontStyle]; + // build a little reference dictionary so if the font style has been used return a + // cached version... + var result = PIXI.Text.heightCache[fontStyle]; - if(!properties) + if(!result) { - properties = {}; - - var canvas = PIXI.Text.fontPropertiesCanvas; - var context = PIXI.Text.fontPropertiesContext; + var body = document.getElementsByTagName('body')[0]; + var dummy = document.createElement('div'); + var dummyText = document.createTextNode('M'); + dummy.appendChild(dummyText); + dummy.setAttribute('style', fontStyle + ';position:absolute;top:0;left:0'); + body.appendChild(dummy); - context.font = fontStyle; + result = dummy.offsetHeight; + PIXI.Text.heightCache[fontStyle] = result; - var width = Math.ceil(context.measureText('|Mq').width); - var baseline = Math.ceil(context.measureText('M').width); - var height = 2 * baseline; - - baseline = baseline * 1.4 | 0; - - canvas.width = width; - canvas.height = height; - - context.fillStyle = '#f00'; - context.fillRect(0, 0, width, height); - - context.font = fontStyle; - - context.textBaseline = 'alphabetic'; - context.fillStyle = '#000'; - context.fillText('|MÉq', 0, baseline); - - var imagedata = context.getImageData(0, 0, width, height).data; - var pixels = imagedata.length; - var line = width * 4; - - var i, j; - - var idx = 0; - var stop = false; - - // ascent. scan from top to bottom until we find a non red pixel - for(i = 0; i < baseline; i++) - { - for(j = 0; j < line; j += 4) - { - if(imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - if(!stop) - { - idx += line; - } - else - { - break; - } - } - - properties.ascent = baseline - i; - - idx = pixels - line; - stop = false; - - // descent. scan from bottom to top until we find a non red pixel - for(i = height; i > baseline; i--) - { - for(j = 0; j < line; j += 4) - { - if(imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - if(!stop) - { - idx -= line; - } - else - { - break; - } - } - - properties.descent = i - baseline; - //TODO might need a tweak. kind of a temp fix! - properties.descent += 6; - properties.fontSize = properties.ascent + properties.descent; - - PIXI.Text.fontPropertiesCache[fontStyle] = properties; + body.removeChild(dummy); } - return properties; + return result; }; /** @@ -3622,7 +2579,7 @@ PIXI.Text.prototype.wordWrap = function(text) { var wordWidth = this.context.measureText(words[j]).width; var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; - if(j === 0 || wordWidthWithSpace > spaceLeft) + if(wordWidthWithSpace > spaceLeft) { // Skip printing the newline if it's the first word of the line that is // greater than the word wrap width. @@ -3630,13 +2587,13 @@ PIXI.Text.prototype.wordWrap = function(text) { result += '\n'; } - result += words[j]; + result += words[j] + ' '; spaceLeft = this.style.wordWrapWidth - wordWidth; } else { spaceLeft -= wordWidthWithSpace; - result += ' ' + words[j]; + result += words[j] + ' '; } } @@ -3649,48 +2606,28 @@ PIXI.Text.prototype.wordWrap = function(text) }; /** -* Returns the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account. -* -* @method getBounds -* @param matrix {Matrix} the transformation matrix of the Text -* @return {Rectangle} the framing rectangle -*/ -PIXI.Text.prototype.getBounds = function(matrix) -{ - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - return PIXI.Sprite.prototype.getBounds.call(this, matrix); -}; - -/** - * Destroys this text object. + * Destroys this text object * * @method destroy - * @param destroyBaseTexture {Boolean} whether to destroy the base texture as well + * @param destroyTexture {Boolean} */ -PIXI.Text.prototype.destroy = function(destroyBaseTexture) +PIXI.Text.prototype.destroy = function(destroyTexture) { - // make sure to reset the the context and canvas.. dont want this hanging around in memory! - this.context = null; - this.canvas = null; + if(destroyTexture) + { + this.texture.destroy(); + } - this.texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); }; -PIXI.Text.fontPropertiesCache = {}; -PIXI.Text.fontPropertiesCanvas = document.createElement('canvas'); -PIXI.Text.fontPropertiesContext = PIXI.Text.fontPropertiesCanvas.getContext('2d'); - +PIXI.Text.heightCache = {}; + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * A BitmapText object will create a line or multiple lines of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' in your string. + * A Text Object will create a line(s) of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' * You can generate the fnt files using * http://www.angelcode.com/products/bmfont/ for windows or * http://www.bmglyph.com/ for mac. @@ -3707,42 +2644,11 @@ PIXI.BitmapText = function(text, style) { PIXI.DisplayObjectContainer.call(this); - /** - * [read-only] The width of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textWidth - * @type Number - * @readOnly - */ - this.textWidth = 0; - - /** - * [read-only] The height of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textHeight - * @type Number - * @readOnly - */ - this.textHeight = 0; - - /** - * @property _pool - * @type Array - * @private - */ this._pool = []; this.setText(text); this.setStyle(style); this.updateText(); - - /** - * The dirty state of this object. - * @property dirty - * @type Boolean - */ this.dirty = false; }; @@ -3751,10 +2657,10 @@ PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype) PIXI.BitmapText.prototype.constructor = PIXI.BitmapText; /** - * Set the text string to be rendered. + * Set the copy for the text object * * @method setText - * @param text {String} The text that you would like displayed + * @param text {String} The copy that you would like the text to display */ PIXI.BitmapText.prototype.setText = function(text) { @@ -3765,7 +2671,7 @@ PIXI.BitmapText.prototype.setText = function(text) /** * Set the style of the text * style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) - * [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single lines of text + * [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text * * @method setStyle * @param style {Object} The style parameters, contained as properties of an object @@ -3800,11 +2706,11 @@ PIXI.BitmapText.prototype.updateText = function() var lineWidths = []; var line = 0; var scale = this.fontSize / data.size; + for(var i = 0; i < this.text.length; i++) { var charCode = this.text.charCodeAt(i); - if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i))) { lineWidths.push(pos.x); @@ -3818,14 +2724,12 @@ PIXI.BitmapText.prototype.updateText = function() } var charData = data.chars[charCode]; - if(!charData) continue; - if(prevCharCode && charData.kerning[prevCharCode]) + if(prevCharCode && charData[prevCharCode]) { pos.x += charData.kerning[prevCharCode]; } - chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)}); pos.x += charData.xAdvance; @@ -3836,7 +2740,6 @@ PIXI.BitmapText.prototype.updateText = function() maxLineWidth = Math.max(maxLineWidth, pos.x); var lineAlignOffsets = []; - for(i = 0; i <= line; i++) { var alignOffset = 0; @@ -3854,7 +2757,6 @@ PIXI.BitmapText.prototype.updateText = function() var lenChildren = this.children.length; var lenChars = chars.length; var tint = this.tint || 0xFFFFFF; - for(i = 0; i < lenChars; i++) { var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool. @@ -3878,7 +2780,23 @@ PIXI.BitmapText.prototype.updateText = function() this.removeChild(child); } + + /** + * [read-only] The width of the overall text, different from fontSize, + * which is defined in the style object + * + * @property textWidth + * @type Number + */ this.textWidth = maxLineWidth * scale; + + /** + * [read-only] The height of the overall text, different from fontSize, + * which is defined in the style object + * + * @property textHeight + * @type Number + */ this.textHeight = (pos.y + data.lineHeight) * scale; }; @@ -3900,11 +2818,11 @@ PIXI.BitmapText.prototype.updateTransform = function() }; PIXI.BitmapText.fonts = {}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - + /** * Holds all information related to an Interaction event * @@ -3921,6 +2839,9 @@ PIXI.InteractionData = function() */ this.global = new PIXI.Point(); + // this is here for legacy... but will remove + this.local = new PIXI.Point(); + /** * The target Sprite that was interacted with * @@ -3943,31 +2864,24 @@ PIXI.InteractionData = function() * * @method getLocalPosition * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off - * @param [point] {Point} A Point object in which to store the value, optional (otherwise will create a new point) * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject */ -PIXI.InteractionData.prototype.getLocalPosition = function(displayObject, point) +PIXI.InteractionData.prototype.getLocalPosition = function(displayObject) { var worldTransform = displayObject.worldTransform; var global = this.global; // do a cheeky transform to get the mouse coords; - var a00 = worldTransform.a, a01 = worldTransform.c, a02 = worldTransform.tx, - a10 = worldTransform.b, a11 = worldTransform.d, a12 = worldTransform.ty, + var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx, + a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty, id = 1 / (a00 * a11 + a01 * -a10); - - point = point || new PIXI.Point(); - - point.x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; - point.y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - // set the mouse coords... - return point; + return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, + a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id); }; // constructor -PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; - +PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -3984,7 +2898,7 @@ PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; PIXI.InteractionManager = function(stage) { /** - * A reference to the stage + * a reference to the stage * * @property stage * @type Stage @@ -3992,7 +2906,7 @@ PIXI.InteractionManager = function(stage) this.stage = stage; /** - * The mouse data + * the mouse data * * @property mouse * @type InteractionData @@ -4000,21 +2914,18 @@ PIXI.InteractionManager = function(stage) this.mouse = new PIXI.InteractionData(); /** - * An object that stores current touches (InteractionData) by id reference + * an object that stores current touches (InteractionData) by id reference * - * @property touches + * @property touchs * @type Object */ - this.touches = {}; + this.touchs = {}; - /** - * @property tempPoint - * @type Point - * @private - */ + // helpers this.tempPoint = new PIXI.Point(); /** + * * @property mouseoverEnabled * @type Boolean * @default @@ -4022,8 +2933,8 @@ PIXI.InteractionManager = function(stage) this.mouseoverEnabled = true; /** - * Tiny little interactiveData pool ! - * + * tiny little interactiveData pool ! + * * @property pool * @type Array */ @@ -4034,6 +2945,7 @@ PIXI.InteractionManager = function(stage) * @property interactiveItems * @type Array * @private + * */ this.interactiveItems = []; @@ -4045,60 +2957,23 @@ PIXI.InteractionManager = function(stage) */ this.interactionDOMElement = null; - //this will make it so that you don't have to call bind all the time - - /** - * @property onMouseMove - * @type Function - */ + //this will make it so that you dont have to call bind all the time this.onMouseMove = this.onMouseMove.bind( this ); - - /** - * @property onMouseDown - * @type Function - */ this.onMouseDown = this.onMouseDown.bind(this); - - /** - * @property onMouseOut - * @type Function - */ this.onMouseOut = this.onMouseOut.bind(this); - - /** - * @property onMouseUp - * @type Function - */ this.onMouseUp = this.onMouseUp.bind(this); - /** - * @property onTouchStart - * @type Function - */ this.onTouchStart = this.onTouchStart.bind(this); - - /** - * @property onTouchEnd - * @type Function - */ this.onTouchEnd = this.onTouchEnd.bind(this); - - /** - * @property onTouchMove - * @type Function - */ this.onTouchMove = this.onTouchMove.bind(this); - /** - * @property last - * @type Number - */ this.last = 0; /** * The css style of the cursor that is being used * @property currentCursorStyle * @type String + * */ this.currentCursorStyle = 'inherit'; @@ -4106,17 +2981,9 @@ PIXI.InteractionManager = function(stage) * Is set to true when the mouse is moved out of the canvas * @property mouseOut * @type Boolean + * */ this.mouseOut = false; - - /** - * @property resolution - * @type Number - */ - this.resolution = 1; - - // used for hit testing - this._tempPoint = new PIXI.Point(); }; // constructor @@ -4136,25 +3003,27 @@ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObj var length = children.length; // make an interaction tree... {item.__interactiveParent} - for (var i = length - 1; i >= 0; i--) + for (var i = length-1; i >= 0; i--) { var child = children[i]; // push all interactive bits - if (child._interactive) + if(child.interactive) { iParent.interactiveChildren = true; //child.__iParent = iParent; this.interactiveItems.push(child); - if (child.children.length > 0) { + if(child.children.length > 0) + { this.collectInteractiveSprite(child, child); } } else { child.__iParent = null; - if (child.children.length > 0) + + if(child.children.length > 0) { this.collectInteractiveSprite(child, iParent); } @@ -4173,14 +3042,17 @@ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObj PIXI.InteractionManager.prototype.setTarget = function(target) { this.target = target; - this.resolution = target.resolution; - // Check if the dom element has been set. If it has don't do anything. - if (this.interactionDOMElement !== null) return; + //check if the dom element has been set. If it has don't do anything + if( this.interactionDOMElement === null ) { - this.setTargetDomElement (target.view); + this.setTargetDomElement( target.view ); + } + + }; + /** * Sets the DOM element which will receive mouse/touch events. This is useful for when you have other DOM * elements on top of the renderers Canvas element. With this you'll be able to delegate another DOM element @@ -4192,13 +3064,17 @@ PIXI.InteractionManager.prototype.setTarget = function(target) */ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) { + this.removeEvents(); + if (window.navigator.msPointerEnabled) { // time to remove some of that zoom in ja.. domElement.style['-ms-content-zooming'] = 'none'; domElement.style['-ms-touch-action'] = 'none'; + + // DO some window specific touch! } this.interactionDOMElement = domElement; @@ -4212,16 +3088,13 @@ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) domElement.addEventListener('touchend', this.onTouchEnd, true); domElement.addEventListener('touchmove', this.onTouchMove, true); - window.addEventListener('mouseup', this.onMouseUp, true); + document.body.addEventListener('mouseup', this.onMouseUp, true); }; -/** - * @method removeEvents - * @private - */ + PIXI.InteractionManager.prototype.removeEvents = function() { - if (!this.interactionDOMElement) return; + if(!this.interactionDOMElement)return; this.interactionDOMElement.style['-ms-content-zooming'] = ''; this.interactionDOMElement.style['-ms-touch-action'] = ''; @@ -4237,7 +3110,7 @@ PIXI.InteractionManager.prototype.removeEvents = function() this.interactionDOMElement = null; - window.removeEventListener('mouseup', this.onMouseUp, true); + document.body.removeEventListener('mouseup', this.onMouseUp, true); }; /** @@ -4248,13 +3121,13 @@ PIXI.InteractionManager.prototype.removeEvents = function() */ PIXI.InteractionManager.prototype.update = function() { - if (!this.target) return; + if(!this.target)return; // frequency of 30fps?? var now = Date.now(); var diff = now - this.last; diff = (diff * PIXI.INTERACTION_FREQUENCY ) / 1000; - if (diff < 1) return; + if(diff < 1)return; this.last = now; var i = 0; @@ -4262,9 +3135,21 @@ PIXI.InteractionManager.prototype.update = function() // ok.. so mouse events?? // yes for now :) // OPTIMISE - how often to check?? - if (this.dirty) + if(this.dirty) { - this.rebuildInteractiveGraph(); + this.dirty = false; + + var len = this.interactiveItems.length; + + for (i = 0; i < len; i++) { + this.interactiveItems[i].interactiveChildren = false; + } + + this.interactiveItems = []; + + if(this.stage.interactive)this.interactiveItems.push(this.stage); + // go through and collect all the objects that are interactive.. + this.collectInteractiveSprite(this.stage, this.stage); } // loop through interactive objects! @@ -4279,77 +3164,43 @@ PIXI.InteractionManager.prototype.update = function() // OPTIMISATION - only calculate every time if the mousemove function exists.. // OK so.. does the object have any other interactive functions? // hit-test the clip! - // if (item.mouseover || item.mouseout || item.buttonMode) + // if(item.mouseover || item.mouseout || item.buttonMode) // { // ok so there are some functions so lets hit test it.. item.__hit = this.hitTest(item, this.mouse); this.mouse.target = item; // ok so deal with interactions.. // looks like there was a hit! - if (item.__hit && !over) + if(item.__hit && !over) { - if (item.buttonMode) cursor = item.defaultCursor; + if(item.buttonMode) cursor = item.defaultCursor; - if (!item.interactiveChildren) - { - over = true; - } + if(!item.interactiveChildren)over = true; - if (!item.__isOver) + if(!item.__isOver) { - if (item.mouseover) - { - item.mouseover (this.mouse); - } + if(item.mouseover)item.mouseover(this.mouse); item.__isOver = true; } } else { - if (item.__isOver) + if(item.__isOver) { // roll out! - if (item.mouseout) - { - item.mouseout (this.mouse); - } + if(item.mouseout)item.mouseout(this.mouse); item.__isOver = false; } } } - if (this.currentCursorStyle !== cursor) + if( this.currentCursorStyle !== cursor ) { this.currentCursorStyle = cursor; this.interactionDOMElement.style.cursor = cursor; } }; -/** - * @method rebuildInteractiveGraph - * @private - */ -PIXI.InteractionManager.prototype.rebuildInteractiveGraph = function() -{ - this.dirty = false; - - var len = this.interactiveItems.length; - - for (var i = 0; i < len; i++) { - this.interactiveItems[i].interactiveChildren = false; - } - - this.interactiveItems = []; - - if (this.stage.interactive) - { - this.interactiveItems.push(this.stage); - } - - // Go through and collect all the objects that are interactive.. - this.collectInteractiveSprite(this.stage, this.stage); -}; - /** * Is called when the mouse moves across the renderer element * @@ -4359,18 +3210,12 @@ PIXI.InteractionManager.prototype.rebuildInteractiveGraph = function() */ PIXI.InteractionManager.prototype.onMouseMove = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - + this.mouse.originalEvent = event || window.event; //IE uses window.event // TODO optimize by not check EVERY TIME! maybe half as often? // var rect = this.interactionDOMElement.getBoundingClientRect(); - this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width) / this.resolution; - this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height) / this.resolution; + this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); + this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); var length = this.interactiveItems.length; @@ -4378,9 +3223,9 @@ PIXI.InteractionManager.prototype.onMouseMove = function(event) { var item = this.interactiveItems[i]; - // Call the function! - if (item.mousemove) + if(item.mousemove) { + //call the function! item.mousemove(this.mouse); } } @@ -4395,17 +3240,9 @@ PIXI.InteractionManager.prototype.onMouseMove = function(event) */ PIXI.InteractionManager.prototype.onMouseDown = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } + this.mouse.originalEvent = event || window.event; //IE uses window.event - this.mouse.originalEvent = event; - - if (PIXI.AUTO_PREVENT_DEFAULT) - { - this.mouse.originalEvent.preventDefault(); - } + if(PIXI.AUTO_PREVENT_DEFAULT)this.mouse.originalEvent.preventDefault(); // loop through interaction tree... // hit test each item! -> @@ -4413,56 +3250,39 @@ PIXI.InteractionManager.prototype.onMouseDown = function(event) //stage.__i var length = this.interactiveItems.length; - var e = this.mouse.originalEvent; - var isRightButton = e.button === 2 || e.which === 3; - var downFunction = isRightButton ? 'rightdown' : 'mousedown'; - var clickFunction = isRightButton ? 'rightclick' : 'click'; - var buttonIsDown = isRightButton ? '__rightIsDown' : '__mouseIsDown'; - var isDown = isRightButton ? '__isRightDown' : '__isDown'; - // while // hit test for (var i = 0; i < length; i++) { var item = this.interactiveItems[i]; - if (item[downFunction] || item[clickFunction]) + if(item.mousedown || item.click) { - item[buttonIsDown] = true; + item.__mouseIsDown = true; item.__hit = this.hitTest(item, this.mouse); - if (item.__hit) + if(item.__hit) { //call the function! - if (item[downFunction]) - { - item[downFunction](this.mouse); - } - item[isDown] = true; + if(item.mousedown)item.mousedown(this.mouse); + item.__isDown = true; // just the one! - if (!item.interactiveChildren) break; + if(!item.interactiveChildren)break; } } } }; /** - * Is called when the mouse is moved out of the renderer element + * Is called when the mouse button is moved out of the renderer element * * @method onMouseOut - * @param event {Event} The DOM event of a mouse being moved out - * @private + * @param event {Event} The DOM event of a mouse button being moved out + * @private */ -PIXI.InteractionManager.prototype.onMouseOut = function(event) +PIXI.InteractionManager.prototype.onMouseOut = function() { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - var length = this.interactiveItems.length; this.interactionDOMElement.style.cursor = 'inherit'; @@ -4470,13 +3290,10 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event) for (var i = 0; i < length; i++) { var item = this.interactiveItems[i]; - if (item.__isOver) + if(item.__isOver) { this.mouse.target = item; - if (item.mouseout) - { - item.mouseout(this.mouse); - } + if(item.mouseout)item.mouseout(this.mouse); item.__isOver = false; } } @@ -4497,62 +3314,42 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event) */ PIXI.InteractionManager.prototype.onMouseUp = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - this.mouse.originalEvent = event; + this.mouse.originalEvent = event || window.event; //IE uses window.event var length = this.interactiveItems.length; var up = false; - var e = this.mouse.originalEvent; - var isRightButton = e.button === 2 || e.which === 3; - - var upFunction = isRightButton ? 'rightup' : 'mouseup'; - var clickFunction = isRightButton ? 'rightclick' : 'click'; - var upOutsideFunction = isRightButton ? 'rightupoutside' : 'mouseupoutside'; - var isDown = isRightButton ? '__isRightDown' : '__isDown'; - for (var i = 0; i < length; i++) { var item = this.interactiveItems[i]; - if (item[clickFunction] || item[upFunction] || item[upOutsideFunction]) + item.__hit = this.hitTest(item, this.mouse); + + if(item.__hit && !up) { - item.__hit = this.hitTest(item, this.mouse); - - if (item.__hit && !up) + //call the function! + if(item.mouseup) { - //call the function! - if (item[upFunction]) - { - item[upFunction](this.mouse); - } - if (item[isDown]) - { - if (item[clickFunction]) - { - item[clickFunction](this.mouse); - } - } - - if (!item.interactiveChildren) - { - up = true; - } + item.mouseup(this.mouse); } - else + if(item.__isDown) { - if (item[isDown]) - { - if (item[upOutsideFunction]) item[upOutsideFunction](this.mouse); - } + if(item.click)item.click(this.mouse); } - item[isDown] = false; + if(!item.interactiveChildren)up = true; } + else + { + if(item.__isDown) + { + if(item.mouseupoutside)item.mouseupoutside(this.mouse); + } + } + + item.__isDown = false; + //} } }; @@ -4568,77 +3365,66 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) { var global = interactionData.global; - if (!item.worldVisible) - { - return false; - } + if( !item.worldVisible )return false; - // map the global point to local space. - item.worldTransform.applyInverse(global, this._tempPoint); - - var x = this._tempPoint.x, - y = this._tempPoint.y, - i; + // temp fix for if the element is in a non visible + + var isSprite = (item instanceof PIXI.Sprite), + worldTransform = item.worldTransform, + a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx, + a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty, + id = 1 / (a00 * a11 + a01 * -a10), + x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, + y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; interactionData.target = item; //a sprite or display object with a hit area defined - if (item.hitArea && item.hitArea.contains) - { - return item.hitArea.contains(x, y); + if(item.hitArea && item.hitArea.contains) { + if(item.hitArea.contains(x, y)) { + //if(isSprite) + interactionData.target = item; + + return true; + } + + return false; } // a sprite with no hitarea defined - else if(item instanceof PIXI.Sprite) + else if(isSprite) { - var width = item.texture.frame.width; - var height = item.texture.frame.height; - var x1 = -width * item.anchor.x; - var y1; + var width = item.texture.frame.width, + height = item.texture.frame.height, + x1 = -width * item.anchor.x, + y1; - if (x > x1 && x < x1 + width) + if(x > x1 && x < x1 + width) { y1 = -height * item.anchor.y; - if (y > y1 && y < y1 + height) + if(y > y1 && y < y1 + height) { // set the target property if a hit is true! + interactionData.target = item; return true; } } } - else if(item instanceof PIXI.Graphics) - { - var graphicsData = item.graphicsData; - for (i = 0; i < graphicsData.length; i++) - { - var data = graphicsData[i]; - if(!data.fill)continue; - - // only deal with fills.. - if(data.shape) - { - if(data.shape.contains(x, y)) - { - //interactionData.target = item; - return true; - } - } - } - } var length = item.children.length; - for (i = 0; i < length; i++) + for (var i = 0; i < length; i++) { var tempItem = item.children[i]; var hit = this.hitTest(tempItem, interactionData); - if (hit) + if(hit) { // hmm.. TODO SET CORRECT TARGET? interactionData.target = item; return true; } } + return false; }; @@ -4651,11 +3437,6 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) */ PIXI.InteractionManager.prototype.onTouchMove = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - var rect = this.interactionDOMElement.getBoundingClientRect(); var changedTouches = event.changedTouches; var touchData; @@ -4664,27 +3445,24 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event) for (i = 0; i < changedTouches.length; i++) { var touchEvent = changedTouches[i]; - touchData = this.touches[touchEvent.identifier]; - touchData.originalEvent = event; + touchData = this.touchs[touchEvent.identifier]; + touchData.originalEvent = event || window.event; // update the touch position - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + if(navigator.isCocoonJS) { touchData.global.x = touchEvent.clientX; touchData.global.y = touchEvent.clientY; } + } - for (var j = 0; j < this.interactiveItems.length; j++) - { - var item = this.interactiveItems[j]; - if (item.touchmove && item.__touchData && item.__touchData[touchEvent.identifier]) - { - item.touchmove(touchData); - } - } + var length = this.interactiveItems.length; + for (i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + if(item.touchmove) + item.touchmove(touchData); } }; @@ -4697,37 +3475,24 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event) */ PIXI.InteractionManager.prototype.onTouchStart = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - var rect = this.interactionDOMElement.getBoundingClientRect(); - if (PIXI.AUTO_PREVENT_DEFAULT) - { - event.preventDefault(); - } - + if(PIXI.AUTO_PREVENT_DEFAULT)event.preventDefault(); + var changedTouches = event.changedTouches; for (var i=0; i < changedTouches.length; i++) { var touchEvent = changedTouches[i]; var touchData = this.pool.pop(); - if (!touchData) - { - touchData = new PIXI.InteractionData(); - } + if(!touchData)touchData = new PIXI.InteractionData(); - touchData.originalEvent = event; + touchData.originalEvent = event || window.event; - this.touches[touchEvent.identifier] = touchData; - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes + this.touchs[touchEvent.identifier] = touchData; + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + if(navigator.isCocoonJS) { touchData.global.x = touchEvent.clientX; touchData.global.y = touchEvent.clientY; } @@ -4738,19 +3503,18 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event) { var item = this.interactiveItems[j]; - if (item.touchstart || item.tap) + if(item.touchstart || item.tap) { item.__hit = this.hitTest(item, touchData); - if (item.__hit) + if(item.__hit) { //call the function! - if (item.touchstart)item.touchstart(touchData); + if(item.touchstart)item.touchstart(touchData); item.__isDown = true; - item.__touchData = item.__touchData || {}; - item.__touchData[touchEvent.identifier] = touchData; + item.__touchData = touchData; - if (!item.interactiveChildren) break; + if(!item.interactiveChildren)break; } } } @@ -4766,24 +3530,18 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event) */ PIXI.InteractionManager.prototype.onTouchEnd = function(event) { - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - + //this.mouse.originalEvent = event || window.event; //IE uses window.event var rect = this.interactionDOMElement.getBoundingClientRect(); var changedTouches = event.changedTouches; for (var i=0; i < changedTouches.length; i++) { var touchEvent = changedTouches[i]; - var touchData = this.touches[touchEvent.identifier]; + var touchData = this.touchs[touchEvent.identifier]; var up = false; - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + if(navigator.isCocoonJS) { touchData.global.x = touchEvent.clientX; touchData.global.y = touchEvent.clientY; } @@ -4792,53 +3550,54 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event) for (var j = 0; j < length; j++) { var item = this.interactiveItems[j]; + var itemTouchData = item.__touchData; // <-- Here! + item.__hit = this.hitTest(item, touchData); - if (item.__touchData && item.__touchData[touchEvent.identifier]) + if(itemTouchData === touchData) { - - item.__hit = this.hitTest(item, item.__touchData[touchEvent.identifier]); - // so this one WAS down... - touchData.originalEvent = event; + touchData.originalEvent = event || window.event; // hitTest?? - if (item.touchend || item.tap) + if(item.touchend || item.tap) { - if (item.__hit && !up) + if(item.__hit && !up) { - if (item.touchend) + if(item.touchend)item.touchend(touchData); + if(item.__isDown) { - item.touchend(touchData); - } - if (item.__isDown && item.tap) - { - item.tap(touchData); - } - if (!item.interactiveChildren) - { - up = true; + if(item.tap)item.tap(touchData); } + + if(!item.interactiveChildren)up = true; } else { - if (item.__isDown && item.touchendoutside) + if(item.__isDown) { - item.touchendoutside(touchData); + if(item.touchendoutside)item.touchendoutside(touchData); } } item.__isDown = false; } - item.__touchData[touchEvent.identifier] = null; + item.__touchData = null; + } + /* + else + { + + } + */ } // remove the touch.. this.pool.push(touchData); - this.touches[touchEvent.identifier] = null; + this.touchs[touchEvent.identifier] = null; } }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4867,7 +3626,7 @@ PIXI.Stage = function(backgroundColor) * [read-only] Current transform of the object based on world (parent) factors * * @property worldTransform - * @type Matrix + * @type Mat3 * @readOnly * @private */ @@ -4884,7 +3643,7 @@ PIXI.Stage = function(backgroundColor) /** * The interaction manage for this stage, manages all interactive activity on the stage * - * @property interactionManager + * @property interactive * @type InteractionManager */ this.interactionManager = new PIXI.InteractionManager(this); @@ -4902,7 +3661,7 @@ PIXI.Stage = function(backgroundColor) this.stage = this; //optimize hit detection a bit - this.stage.hitArea = new PIXI.Rectangle(0, 0, 100000, 100000); + this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000); this.setBackgroundColor(backgroundColor); }; @@ -4965,16 +3724,16 @@ PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor) }; /** - * This will return the point containing global coordinates of the mouse. + * This will return the point containing global coords of the mouse. * * @method getMousePosition - * @return {Point} A point containing the coordinates of the global InteractionData position. + * @return {Point} The point containing the coords of the global InteractionData position. */ PIXI.Stage.prototype.getMousePosition = function() { return this.interactionManager.mouse.global; }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -4993,40 +3752,37 @@ PIXI.Stage.prototype.getMousePosition = function() * * @method requestAnimationFrame */ - /** * A polyfill for cancelAnimationFrame * * @method cancelAnimationFrame */ -(function(window) { - var lastTime = 0; - var vendors = ['ms', 'moz', 'webkit', 'o']; - for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || - window[vendors[x] + 'CancelRequestAnimationFrame']; - } +var lastTime = 0; +var vendors = ['ms', 'moz', 'webkit', 'o']; +for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || + window[vendors[x] + 'CancelRequestAnimationFrame']; +} - if (!window.requestAnimationFrame) { - window.requestAnimationFrame = function(callback) { - var currTime = new Date().getTime(); - var timeToCall = Math.max(0, 16 - (currTime - lastTime)); - var id = window.setTimeout(function() { callback(currTime + timeToCall); }, - timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } +if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; + }; +} - if (!window.cancelAnimationFrame) { - window.cancelAnimationFrame = function(id) { - clearTimeout(id); - }; - } +if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; +} - window.requestAnimFrame = window.requestAnimationFrame; -})(this); +window.requestAnimFrame = window.requestAnimationFrame; /** * Converts a hex color number to an [R, G, B] array @@ -5055,21 +3811,15 @@ PIXI.rgb2hex = function(rgb) { */ if (typeof Function.prototype.bind !== 'function') { Function.prototype.bind = (function () { + var slice = Array.prototype.slice; return function (thisArg) { - var target = this, i = arguments.length - 1, boundArgs = []; - if (i > 0) - { - boundArgs.length = i; - while (i--) boundArgs[i] = arguments[i + 1]; - } + var target = this, boundArgs = slice.call(arguments, 1); if (typeof target !== 'function') throw new TypeError(); function bound() { - var i = arguments.length, args = new Array(i); - while (i--) args[i] = arguments[i]; - args = boundArgs.concat(args); - return target.apply(this instanceof bound ? this : thisArg, args); + var args = boundArgs.concat(slice.call(arguments)); + target.apply(this instanceof bound ? this : thisArg, args); } bound.prototype = (function F(proto) { @@ -5150,7 +3900,6 @@ PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a) */ PIXI.canUseNewCanvasBlendModes = function() { - if (typeof document === 'undefined') return false; var canvas = document.createElement('canvas'); canvas.width = 1; canvas.height = 1; @@ -5182,298 +3931,115 @@ PIXI.getNextPowerOfTwo = function(number) return result; } }; - -PIXI.isPowerOfTwo = function(width, height) -{ - return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0); - -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 - * @author Chad Engler https://github.com/englercj @Rolnaaba + */ + +/** + * https://github.com/mrdoob/eventtarget.js/ + * THankS mr DOob! */ /** - * Originally based on https://github.com/mrdoob/eventtarget.js/ from mr Doob. - * Currently takes inspiration from the nodejs EventEmitter, EventEmitter3, and smokesignals - */ - -/** - * Mixins event emitter functionality to a class + * Adds event emitter functionality to a class * * @class EventTarget * @example - * function MyEmitter() {} - * - * PIXI.EventTarget.mixin(MyEmitter.prototype); + * function MyEmitter() { + * PIXI.EventTarget.call(this); //mixes in event target stuff + * } * * var em = new MyEmitter(); - * em.emit('eventName', 'some data', 'some more data', {}, null, ...); + * em.emit({ type: 'eventName', data: 'some data' }); */ -PIXI.EventTarget = { +PIXI.EventTarget = function () { + /** - * Backward compat from when this used to be a function + * Holds all the listeners + * + * @property listeneners + * @type Object */ - call: function callCompat(obj) { - if(obj) { - obj = obj.prototype || obj; - PIXI.EventTarget.mixin(obj); + var listeners = {}; + + /** + * Adds a listener for a specific event + * + * @method addEventListener + * @param type {string} A string representing the event type to listen for. + * @param listener {function} The callback function that will be fired when the event occurs + */ + this.addEventListener = this.on = function ( type, listener ) { + + + if ( listeners[ type ] === undefined ) { + + listeners[ type ] = []; + } - }, + + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + + listeners[ type ].push( listener ); + } + + }; /** - * Mixes in the properties of the EventTarget prototype onto another object + * Fires the event, ie pretends that the event has happened * - * @method mixin - * @param object {Object} The obj to mix into + * @method dispatchEvent + * @param event {Event} the event object */ - mixin: function mixin(obj) { - /** - * Return a list of assigned event listeners. - * - * @method listeners - * @param eventName {String} The events that should be listed. - * @return {Array} An array of listener functions - */ - obj.listeners = function listeners(eventName) { - this._listeners = this._listeners || {}; + this.dispatchEvent = this.emit = function ( event ) { - return this._listeners[eventName] ? this._listeners[eventName].slice() : []; - }; + if ( !listeners[ event.type ] || !listeners[ event.type ].length ) { - /** - * Emit an event to all registered event listeners. - * - * @method emit - * @alias dispatchEvent - * @param eventName {String} The name of the event. - * @return {Boolean} Indication if we've emitted an event. - */ - obj.emit = obj.dispatchEvent = function emit(eventName, data) { - this._listeners = this._listeners || {}; + return; - //backwards compat with old method ".emit({ type: 'something' })" - if(typeof eventName === 'object') { - data = eventName; - eventName = eventName.type; - } + } - //ensure we are using a real pixi event - if(!data || data.__isEventObject !== true) { - data = new PIXI.Event(this, eventName, data); - } + for(var i = 0, l = listeners[ event.type ].length; i < l; i++) { - //iterate the listeners - if(this._listeners && this._listeners[eventName]) { - var listeners = this._listeners[eventName].slice(0), - length = listeners.length, - fn = listeners[0], - i; + listeners[ event.type ][ i ]( event ); - for(i = 0; i < length; fn = listeners[++i]) { - //call the event listener - fn.call(this, data); + } - //if "stopImmediatePropagation" is called, stop calling sibling events - if(data.stoppedImmediate) { - return this; - } - } + }; - //if "stopPropagation" is called then don't bubble the event - if(data.stopped) { - return this; - } - } + /** + * Removes the specified listener that was assigned to the specified event type + * + * @method removeEventListener + * @param type {string} A string representing the event type which will have its listener removed + * @param listener {function} The callback function that was be fired when the event occured + */ + this.removeEventListener = this.off = function ( type, listener ) { - //bubble this event up the scene graph - if(this.parent && this.parent.emit) { - this.parent.emit.call(this.parent, eventName, data); - } + var index = listeners[ type ].indexOf( listener ); - return this; - }; + if ( index !== - 1 ) { - /** - * Register a new EventListener for the given event. - * - * @method on - * @alias addEventListener - * @param eventName {String} Name of the event. - * @param callback {Functon} fn Callback function. - */ - obj.on = obj.addEventListener = function on(eventName, fn) { - this._listeners = this._listeners || {}; + listeners[ type ].splice( index, 1 ); - (this._listeners[eventName] = this._listeners[eventName] || []) - .push(fn); + } - return this; - }; + }; - /** - * Add an EventListener that's only called once. - * - * @method once - * @param eventName {String} Name of the event. - * @param callback {Function} Callback function. - */ - obj.once = function once(eventName, fn) { - this._listeners = this._listeners || {}; - - var self = this; - function onceHandlerWrapper() { - fn.apply(self.off(eventName, onceHandlerWrapper), arguments); - } - onceHandlerWrapper._originalHandler = fn; - - return this.on(eventName, onceHandlerWrapper); - }; - - /** - * Remove event listeners. - * - * @method off - * @alias removeEventListener - * @param eventName {String} The event we want to remove. - * @param callback {Function} The listener that we need to find. - */ - obj.off = obj.removeEventListener = function off(eventName, fn) { - this._listeners = this._listeners || {}; - - if(!this._listeners[eventName]) - return this; - - var list = this._listeners[eventName], - i = fn ? list.length : 0; - - while(i-- > 0) { - if(list[i] === fn || list[i]._originalHandler === fn) { - list.splice(i, 1); - } - } - - if(list.length === 0) { - delete this._listeners[eventName]; - } - - return this; - }; - - /** - * Remove all listeners or only the listeners for the specified event. - * - * @method removeAllListeners - * @param eventName {String} The event you want to remove all listeners for. - */ - obj.removeAllListeners = function removeAllListeners(eventName) { - this._listeners = this._listeners || {}; - - if(!this._listeners[eventName]) - return this; - - delete this._listeners[eventName]; - - return this; - }; - } + /** + * Removes all the listeners that were active for the specified event type + * + * @method removeAllEventListeners + * @param type {string} A string representing the event type which will have all its listeners removed + */ + this.removeAllEventListeners = function( type ) { + var a = listeners[type]; + if (a) + a.length = 0; + }; }; - -/** - * Creates an homogenous object for tracking events so users can know what to expect. - * - * @class Event - * @extends Object - * @constructor - * @param target {Object} The target object that the event is called on - * @param name {String} The string name of the event that was triggered - * @param data {Object} Arbitrary event data to pass along - */ -PIXI.Event = function(target, name, data) { - //for duck typing in the ".on()" function - this.__isEventObject = true; - - /** - * Tracks the state of bubbling propagation. Do not - * set this directly, instead use `event.stopPropagation()` - * - * @property stopped - * @type Boolean - * @private - * @readOnly - */ - this.stopped = false; - - /** - * Tracks the state of sibling listener propagation. Do not - * set this directly, instead use `event.stopImmediatePropagation()` - * - * @property stoppedImmediate - * @type Boolean - * @private - * @readOnly - */ - this.stoppedImmediate = false; - - /** - * The original target the event triggered on. - * - * @property target - * @type Object - * @readOnly - */ - this.target = target; - - /** - * The string name of the event that this represents. - * - * @property type - * @type String - * @readOnly - */ - this.type = name; - - /** - * The data that was passed in with this event. - * - * @property data - * @type Object - * @readOnly - */ - this.data = data; - - //backwards compat with older version of events - this.content = data; - - /** - * The timestamp when the event occurred. - * - * @property timeStamp - * @type Number - * @readOnly - */ - this.timeStamp = Date.now(); -}; - -/** - * Stops the propagation of events up the scene graph (prevents bubbling). - * - * @method stopPropagation - */ -PIXI.Event.prototype.stopPropagation = function stopPropagation() { - this.stopped = true; -}; - -/** - * Stops the propagation of events to sibling listeners (no longer calls any listeners). - * - * @method stopImmediatePropagation - */ -PIXI.Event.prototype.stopImmediatePropagation = function stopImmediatePropagation() { - this.stoppedImmediate = true; -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -5482,22 +4048,16 @@ PIXI.Event.prototype.stopImmediatePropagation = function stopImmediatePropagatio * This helper function will automatically detect which renderer you should be using. * WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by * the browser then this function will return a canvas renderer - * - * @method autoDetectRenderer - * @for PIXI + * @class autoDetectRenderer * @static * @param width=800 {Number} the width of the renderers view * @param height=600 {Number} the height of the renderers view - * - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * + * @param [view] {Canvas} the canvas to use as a view, optional + * @param [transparent=false] {Boolean} the transparency of the render view, default false + * @param [antialias=false] {Boolean} sets antialias (only applicable in webGL chrome at the moment) + * */ -PIXI.autoDetectRenderer = function(width, height, options) +PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias) { if(!width)width = 800; if(!height)height = 600; @@ -5511,58 +4071,15 @@ PIXI.autoDetectRenderer = function(width, height, options) } } )(); + if( webgl ) { - return new PIXI.WebGLRenderer(width, height, options); + return new PIXI.WebGLRenderer(width, height, view, transparent, antialias); } - return new PIXI.CanvasRenderer(width, height, options); + return new PIXI.CanvasRenderer(width, height, view, transparent); }; - -/** - * This helper function will automatically detect which renderer you should be using. - * This function is very similar to the autoDetectRenderer function except that is will return a canvas renderer for android. - * Even thought both android chrome supports webGL the canvas implementation perform better at the time of writing. - * This function will likely change and update as webGL performance improves on these devices. - * - * @method autoDetectRecommendedRenderer - * @for PIXI - * @static - * @param width=800 {Number} the width of the renderers view - * @param height=600 {Number} the height of the renderers view - * - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * - */ -PIXI.autoDetectRecommendedRenderer = function(width, height, options) -{ - if(!width)width = 800; - if(!height)height = 600; - - // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { - var canvas = document.createElement( 'canvas' ); - return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); - } catch( e ) { - return false; - } - } )(); - - var isAndroid = /Android/i.test(navigator.userAgent); - - if( webgl && !isAndroid) - { - return new PIXI.WebGLRenderer(width, height, options); - } - - return new PIXI.CanvasRenderer(width, height, options); -}; - + /* PolyK library url: http://polyk.ivank.net @@ -5593,21 +4110,23 @@ PIXI.autoDetectRecommendedRenderer = function(width, height, options) This is an amazing lib! - Slightly modified by Mat Groves (matgroves.com); + slightly modified by Mat Groves (matgroves.com); */ /** * Based on the Polyk library http://polyk.ivank.net released under MIT licence. * This is an amazing lib! - * Slightly modified by Mat Groves (matgroves.com); + * slightly modified by Mat Groves (matgroves.com); * @class PolyK + * */ PIXI.PolyK = {}; /** - * Triangulates shapes for webGL graphic fills. + * Triangulates shapes for webGL graphic fills * * @method Triangulate + * */ PIXI.PolyK.Triangulate = function(p) { @@ -5672,8 +4191,8 @@ PIXI.PolyK.Triangulate = function(p) } else { - // window.console.log("PIXI Warning: shape too complex to fill"); - return null; + window.console.log("PIXI Warning: shape too complex to fill"); + return []; } } } @@ -5695,7 +4214,6 @@ PIXI.PolyK.Triangulate = function(p) * @param cx {Number} x coordinate of the c point of the triangle * @param cy {Number} y coordinate of the c point of the triangle * @private - * @return {Boolean} */ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) { @@ -5724,60 +4242,39 @@ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) * Checks whether a shape is convex * * @method _convex + * * @private - * @return {Boolean} */ PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign) { return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign; }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ -/** -* @method initDefaultShaders -* @static -* @private -*/ +// TODO Alvin and Mat +// Should we eventually create a Utils class ? +// Or just move this file to the pixi.js file ? PIXI.initDefaultShaders = function() { + + // PIXI.stripShader = new PIXI.StripShader(); +// PIXI.stripShader.init(); + }; -/** -* @method CompileVertexShader -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @return {Any} -*/ PIXI.CompileVertexShader = function(gl, shaderSrc) { return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); }; -/** -* @method CompileFragmentShader -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @return {Any} -*/ PIXI.CompileFragmentShader = function(gl, shaderSrc) { return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); }; -/** -* @method _CompileShader -* @static -* @private -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @param shaderType {Number} -* @return {Any} -*/ PIXI._CompileShader = function(gl, shaderSrc, shaderType) { var src = shaderSrc.join("\n"); @@ -5785,8 +4282,7 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType) gl.shaderSource(shader, src); gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) - { + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { window.console.log(gl.getShaderInfoLog(shader)); return null; } @@ -5794,14 +4290,6 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType) return shader; }; -/** -* @method compileProgram -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param vertexSrc {Array} -* @param fragmentSrc {Array} -* @return {Any} -*/ PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc) { var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); @@ -5813,14 +4301,13 @@ PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc) gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) - { + if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { window.console.log("Could not initialise shaders"); } return shaderProgram; }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 * @author Richard Davey http://www.photonstorm.com @photonstorm @@ -5829,17 +4316,9 @@ PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc) /** * @class PixiShader * @constructor -* @param gl {WebGLContext} the current WebGL drawing context */ PIXI.PixiShader = function(gl) { - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - /** * @property gl * @type WebGLContext @@ -5847,17 +4326,13 @@ PIXI.PixiShader = function(gl) this.gl = gl; /** - * The WebGL program. - * @property program - * @type Any - */ + * @property {any} program - The WebGL program. + */ this.program = null; /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ + * @property {array} fragmentSrc - The fragment shader. + */ this.fragmentSrc = [ 'precision lowp float;', 'varying vec2 vTextureCoord;', @@ -5868,52 +4343,29 @@ PIXI.PixiShader = function(gl) '}' ]; + /** - * A local texture counter for multi-texture shaders. - * @property textureCount - * @type Number - */ + * @property {number} textureCount - A local texture counter for multi-texture shaders. + */ this.textureCount = 0; - /** - * A local flag - * @property firstRun - * @type Boolean - * @private - */ - this.firstRun = true; - - /** - * A dirty flag - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * Uniform attributes cache. - * @property attributes - * @type Array - * @private - */ this.attributes = []; this.init(); }; -PIXI.PixiShader.prototype.constructor = PIXI.PixiShader; - /** -* Initialises the shader. -* +* Initialises the shader * @method init +* */ PIXI.PixiShader.prototype.init = function() { + var gl = this.gl; var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc); - + gl.useProgram(program); // get and store the uniforms for the shader @@ -5927,11 +4379,12 @@ PIXI.PixiShader.prototype.init = function() this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + // Begin worst hack eva // // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? // maybe its something to do with the current state of the gl context. - // I'm convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel + // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel // If theres any webGL people that know why could happen please help :) if(this.colorAttribute === -1) { @@ -5956,7 +4409,6 @@ PIXI.PixiShader.prototype.init = function() /** * Initialises the shader uniform values. -* * Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ * http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf * @@ -6043,7 +4495,7 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform) var gl = this.gl; gl.activeTexture(gl['TEXTURE' + this.textureCount]); - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id]); + gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTexture); // Extended texture data if (uniform.textureData) @@ -6117,6 +4569,7 @@ PIXI.PixiShader.prototype.syncUniforms = function() // This would probably be faster in an array and it would guarantee key order for (var key in this.uniforms) { + uniform = this.uniforms[key]; if (uniform.glValueLength === 1) @@ -6147,18 +4600,7 @@ PIXI.PixiShader.prototype.syncUniforms = function() if (uniform._init) { gl.activeTexture(gl['TEXTURE' + this.textureCount]); - - if(uniform.value.baseTexture._dirty[gl.id]) - { - PIXI.instances[gl.id].updateTexture(uniform.value.baseTexture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id]); - } - - // gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl)); + gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl)); gl.uniform1i(uniform.uniformLocation, this.textureCount); this.textureCount++; } @@ -6172,9 +4614,9 @@ PIXI.PixiShader.prototype.syncUniforms = function() }; /** -* Destroys the shader. -* +* Destroys the shader * @method destroy +* */ PIXI.PixiShader.prototype.destroy = function() { @@ -6186,7 +4628,6 @@ PIXI.PixiShader.prototype.destroy = function() }; /** -* The Default Vertex shader source. * * @property defaultVertexSrc * @type String @@ -6194,7 +4635,7 @@ PIXI.PixiShader.prototype.destroy = function() PIXI.PixiShader.defaultVertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', + 'attribute vec2 aColor;', 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', @@ -6207,11 +4648,18 @@ PIXI.PixiShader.defaultVertexSrc = [ 'void main(void) {', ' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);', ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', + ' vColor = vec4(color * aColor.x, aColor.x);', '}' ]; + + + + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 + * @author Richard Davey http://www.photonstorm.com @photonstorm */ /** @@ -6221,13 +4669,7 @@ PIXI.PixiShader.defaultVertexSrc = [ */ PIXI.PixiFastShader = function(gl) { - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - + /** * @property gl * @type WebGLContext @@ -6235,16 +4677,12 @@ PIXI.PixiFastShader = function(gl) this.gl = gl; /** - * The WebGL program. - * @property program - * @type Any + * @property {any} program - The WebGL program. */ this.program = null; /** - * The fragment shader. - * @property fragmentSrc - * @type Array + * @property {array} fragmentSrc - The fragment shader. */ this.fragmentSrc = [ 'precision lowp float;', @@ -6257,10 +4695,8 @@ PIXI.PixiFastShader = function(gl) ]; /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ + * @property {array} vertexSrc - The vertex shader + */ this.vertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aPositionCoord;', @@ -6291,25 +4727,24 @@ PIXI.PixiFastShader = function(gl) '}' ]; + /** - * A local texture counter for multi-texture shaders. - * @property textureCount - * @type Number - */ + * @property {number} textureCount - A local texture counter for multi-texture shaders. + */ this.textureCount = 0; + this.init(); }; -PIXI.PixiFastShader.prototype.constructor = PIXI.PixiFastShader; - /** -* Initialises the shader. -* +* Initialises the shader * @method init +* */ PIXI.PixiFastShader.prototype.init = function() { + var gl = this.gl; var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); @@ -6334,6 +4769,8 @@ PIXI.PixiFastShader.prototype.init = function() this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + + // Begin worst hack eva // // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? @@ -6349,13 +4786,14 @@ PIXI.PixiFastShader.prototype.init = function() // End worst hack eva // + this.program = program; }; /** -* Destroys the shader. -* +* Destroys the shader * @method destroy +* */ PIXI.PixiFastShader.prototype.destroy = function() { @@ -6365,94 +4803,67 @@ PIXI.PixiFastShader.prototype.destroy = function() this.attributes = null; }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ -/** -* @class StripShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.StripShader = function(gl) + +PIXI.StripShader = function() { /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ + * @property {any} program - The WebGL program. + */ this.program = null; /** - * The fragment shader. - * @property fragmentSrc - * @type Array + * @property {array} fragmentSrc - The fragment shader. */ this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', - // 'varying float vColor;', + 'varying float vColor;', 'uniform float alpha;', 'uniform sampler2D uSampler;', 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * alpha;', - // ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);',//gl_FragColor * alpha;', + ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));', + ' gl_FragColor = gl_FragColor * alpha;', '}' ]; /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ + * @property {array} fragmentSrc - The fragment shader. + */ + this.vertexSrc = [ 'attribute vec2 aVertexPosition;', 'attribute vec2 aTextureCoord;', + 'attribute float aColor;', 'uniform mat3 translationMatrix;', 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - // 'uniform float alpha;', - // 'uniform vec3 tint;', 'varying vec2 vTextureCoord;', - // 'varying vec4 vColor;', + 'uniform vec2 offsetVector;', + 'varying float vColor;', 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', + ' vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);', ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);', ' vTextureCoord = aTextureCoord;', - // ' vColor = aColor * vec4(tint * alpha, alpha);', + ' vColor = aColor;', '}' ]; - - this.init(); }; -PIXI.StripShader.prototype.constructor = PIXI.StripShader; - /** -* Initialises the shader. -* +* Initialises the shader * @method init +* */ PIXI.StripShader.prototype.init = function() { - var gl = this.gl; + + var gl = PIXI.gl; var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); gl.useProgram(program); @@ -6468,28 +4879,12 @@ PIXI.StripShader.prototype.init = function() this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.attributes = [this.aVertexPosition, this.aTextureCoord]; - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); this.alpha = gl.getUniformLocation(program, 'alpha'); this.program = program; }; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.StripShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attribute = null; -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -6501,13 +4896,6 @@ PIXI.StripShader.prototype.destroy = function() */ PIXI.PrimitiveShader = function(gl) { - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - /** * @property gl * @type WebGLContext @@ -6515,14 +4903,11 @@ PIXI.PrimitiveShader = function(gl) this.gl = gl; /** - * The WebGL program. - * @property program - * @type Any - */ + * @property {any} program - The WebGL program. + */ this.program = null; /** - * The fragment shader. * @property fragmentSrc * @type Array */ @@ -6536,7 +4921,6 @@ PIXI.PrimitiveShader = function(gl) ]; /** - * The vertex shader. * @property vertexSrc * @type Array */ @@ -6547,14 +4931,13 @@ PIXI.PrimitiveShader = function(gl) 'uniform vec2 projectionVector;', 'uniform vec2 offsetVector;', 'uniform float alpha;', - 'uniform float flipY;', 'uniform vec3 tint;', 'varying vec4 vColor;', 'void main(void) {', ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, (v.y / projectionVector.y * -flipY) + flipY , 0.0, 1.0);', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', ' vColor = aColor * vec4(tint * alpha, alpha);', '}' ]; @@ -6562,15 +4945,14 @@ PIXI.PrimitiveShader = function(gl) this.init(); }; -PIXI.PrimitiveShader.prototype.constructor = PIXI.PrimitiveShader; - /** -* Initialises the shader. -* +* Initialises the shader * @method init +* */ PIXI.PrimitiveShader.prototype.init = function() { + var gl = this.gl; var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); @@ -6580,7 +4962,7 @@ PIXI.PrimitiveShader.prototype.init = function() this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); this.tintColor = gl.getUniformLocation(program, 'tint'); - this.flipY = gl.getUniformLocation(program, 'flipY'); + // get and store the attributes this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); @@ -6595,9 +4977,9 @@ PIXI.PrimitiveShader.prototype.init = function() }; /** -* Destroys the shader. -* +* Destroys the shader * @method destroy +* */ PIXI.PrimitiveShader.prototype.destroy = function() { @@ -6605,132 +4987,9 @@ PIXI.PrimitiveShader.prototype.destroy = function() this.uniforms = null; this.gl = null; - this.attributes = null; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class ComplexPrimitiveShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.ComplexPrimitiveShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - - 'precision mediump float;', - - 'varying vec4 vColor;', - - 'void main(void) {', - ' gl_FragColor = vColor;', - '}' - ]; - - /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - //'attribute vec4 aColor;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - - 'uniform vec3 tint;', - 'uniform float alpha;', - 'uniform vec3 color;', - 'uniform float flipY;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, (v.y / projectionVector.y * -flipY) + flipY , 0.0, 1.0);', - ' vColor = vec4(color * alpha * tint, alpha);',//" * vec4(tint * alpha, alpha);', - '}' - ]; - - this.init(); -}; - -PIXI.ComplexPrimitiveShader.prototype.constructor = PIXI.ComplexPrimitiveShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.ComplexPrimitiveShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.tintColor = gl.getUniformLocation(program, 'tint'); - this.color = gl.getUniformLocation(program, 'color'); - this.flipY = gl.getUniformLocation(program, 'flipY'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - // this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - this.attributes = [this.aVertexPosition, this.colorAttribute]; - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.ComplexPrimitiveShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - this.attribute = null; }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -6744,6 +5003,7 @@ PIXI.ComplexPrimitiveShader.prototype.destroy = function() */ PIXI.WebGLGraphics = function() { + }; /** @@ -6760,60 +5020,60 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projectio var gl = renderSession.gl; var projection = renderSession.projection, offset = renderSession.offset, - shader = renderSession.shaderManager.primitiveShader, - webGLData; + shader = renderSession.shaderManager.primitiveShader; - if(graphics.dirty) - { - PIXI.WebGLGraphics.updateGraphics(graphics, gl); - } + if(!graphics._webGL[gl.id])graphics._webGL[gl.id] = {points:[], indices:[], lastIndex:0, + buffer:gl.createBuffer(), + indexBuffer:gl.createBuffer()}; var webGL = graphics._webGL[gl.id]; + if(graphics.dirty) + { + graphics.dirty = false; + + if(graphics.clearDirty) + { + graphics.clearDirty = false; + + webGL.lastIndex = 0; + webGL.points = []; + webGL.indices = []; + + } + + PIXI.WebGLGraphics.updateGraphics(graphics, gl); + } + + renderSession.shaderManager.activatePrimitiveShader(); + // This could be speeded up for sure! - for (var i = 0; i < webGL.data.length; i++) - { - if(webGL.data[i].mode === 1) - { - webGLData = webGL.data[i]; + // set the matrix transform + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); - renderSession.stencilManager.pushStencil(graphics, webGLData, renderSession); + gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - // render quad.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - renderSession.stencilManager.popStencil(graphics, webGLData, renderSession); - } - else - { - webGLData = webGL.data[i]; - + gl.uniform2f(shader.projectionVector, projection.x, -projection.y); + gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - renderSession.shaderManager.setShader( shader );//activatePrimitiveShader(); - shader = renderSession.shaderManager.primitiveShader; - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform1f(shader.flipY, 1); - - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); + gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); + gl.uniform1f(shader.alpha, graphics.worldAlpha); + gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer); - gl.uniform1f(shader.alpha, graphics.worldAlpha); - + gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); + gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); + // set the index buffer! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); + gl.drawElements(gl.TRIANGLE_STRIP, webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - } - } + renderSession.shaderManager.deactivatePrimitiveShader(); + + // return to default shader... +// PIXI.activateShader(PIXI.defaultShader); }; /** @@ -6827,152 +5087,48 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projectio */ PIXI.WebGLGraphics.updateGraphics = function(graphics, gl) { - // get the contexts graphics object var webGL = graphics._webGL[gl.id]; - // if the graphics object does not exist in the webGL context time to create it! - if(!webGL)webGL = graphics._webGL[gl.id] = {lastIndex:0, data:[], gl:gl}; - - // flag the graphics as not dirty as we are about to update it... - graphics.dirty = false; - - var i; - - // if the user cleared the graphics object we will need to clear every object - if(graphics.clearDirty) - { - graphics.clearDirty = false; - - // lop through and return all the webGLDatas to the object pool so than can be reused later on - for (i = 0; i < webGL.data.length; i++) - { - var graphicsData = webGL.data[i]; - graphicsData.reset(); - PIXI.WebGLGraphics.graphicsDataPool.push( graphicsData ); - } - - // clear the array and reset the index.. - webGL.data = []; - webGL.lastIndex = 0; - } - var webGLData; - - // loop through the graphics datas and construct each one.. - // if the object is a complex fill then the new stencil buffer technique will be used - // other wise graphics objects will be pushed into a batch.. - for (i = webGL.lastIndex; i < graphics.graphicsData.length; i++) + for (var i = webGL.lastIndex; i < graphics.graphicsData.length; i++) { var data = graphics.graphicsData[i]; if(data.type === PIXI.Graphics.POLY) { - // need to add the points the the graphics object.. - data.points = data.shape.points.slice(); - if(data.shape.closed) - { - // close the poly if the value is true! - if(data.points[0] !== data.points[data.points.length-2] || data.points[1] !== data.points[data.points.length-1]) - { - data.points.push(data.points[0], data.points[1]); - } - } - - // MAKE SURE WE HAVE THE CORRECT TYPE.. if(data.fill) { - if(data.points.length >= 6) - { - if(data.points.length < 6 * 2) - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - - var canDrawUsingSimple = PIXI.WebGLGraphics.buildPoly(data, webGLData); - // console.log(canDrawUsingSimple); - - if(!canDrawUsingSimple) - { - // console.log("<>>>") - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 1); - PIXI.WebGLGraphics.buildComplexPoly(data, webGLData); - } - - } - else - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 1); - PIXI.WebGLGraphics.buildComplexPoly(data, webGLData); - } - } + if(data.points.length>3) + PIXI.WebGLGraphics.buildPoly(data, webGL); } if(data.lineWidth > 0) { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - PIXI.WebGLGraphics.buildLine(data, webGLData); - + PIXI.WebGLGraphics.buildLine(data, webGL); } } - else + else if(data.type === PIXI.Graphics.RECT) { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - - if(data.type === PIXI.Graphics.RECT) - { - PIXI.WebGLGraphics.buildRectangle(data, webGLData); - } - else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP) - { - PIXI.WebGLGraphics.buildCircle(data, webGLData); - } - else if(data.type === PIXI.Graphics.RREC) - { - PIXI.WebGLGraphics.buildRoundedRectangle(data, webGLData); - } + PIXI.WebGLGraphics.buildRectangle(data, webGL); } - - webGL.lastIndex++; - } - - // upload all the dirty data... - for (i = 0; i < webGL.data.length; i++) - { - webGLData = webGL.data[i]; - if(webGLData.dirty)webGLData.upload(); - } -}; - -/** - * @static - * @private - * @method switchMode - * @param webGL {WebGLContext} - * @param type {Number} - */ -PIXI.WebGLGraphics.switchMode = function(webGL, type) -{ - var webGLData; - - if(!webGL.data.length) - { - webGLData = PIXI.WebGLGraphics.graphicsDataPool.pop() || new PIXI.WebGLGraphicsData(webGL.gl); - webGLData.mode = type; - webGL.data.push(webGLData); - } - else - { - webGLData = webGL.data[webGL.data.length-1]; - - if(webGLData.mode !== type || type === 1) + else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP) { - webGLData = PIXI.WebGLGraphics.graphicsDataPool.pop() || new PIXI.WebGLGraphicsData(webGL.gl); - webGLData.mode = type; - webGL.data.push(webGLData); + PIXI.WebGLGraphics.buildCircle(data, webGL); } } - webGLData.dirty = true; + webGL.lastIndex = graphics.graphicsData.length; - return webGLData; + + + webGL.glPoints = new Float32Array(webGL.points); + + gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer); + gl.bufferData(gl.ARRAY_BUFFER, webGL.glPoints, gl.STATIC_DRAW); + + webGL.glIndicies = new Uint16Array(webGL.indices); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, webGL.glIndicies, gl.STATIC_DRAW); }; /** @@ -6989,11 +5145,12 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) // --- // // need to convert points to a nice regular data // - var rectData = graphicsData.shape; - var x = rectData.x; - var y = rectData.y; - var width = rectData.width; - var height = rectData.height; + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; + if(graphicsData.fill) { @@ -7043,129 +5200,6 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) } }; -/** - * Builds a rounded rectangle to draw - * - * @static - * @private - * @method buildRoundedRectangle - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildRoundedRectangle = function(graphicsData, webGLData) -{ - var rrectData = graphicsData.shape; - var x = rrectData.x; - var y = rrectData.y; - var width = rrectData.width; - var height = rrectData.height; - - var radius = rrectData.radius; - - var recPoints = []; - recPoints.push(x, y + radius); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + radius, y, x, y, x, y + radius)); - - if (graphicsData.fill) { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - var triangles = PIXI.PolyK.Triangulate(recPoints); - - // - - var i = 0; - for (i = 0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vecPos); - indices.push(triangles[i] + vecPos); - indices.push(triangles[i+1] + vecPos); - indices.push(triangles[i+2] + vecPos); - indices.push(triangles[i+2] + vecPos); - } - - - for (i = 0; i < recPoints.length; i++) - { - verts.push(recPoints[i], recPoints[++i], r, g, b, alpha); - } - } - - if (graphicsData.lineWidth) { - var tempPoints = graphicsData.points; - - graphicsData.points = recPoints; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Calculate the points for a quadratic bezier curve. (helper function..) - * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c - * - * @static - * @private - * @method quadraticBezierCurve - * @param fromX {Number} Origin point x - * @param fromY {Number} Origin point x - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Array(Number)} - */ -PIXI.WebGLGraphics.quadraticBezierCurve = function(fromX, fromY, cpX, cpY, toX, toY) { - - var xa, - ya, - xb, - yb, - x, - y, - n = 20, - points = []; - - function getPt(n1 , n2, perc) { - var diff = n2 - n1; - - return n1 + ( diff * perc ); - } - - var j = 0; - for (var i = 0; i <= n; i++ ) - { - j = i / n; - - // The Green Line - xa = getPt( fromX , cpX , j ); - ya = getPt( fromY , cpY , j ); - xb = getPt( cpX , toX , j ); - yb = getPt( cpY , toY , j ); - - // The Black Dot - x = getPt( xa , xb , j ); - y = getPt( ya , yb , j ); - - points.push(x, y); - } - return points; -}; - /** * Builds a circle to draw * @@ -7177,24 +5211,13 @@ PIXI.WebGLGraphics.quadraticBezierCurve = function(fromX, fromY, cpX, cpY, toX, */ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) { - // need to convert points to a nice regular data - var circleData = graphicsData.shape; - var x = circleData.x; - var y = circleData.y; - var width; - var height; - // TODO - bit hacky?? - if(graphicsData.type === PIXI.Graphics.CIRC) - { - width = circleData.radius; - height = circleData.radius; - } - else - { - width = circleData.width; - height = circleData.height; - } + // need to convert points to a nice regular data + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; var totalSegs = 40; var seg = (Math.PI * 2) / totalSegs ; @@ -7262,6 +5285,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) { // TODO OPTIMISE! var i = 0; + var points = graphicsData.points; if(points.length === 0)return; @@ -7280,9 +5304,6 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) // if the first point is the last point - gonna have issues :) if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) { - // need to clone as we are going to slightly modify the shape.. - points = points.slice(); - points.pop(); points.pop(); @@ -7461,68 +5482,6 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) indices.push(indexStart-1); }; -/** - * Builds a complex polygon to draw - * - * @static - * @private - * @method buildComplexPoly - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildComplexPoly = function(graphicsData, webGLData) -{ - //TODO - no need to copy this as it gets turned into a FLoat32Array anyways.. - var points = graphicsData.points.slice(); - if(points.length < 6)return; - - // get first and last point.. figure out the middle! - var indices = webGLData.indices; - webGLData.points = points; - webGLData.alpha = graphicsData.fillAlpha; - webGLData.color = PIXI.hex2rgb(graphicsData.fillColor); - - /* - calclate the bounds.. - */ - var minX = Infinity; - var maxX = -Infinity; - - var minY = Infinity; - var maxY = -Infinity; - - var x,y; - - // get size.. - for (var i = 0; i < points.length; i+=2) - { - x = points[i]; - y = points[i+1]; - - minX = x < minX ? x : minX; - maxX = x > maxX ? x : maxX; - - minY = y < minY ? y : minY; - maxY = y > maxY ? y : maxY; - } - - // add a quad to the end cos there is no point making another buffer! - points.push(minX, minY, - maxX, minY, - maxX, maxY, - minX, maxY); - - // push a quad onto the end.. - - //TODO - this aint needed! - var length = points.length / 2; - for (i = 0; i < length; i++) - { - indices.push( i ); - } - -}; - /** * Builds a polygon to draw * @@ -7535,8 +5494,8 @@ PIXI.WebGLGraphics.buildComplexPoly = function(graphicsData, webGLData) PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) { var points = graphicsData.points; - if(points.length < 6)return; + // get first and last point.. figure out the middle! var verts = webGLData.points; var indices = webGLData.indices; @@ -7552,8 +5511,6 @@ PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) var triangles = PIXI.PolyK.Triangulate(points); - if(!triangles)return false; - var vertPos = verts.length / 6; var i = 0; @@ -7572,159 +5529,43 @@ PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) verts.push(points[i * 2], points[i * 2 + 1], r, g, b, alpha); } - - return true; }; - -PIXI.WebGLGraphics.graphicsDataPool = []; - -/** - * @class WebGLGraphicsData - * @private - * @static - */ -PIXI.WebGLGraphicsData = function(gl) -{ - this.gl = gl; - - //TODO does this need to be split before uploding?? - this.color = [0,0,0]; // color split! - this.points = []; - this.indices = []; - this.buffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.mode = 1; - this.alpha = 1; - this.dirty = true; -}; - -/** - * @method reset - */ -PIXI.WebGLGraphicsData.prototype.reset = function() -{ - this.points = []; - this.indices = []; -}; - -/** - * @method upload - */ -PIXI.WebGLGraphicsData.prototype.upload = function() -{ - var gl = this.gl; - -// this.lastIndex = graphics.graphicsData.length; - this.glPoints = new PIXI.Float32Array(this.points); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); - gl.bufferData(gl.ARRAY_BUFFER, this.glPoints, gl.STATIC_DRAW); - - this.glIndicies = new PIXI.Uint16Array(this.indices); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.glIndicies, gl.STATIC_DRAW); - - this.dirty = false; -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ PIXI.glContexts = []; // this is where we store the webGL contexts for easy access. -PIXI.instances = []; /** - * The WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer - * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs. - * So no need for Sprite Batches or Sprite Clouds. - * Don't forget to add the view to your DOM or you will not see anything :) + * the WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer + * should be used for browsers that support webGL. This Render works by automatically managing webGLBatch's. + * So no need for Sprite Batch's or Sprite Cloud's + * Dont forget to add the view to your DOM or you will not see anything :) * * @class WebGLRenderer * @constructor - * @param [width=0] {Number} the width of the canvas view - * @param [height=0] {Number} the height of the canvas view - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.autoResize=false] {Boolean} If the render view is automatically resized, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 + * @param width=0 {Number} the width of the canvas view + * @param height=0 {Number} the height of the canvas view + * @param view {HTMLCanvasElement} the canvas to use as a view, optional + * @param transparent=false {Boolean} If the render view is transparent, default false + * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment) + * */ -PIXI.WebGLRenderer = function(width, height, options) +PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) { - if(options) - { - for (var i in PIXI.defaultRenderOptions) - { - if (typeof options[i] === 'undefined') options[i] = PIXI.defaultRenderOptions[i]; - } - } - else - { - options = PIXI.defaultRenderOptions; - } + if(!PIXI.defaultRenderer)PIXI.defaultRenderer = this; - if(!PIXI.defaultRenderer) - { - PIXI.sayHello('webGL'); - PIXI.defaultRenderer = this; - } - - /** - * @property type - * @type Number - */ this.type = PIXI.WEBGL_RENDERER; - /** - * The resolution of the renderer - * - * @property resolution - * @type Number - * @default 1 - */ - this.resolution = options.resolution; - // do a catch.. only 1 webGL renderer.. - /** * Whether the render view is transparent * * @property transparent * @type Boolean */ - this.transparent = options.transparent; - - /** - * Whether the render view should be resized automatically - * - * @property autoResize - * @type Boolean - */ - this.autoResize = options.autoResize || false; - - /** - * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering. - * - * @property preserveDrawingBuffer - * @type Boolean - */ - this.preserveDrawingBuffer = options.preserveDrawingBuffer; - - /** - * This sets if the WebGLRenderer will clear the context texture or not before the new render pass. If true: - * If the Stage is NOT transparent, Pixi will clear to alpha (0, 0, 0, 0). - * If the Stage is transparent, Pixi will clear to the target Stage's background color. - * Disable this by setting this to false. For example: if your game has a canvas filling background image, you often don't need this set. - * - * @property clearBeforeRender - * @type Boolean - * @default - */ - this.clearBeforeRender = options.clearBeforeRender; + this.transparent = !!transparent; /** * The width of the canvas view @@ -7750,159 +5591,104 @@ PIXI.WebGLRenderer = function(width, height, options) * @property view * @type HTMLCanvasElement */ - this.view = options.view || document.createElement( 'canvas' ); + this.view = view || document.createElement( 'canvas' ); + this.view.width = this.width; + this.view.height = this.height; // deal with losing context.. + this.contextLost = this.handleContextLost.bind(this); + this.contextRestoredLost = this.handleContextRestored.bind(this); + + this.view.addEventListener('webglcontextlost', this.contextLost, false); + this.view.addEventListener('webglcontextrestored', this.contextRestoredLost, false); - /** - * @property contextLostBound - * @type Function - */ - this.contextLostBound = this.handleContextLost.bind(this); - - /** - * @property contextRestoredBound - * @type Function - */ - this.contextRestoredBound = this.handleContextRestored.bind(this); - - this.view.addEventListener('webglcontextlost', this.contextLostBound, false); - this.view.addEventListener('webglcontextrestored', this.contextRestoredBound, false); - - /** - * @property _contextOptions - * @type Object - * @private - */ - this._contextOptions = { + this.options = { alpha: this.transparent, - antialias: options.antialias, // SPEED UP?? - premultipliedAlpha:this.transparent && this.transparent !== 'notMultiplied', - stencil:true, - preserveDrawingBuffer: options.preserveDrawingBuffer + antialias:!!antialias, // SPEED UP?? + premultipliedAlpha:!!transparent, + stencil:true }; - /** - * @property projection - * @type Point - */ - this.projection = new PIXI.Point(); + //try 'experimental-webgl' + try { + this.gl = this.view.getContext('experimental-webgl', this.options); + } catch (e) { + //try 'webgl' + try { + this.gl = this.view.getContext('webgl', this.options); + } catch (e2) { + // fail, not able to get a context + throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); + } + } + + var gl = this.gl; + this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++; + + PIXI.glContexts[this.glContextId] = gl; + + if(!PIXI.blendModesWebGL) + { + PIXI.blendModesWebGL = []; + + PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; + PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; + } + + + + + this.projection = new PIXI.Point(); + this.projection.x = this.width/2; + this.projection.y = -this.height/2; - /** - * @property offset - * @type Point - */ this.offset = new PIXI.Point(0, 0); - // time to create the render managers! each one focuses on managing a state in webGL + this.resize(this.width, this.height); + this.contextLost = false; - /** - * Deals with managing the shader programs and their attribs - * @property shaderManager - * @type WebGLShaderManager - */ - this.shaderManager = new PIXI.WebGLShaderManager(); + // time to create the render managers! each one focuses on managine a state in webGL + this.shaderManager = new PIXI.WebGLShaderManager(gl); // deals with managing the shader programs and their attribs + this.spriteBatch = new PIXI.WebGLSpriteBatch(gl); // manages the rendering of sprites + this.maskManager = new PIXI.WebGLMaskManager(gl); // manages the masks using the stencil buffer + this.filterManager = new PIXI.WebGLFilterManager(gl, this.transparent); // manages the filters - /** - * Manages the rendering of sprites - * @property spriteBatch - * @type WebGLSpriteBatch - */ - this.spriteBatch = new PIXI.WebGLSpriteBatch(); - - /** - * Manages the masks using the stencil buffer - * @property maskManager - * @type WebGLMaskManager - */ - this.maskManager = new PIXI.WebGLMaskManager(); - - /** - * Manages the filters - * @property filterManager - * @type WebGLFilterManager - */ - this.filterManager = new PIXI.WebGLFilterManager(); - - /** - * Manages the stencil buffer - * @property stencilManager - * @type WebGLStencilManager - */ - this.stencilManager = new PIXI.WebGLStencilManager(); - - /** - * Manages the blendModes - * @property blendModeManager - * @type WebGLBlendModeManager - */ - this.blendModeManager = new PIXI.WebGLBlendModeManager(); - - /** - * TODO remove - * @property renderSession - * @type Object - */ this.renderSession = {}; this.renderSession.gl = this.gl; this.renderSession.drawCount = 0; this.renderSession.shaderManager = this.shaderManager; this.renderSession.maskManager = this.maskManager; this.renderSession.filterManager = this.filterManager; - this.renderSession.blendModeManager = this.blendModeManager; this.renderSession.spriteBatch = this.spriteBatch; - this.renderSession.stencilManager = this.stencilManager; - this.renderSession.renderer = this; - this.renderSession.resolution = this.resolution; - // time init the context.. - this.initContext(); - // map some webGL blend modes.. - this.mapBlendModes(); + gl.useProgram(this.shaderManager.defaultShader.program); + + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); + + gl.enable(gl.BLEND); + gl.colorMask(true, true, true, this.transparent); }; // constructor PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; -/** -* @method initContext -*/ -PIXI.WebGLRenderer.prototype.initContext = function() -{ - var gl = this.view.getContext('webgl', this._contextOptions) || this.view.getContext('experimental-webgl', this._contextOptions); - this.gl = gl; - - if (!gl) { - // fail, not able to get a context - throw new Error('This browser does not support webGL. Try using the canvas renderer'); - } - - this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++; - - PIXI.glContexts[this.glContextId] = gl; - - PIXI.instances[this.glContextId] = this; - - // set up the default pixi settings.. - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); - gl.enable(gl.BLEND); - - // need to set the context for all the managers... - this.shaderManager.setContext(gl); - this.spriteBatch.setContext(gl); - this.maskManager.setContext(gl); - this.filterManager.setContext(gl); - this.blendModeManager.setContext(gl); - this.stencilManager.setContext(gl); - - this.renderSession.gl = this.gl; - - // now resize and we are good to go! - this.resize(this.width, this.height); -}; - /** * Renders the stage to its webGL view * @@ -7911,9 +5697,9 @@ PIXI.WebGLRenderer.prototype.initContext = function() */ PIXI.WebGLRenderer.prototype.render = function(stage) { - // no point rendering if our context has been blown up! if(this.contextLost)return; + // if rendering a new stage clear the batches.. if(this.__stage !== stage) { @@ -7924,13 +5710,37 @@ PIXI.WebGLRenderer.prototype.render = function(stage) this.__stage = stage; } + // update any textures this includes uvs and uploading them to the gpu + PIXI.WebGLRenderer.updateTextures(); + // update the scene graph stage.updateTransform(); var gl = this.gl; + // -- Does this need to be set every frame? -- // + //gl.colorMask(true, true, true, this.transparent); + gl.viewport(0, 0, this.width, this.height); + + // make sure we are bound to the main frame buffer + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + if(this.transparent) + { + gl.clearColor(0, 0, 0, 0); + } + else + { + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1); + } + + + gl.clear(gl.COLOR_BUFFER_BIT); + + this.renderDisplayObject( stage, this.projection ); + // interaction - if(stage._interactive) + if(stage.interactive) { //need to add some events! if(!stage._interactiveEventsAdded) @@ -7948,51 +5758,43 @@ PIXI.WebGLRenderer.prototype.render = function(stage) } } - // -- Does this need to be set every frame? -- // - gl.viewport(0, 0, this.width, this.height); - - // make sure we are bound to the main frame buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - if (this.clearBeforeRender) - { - if(this.transparent) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1); - } - - gl.clear (gl.COLOR_BUFFER_BIT); - } - - this.renderDisplayObject( stage, this.projection ); + /* + //can simulate context loss in Chrome like so: + this.view.onmousedown = function(ev) { + console.dir(this.gl.getSupportedExtensions()); + var ext = ( + gl.getExtension("WEBGL_scompressed_texture_s3tc") + // gl.getExtension("WEBGL_compressed_texture_s3tc") || + // gl.getExtension("MOZ_WEBGL_compressed_texture_s3tc") || + // gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc") + ); + console.dir(ext); + var loseCtx = this.gl.getExtension("WEBGL_lose_context"); + console.log("killing context"); + loseCtx.loseContext(); + setTimeout(function() { + console.log("restoring context..."); + loseCtx.restoreContext(); + }.bind(this), 1000); + }.bind(this); + */ }; /** - * Renders a Display Object. + * Renders a display Object * - * @method renderDisplayObject + * @method renderDIsplayObject * @param displayObject {DisplayObject} The DisplayObject to render * @param projection {Point} The projection - * @param buffer {Array} a standard WebGL buffer + * @param buffer {Array} a standard WebGL buffer */ PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, projection, buffer) { - this.renderSession.blendModeManager.setBlendMode(PIXI.blendModes.NORMAL); - // reset the render session data.. this.renderSession.drawCount = 0; + this.renderSession.currentBlendMode = 9999; - // make sure to flip the Y if using a render texture.. - this.renderSession.flipY = buffer ? -1 : 1; - - // set the default projection this.renderSession.projection = projection; - - //set the default offset this.renderSession.offset = this.offset; // start the sprite batch @@ -8009,7 +5811,74 @@ PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, proje }; /** - * Resizes the webGL view to the specified width and height. + * Updates the textures loaded into this webgl renderer + * + * @static + * @method updateTextures + * @private + */ +PIXI.WebGLRenderer.updateTextures = function() +{ + var i = 0; + + //TODO break this out into a texture manager... + //for (i = 0; i < PIXI.texturesToUpdate.length; i++) + // PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); + + + for (i=0; i < PIXI.Texture.frameUpdates.length; i++) + PIXI.WebGLRenderer.updateTextureFrame(PIXI.Texture.frameUpdates[i]); + + for (i = 0; i < PIXI.texturesToDestroy.length; i++) + PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); + + PIXI.texturesToUpdate.length = 0; + PIXI.texturesToDestroy.length = 0; + PIXI.Texture.frameUpdates.length = 0; +}; + +/** + * Destroys a loaded webgl texture + * + * @method destroyTexture + * @param texture {Texture} The texture to update + * @private + */ +PIXI.WebGLRenderer.destroyTexture = function(texture) +{ + //TODO break this out into a texture manager... + + for (var i = texture._glTextures.length - 1; i >= 0; i--) + { + var glTexture = texture._glTextures[i]; + var gl = PIXI.glContexts[i]; + + if(gl && glTexture) + { + gl.deleteTexture(glTexture); + } + } + + texture._glTextures.length = 0; +}; + +/** + * + * @method updateTextureFrame + * @param texture {Texture} The texture to update the frame from + * @private + */ +PIXI.WebGLRenderer.updateTextureFrame = function(texture) +{ + texture.updateFrame = false; + + // now set the uvs. Figured that the uv data sits with a texture rather than a sprite. + // so uv data is stored on the texture itself + texture._updateWebGLuvs(); +}; + +/** + * resizes the webGL view to the specified width and height * * @method resize * @param width {Number} the new width of the webGL view @@ -8017,72 +5886,97 @@ PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, proje */ PIXI.WebGLRenderer.prototype.resize = function(width, height) { - this.width = width * this.resolution; - this.height = height * this.resolution; + this.width = width; + this.height = height; - this.view.width = this.width; - this.view.height = this.height; - - if (this.autoResize) { - this.view.style.width = this.width / this.resolution + 'px'; - this.view.style.height = this.height / this.resolution + 'px'; - } + this.view.width = width; + this.view.height = height; this.gl.viewport(0, 0, this.width, this.height); - this.projection.x = this.width / 2 / this.resolution; - this.projection.y = -this.height / 2 / this.resolution; + this.projection.x = this.width/2; + this.projection.y = -this.height/2; }; /** - * Updates and Creates a WebGL texture for the renderers context. + * Creates a WebGL texture * - * @method updateTexture - * @param texture {Texture} the texture to update + * @method createWebGLTexture + * @param texture {Texture} the texture to render + * @param gl {webglContext} the WebGL context + * @static */ -PIXI.WebGLRenderer.prototype.updateTexture = function(texture) +PIXI.createWebGLTexture = function(texture, gl) { - if(!texture.hasLoaded )return; - var gl = this.gl; - if(!texture._glTextures[gl.id])texture._glTextures[gl.id] = gl.createTexture(); - - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - - - if(texture.mipmap && PIXI.isPowerOfTwo(texture.width, texture.height)) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); - gl.generateMipmap(gl.TEXTURE_2D); - } - else + if(texture.hasLoaded) { + texture._glTextures[gl.id] = gl.createTexture(); + + gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - } - // reguler... - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } + // reguler... - texture._dirty[gl.id] = false; + if(!texture._powerOf2) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + + gl.bindTexture(gl.TEXTURE_2D, null); + } return texture._glTextures[gl.id]; }; +/** + * Updates a WebGL texture + * + * @method updateWebGLTexture + * @param texture {Texture} the texture to update + * @param gl {webglContext} the WebGL context + * @private + */ +PIXI.updateWebGLTexture = function(texture, gl) +{ + if( texture._glTextures[gl.id] ) + { + gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); + + // reguler... + + if(!texture._powerOf2) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + + gl.bindTexture(gl.TEXTURE_2D, null); + } + +}; + /** * Handles a lost webgl context * @@ -8105,16 +5999,55 @@ PIXI.WebGLRenderer.prototype.handleContextLost = function(event) */ PIXI.WebGLRenderer.prototype.handleContextRestored = function() { - this.initContext(); - // empty all the ol gl textures as they are useless now + //try 'experimental-webgl' + try { + this.gl = this.view.getContext('experimental-webgl', this.options); + } catch (e) { + //try 'webgl' + try { + this.gl = this.view.getContext('webgl', this.options); + } catch (e2) { + // fail, not able to get a context + throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); + } + } + + var gl = this.gl; + gl.id = PIXI.WebGLRenderer.glContextId ++; + + + + // need to set the context... + this.shaderManager.setContext(gl); + this.spriteBatch.setContext(gl); + this.maskManager.setContext(gl); + this.filterManager.setContext(gl); + + + this.renderSession.gl = this.gl; + + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); + + gl.enable(gl.BLEND); + gl.colorMask(true, true, true, this.transparent); + + this.gl.viewport(0, 0, this.width, this.height); + for(var key in PIXI.TextureCache) { var texture = PIXI.TextureCache[key].baseTexture; texture._glTextures = []; } + /** + * Whether the context was lost + * @property contextLost + * @type Boolean + */ this.contextLost = false; + }; /** @@ -8124,9 +6057,12 @@ PIXI.WebGLRenderer.prototype.handleContextRestored = function() */ PIXI.WebGLRenderer.prototype.destroy = function() { + + // deal with losing context.. + // remove listeners - this.view.removeEventListener('webglcontextlost', this.contextLostBound); - this.view.removeEventListener('webglcontextrestored', this.contextRestoredBound); + this.view.removeEventListener('webglcontextlost', this.contextLost); + this.view.removeEventListener('webglcontextrestored', this.contextRestoredLost); PIXI.glContexts[this.glContextId] = null; @@ -8143,123 +6079,36 @@ PIXI.WebGLRenderer.prototype.destroy = function() this.spriteBatch = null; this.maskManager = null; this.filterManager = null; - + this.gl = null; + // this.renderSession = null; }; -/** - * Maps Pixi blend modes to WebGL blend modes. - * - * @method mapBlendModes - */ -PIXI.WebGLRenderer.prototype.mapBlendModes = function() -{ - var gl = this.gl; - - if(!PIXI.blendModesWebGL) - { - PIXI.blendModesWebGL = []; - - PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; - PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - } -}; PIXI.WebGLRenderer.glContextId = 0; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLBlendModeManager -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLBlendModeManager = function() -{ - /** - * @property currentBlendMode - * @type Number - */ - this.currentBlendMode = 99999; -}; - -PIXI.WebGLBlendModeManager.prototype.constructor = PIXI.WebGLBlendModeManager; - -/** - * Sets the WebGL Context. - * - * @method setContext - * @param gl {WebGLContext} the current WebGL drawing context - */ -PIXI.WebGLBlendModeManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Sets-up the given blendMode from WebGL's point of view. -* -* @method setBlendMode -* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD -*/ -PIXI.WebGLBlendModeManager.prototype.setBlendMode = function(blendMode) -{ - if(this.currentBlendMode === blendMode)return false; - - this.currentBlendMode = blendMode; - - var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; - this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); - - return true; -}; - -/** -* Destroys this object. -* -* @method destroy -*/ -PIXI.WebGLBlendModeManager.prototype.destroy = function() -{ - this.gl = null; -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ + /** * @class WebGLMaskManager * @constructor +* @param gl {WebGLContext} the current WebGL drawing context * @private */ -PIXI.WebGLMaskManager = function() +PIXI.WebGLMaskManager = function(gl) { + this.maskStack = []; + this.maskPosition = 0; + + this.setContext(gl); }; -PIXI.WebGLMaskManager.prototype.constructor = PIXI.WebGLMaskManager; - /** -* Sets the drawing context to the one given in parameter. -* +* Sets the drawing context to the one given in parameter * @method setContext * @param gl {WebGLContext} the current WebGL drawing context */ @@ -8269,347 +6118,73 @@ PIXI.WebGLMaskManager.prototype.setContext = function(gl) }; /** -* Applies the Mask and adds it to the current filter stack. -* +* Applies the Mask and adds it to the current filter stack * @method pushMask * @param maskData {Array} -* @param renderSession {Object} +* @param renderSession {RenderSession} */ PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession) { - var gl = renderSession.gl; + var gl = this.gl; - if(maskData.dirty) + if(this.maskStack.length === 0) { - PIXI.WebGLGraphics.updateGraphics(maskData, gl); + gl.enable(gl.STENCIL_TEST); + gl.stencilFunc(gl.ALWAYS,1,1); } + + // maskData.visible = false; - if(!maskData._webGL[gl.id].data.length)return; + this.maskStack.push(maskData); + + gl.colorMask(false, false, false, true); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - renderSession.stencilManager.pushStencil(maskData, maskData._webGL[gl.id].data[0], renderSession); + PIXI.WebGLGraphics.renderGraphics(maskData, renderSession); + + gl.colorMask(true, true, true, true); + gl.stencilFunc(gl.NOTEQUAL,0, this.maskStack.length); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); }; /** -* Removes the last filter from the filter stack and doesn't return it. -* +* Removes the last filter from the filter stack and doesn't return it * @method popMask -* @param maskData {Array} -* @param renderSession {Object} an object containing all the useful parameters +* +* @param renderSession {RenderSession} an object containing all the useful parameters */ -PIXI.WebGLMaskManager.prototype.popMask = function(maskData, renderSession) +PIXI.WebGLMaskManager.prototype.popMask = function(renderSession) { var gl = this.gl; - renderSession.stencilManager.popStencil(maskData, maskData._webGL[gl.id].data[0], renderSession); + + var maskData = this.maskStack.pop(); + + if(maskData) + { + gl.colorMask(false, false, false, false); + + //gl.stencilFunc(gl.ALWAYS,1,1); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); + + PIXI.WebGLGraphics.renderGraphics(maskData, renderSession); + + gl.colorMask(true, true, true, true); + gl.stencilFunc(gl.NOTEQUAL,0,this.maskStack.length); + gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); + } + + if(this.maskStack.length === 0)gl.disable(gl.STENCIL_TEST); }; /** -* Destroys the mask stack. -* +* Destroys the mask stack * @method destroy */ PIXI.WebGLMaskManager.prototype.destroy = function() { + this.maskStack = null; this.gl = null; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLStencilManager -* @constructor -* @private -*/ -PIXI.WebGLStencilManager = function() -{ - this.stencilStack = []; - this.reverse = true; - this.count = 0; -}; - -/** -* Sets the drawing context to the one given in parameter. -* -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLStencilManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Applies the Mask and adds it to the current filter stack. -* -* @method pushMask -* @param graphics {Graphics} -* @param webGLData {Array} -* @param renderSession {Object} -*/ -PIXI.WebGLStencilManager.prototype.pushStencil = function(graphics, webGLData, renderSession) -{ - var gl = this.gl; - this.bindGraphics(graphics, webGLData, renderSession); - - if(this.stencilStack.length === 0) - { - gl.enable(gl.STENCIL_TEST); - gl.clear(gl.STENCIL_BUFFER_BIT); - this.reverse = true; - this.count = 0; - } - - this.stencilStack.push(webGLData); - - var level = this.count; - - gl.colorMask(false, false, false, false); - - gl.stencilFunc(gl.ALWAYS,0,0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT); - - // draw the triangle strip! - - if(webGLData.mode === 1) - { - gl.drawElements(gl.TRIANGLE_FAN, webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 ); - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - - // draw a quad to increment.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - } - - this.reverse = !this.reverse; - } - else - { - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - } - } - - gl.colorMask(true, true, true, true); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - - this.count++; -}; - -/** - * TODO this does not belong here! - * - * @method bindGraphics - * @param graphics {Graphics} - * @param webGLData {Array} - * @param renderSession {Object} - */ -PIXI.WebGLStencilManager.prototype.bindGraphics = function(graphics, webGLData, renderSession) -{ - //if(this._currentGraphics === graphics)return; - this._currentGraphics = graphics; - - var gl = this.gl; - - // bind the graphics object.. - var projection = renderSession.projection, - offset = renderSession.offset, - shader;// = renderSession.shaderManager.primitiveShader; - - if(webGLData.mode === 1) - { - shader = renderSession.shaderManager.complexPrimitiveShader; - - renderSession.shaderManager.setShader( shader ); - - gl.uniform1f(shader.flipY, renderSession.flipY); - - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - gl.uniform3fv(shader.color, webGLData.color); - - gl.uniform1f(shader.alpha, graphics.worldAlpha * webGLData.alpha); - - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 2, 0); - - - // now do the rest.. - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - } - else - { - //renderSession.shaderManager.activatePrimitiveShader(); - shader = renderSession.shaderManager.primitiveShader; - renderSession.shaderManager.setShader( shader ); - - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform1f(shader.flipY, renderSession.flipY); - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - - gl.uniform1f(shader.alpha, graphics.worldAlpha); - - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - } -}; - -/** - * @method popStencil - * @param graphics {Graphics} - * @param webGLData {Array} - * @param renderSession {Object} - */ -PIXI.WebGLStencilManager.prototype.popStencil = function(graphics, webGLData, renderSession) -{ - var gl = this.gl; - this.stencilStack.pop(); - - this.count--; - - if(this.stencilStack.length === 0) - { - // the stack is empty! - gl.disable(gl.STENCIL_TEST); - - } - else - { - - var level = this.count; - - this.bindGraphics(graphics, webGLData, renderSession); - - gl.colorMask(false, false, false, false); - - if(webGLData.mode === 1) - { - this.reverse = !this.reverse; - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - - // draw a quad to increment.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - gl.stencilFunc(gl.ALWAYS,0,0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT); - - // draw the triangle strip! - gl.drawElements(gl.TRIANGLE_FAN, webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - } - - } - else - { - // console.log("<<>>") - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - } - } - - gl.colorMask(true, true, true, true); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - - - } -}; - -/** -* Destroys the mask stack. -* -* @method destroy -*/ -PIXI.WebGLStencilManager.prototype.destroy = function() -{ - this.stencilStack = null; - this.gl = null; -}; - +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -8617,79 +6192,59 @@ PIXI.WebGLStencilManager.prototype.destroy = function() /** * @class WebGLShaderManager * @constructor +* @param gl {WebGLContext} the current WebGL drawing context * @private */ -PIXI.WebGLShaderManager = function() +PIXI.WebGLShaderManager = function(gl) { - /** - * @property maxAttibs - * @type Number - */ + this.maxAttibs = 10; - - /** - * @property attribState - * @type Array - */ this.attribState = []; - - /** - * @property tempAttribState - * @type Array - */ this.tempAttribState = []; - for (var i = 0; i < this.maxAttibs; i++) - { + for (var i = 0; i < this.maxAttibs; i++) { this.attribState[i] = false; } - /** - * @property stack - * @type Array - */ - this.stack = []; - + this.setContext(gl); + // the final one is used for the rendering strips + //this.stripShader = new PIXI.StripShader(gl); }; -PIXI.WebGLShaderManager.prototype.constructor = PIXI.WebGLShaderManager; /** -* Initialises the context and the properties. -* +* Initialises the context and the properties * @method setContext * @param gl {WebGLContext} the current WebGL drawing context +* @param transparent {Boolean} Whether or not the drawing context should be transparent */ PIXI.WebGLShaderManager.prototype.setContext = function(gl) { this.gl = gl; - // the next one is used for rendering primitives + // the next one is used for rendering primatives this.primitiveShader = new PIXI.PrimitiveShader(gl); - // the next one is used for rendering triangle strips - this.complexPrimitiveShader = new PIXI.ComplexPrimitiveShader(gl); - // this shader is used for the default sprite rendering this.defaultShader = new PIXI.PixiShader(gl); // this shader is used for the fast sprite rendering this.fastShader = new PIXI.PixiFastShader(gl); - // the next one is used for rendering triangle strips - this.stripShader = new PIXI.StripShader(gl); - this.setShader(this.defaultShader); + + this.activateShader(this.defaultShader); }; + /** -* Takes the attributes given in parameters. -* +* Takes the attributes given in parameters * @method setAttribs * @param attribs {Array} attribs */ PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs) { // reset temp state + var i; for (i = 0; i < this.tempAttribState.length; i++) @@ -8708,6 +6263,7 @@ PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs) for (i = 0; i < this.attribState.length; i++) { + if(this.attribState[i] !== this.tempAttribState[i]) { this.attribState[i] = this.tempAttribState[i]; @@ -8725,28 +6281,51 @@ PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs) }; /** -* Sets the current shader. -* -* @method setShader -* @param shader {Any} +* Sets-up the given shader +* +* @method activateShader +* @param shader {Object} the shader that is going to be activated */ -PIXI.WebGLShaderManager.prototype.setShader = function(shader) +PIXI.WebGLShaderManager.prototype.activateShader = function(shader) { - if(this._currentId === shader._UID)return false; - - this._currentId = shader._UID; + //if(this.currentShader == shader)return; this.currentShader = shader; this.gl.useProgram(shader.program); this.setAttribs(shader.attributes); - - return true; + }; /** -* Destroys this object. -* +* Triggers the primitive shader +* @method activatePrimitiveShader +*/ +PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function() +{ + var gl = this.gl; + + gl.useProgram(this.primitiveShader.program); + + this.setAttribs(this.primitiveShader.attributes); + +}; + +/** +* Disable the primitive shader +* @method deactivatePrimitiveShader +*/ +PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function() +{ + var gl = this.gl; + + gl.useProgram(this.defaultShader.program); + + this.setAttribs(this.defaultShader.attributes); +}; + +/** +* Destroys * @method destroy */ PIXI.WebGLShaderManager.prototype.destroy = function() @@ -8757,24 +6336,20 @@ PIXI.WebGLShaderManager.prototype.destroy = function() this.primitiveShader.destroy(); - this.complexPrimitiveShader.destroy(); - this.defaultShader.destroy(); this.fastShader.destroy(); - this.stripShader.destroy(); - this.gl = null; }; + /** * @author Mat Groves * * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ * for creating the original pixi version! - * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer - * + * * Heavily inspired by LibGDX's WebGLSpriteBatch: * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java */ @@ -8784,63 +6359,51 @@ PIXI.WebGLShaderManager.prototype.destroy = function() * @class WebGLSpriteBatch * @private * @constructor + * @param gl {WebGLContext} the current WebGL drawing context + * */ -PIXI.WebGLSpriteBatch = function() +PIXI.WebGLSpriteBatch = function(gl) { + /** + * + * * @property vertSize * @type Number */ - this.vertSize = 5; + this.vertSize = 6; /** * The number of images in the SpriteBatch before it flushes * @property size * @type Number */ - this.size = 2000;//Math.pow(2, 16) / this.vertSize; + this.size = 10000;//Math.pow(2, 16) / this.vertSize; - //the total number of bytes in our batch - var numVerts = this.size * 4 * 4 * this.vertSize; + //the total number of floats in our batch + var numVerts = this.size * 4 * this.vertSize; //the total number of indices in our batch var numIndices = this.size * 6; + //vertex data + /** * Holds the vertices * * @property vertices - * @type ArrayBuffer - */ - this.vertices = new PIXI.ArrayBuffer(numVerts); - - /** - * View on the vertices as a Float32Array - * - * @property positions * @type Float32Array */ - this.positions = new PIXI.Float32Array(this.vertices); - - /** - * View on the vertices as a Uint32Array - * - * @property colors - * @type Uint32Array - */ - this.colors = new PIXI.Uint32Array(this.vertices); + this.vertices = new Float32Array(numVerts); + //index data /** * Holds the indices * * @property indices * @type Uint16Array */ - this.indices = new PIXI.Uint16Array(numIndices); + this.indices = new Uint16Array(numIndices); - /** - * @property lastIndexCount - * @type Number - */ this.lastIndexCount = 0; for (var i=0, j=0; i < numIndices; i += 6, j += 4) @@ -8853,71 +6416,18 @@ PIXI.WebGLSpriteBatch = function() this.indices[i + 5] = j + 3; } - /** - * @property drawing - * @type Boolean - */ + this.drawing = false; - - /** - * @property currentBatchSize - * @type Number - */ this.currentBatchSize = 0; - - /** - * @property currentBaseTexture - * @type BaseTexture - */ this.currentBaseTexture = null; - - /** - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * @property textures - * @type Array - */ - this.textures = []; - - /** - * @property blendModes - * @type Array - */ - this.blendModes = []; - - /** - * @property shaders - * @type Array - */ - this.shaders = []; - - /** - * @property sprites - * @type Array - */ - this.sprites = []; - - /** - * @property defaultShader - * @type AbstractFilter - */ - this.defaultShader = new PIXI.AbstractFilter([ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]); + + this.setContext(gl); }; /** +* * @method setContext +* * @param gl {WebGLContext} the current WebGL drawing context */ PIXI.WebGLSpriteBatch.prototype.setContext = function(gl) @@ -8930,6 +6440,7 @@ PIXI.WebGLSpriteBatch.prototype.setContext = function(gl) // 65535 is max index, so 65535 / 6 = 10922. + //upload the index data gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); @@ -8938,19 +6449,13 @@ PIXI.WebGLSpriteBatch.prototype.setContext = function(gl) gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); this.currentBlendMode = 99999; - - var shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc = this.defaultShader.fragmentSrc; - shader.uniforms = {}; - shader.init(); - - this.defaultShader.shaders[gl.id] = shader; }; /** +* * @method begin -* @param renderSession {Object} The RenderSession object +* +* @param renderSession {RenderSession} the RenderSession */ PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession) { @@ -8961,7 +6466,9 @@ PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession) }; /** +* * @method end +* */ PIXI.WebGLSpriteBatch.prototype.end = function() { @@ -8969,150 +6476,146 @@ PIXI.WebGLSpriteBatch.prototype.end = function() }; /** +* * @method render +* * @param sprite {Sprite} the sprite to render when using this spritebatch */ PIXI.WebGLSpriteBatch.prototype.render = function(sprite) { - var texture = sprite.texture; - - //TODO set blend modes.. // check texture.. - if(this.currentBatchSize >= this.size) + if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { this.flush(); - this.currentBaseTexture = texture.baseTexture; + this.currentBaseTexture = sprite.texture.baseTexture; + } + + + // check blend mode + if(sprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(sprite.blendMode); } // get the uvs for the texture - var uvs = texture._uvs; + var uvs = sprite._uvs || sprite.texture._uvs; // if the uvs have not updated then no point rendering just yet! if(!uvs)return; + // get the sprites current alpha + var alpha = sprite.worldAlpha; + var tint = sprite.tint; + + var verticies = this.vertices; + + var width = sprite.texture.frame.width; + var height = sprite.texture.frame.height; + // TODO trim?? var aX = sprite.anchor.x; var aY = sprite.anchor.y; var w0, w1, h0, h1; - if (texture.trim) + if (sprite.texture.trim) { // if the sprite is trimmed then we need to add the extra space before transforming the sprite coords.. - var trim = texture.trim; + var trim = sprite.texture.trim; w1 = trim.x - aX * trim.width; - w0 = w1 + texture.crop.width; + w0 = w1 + width; h1 = trim.y - aY * trim.height; - h0 = h1 + texture.crop.height; - + h0 = h1 + height; } else { - w0 = (texture.frame.width ) * (1-aX); - w1 = (texture.frame.width ) * -aX; + w0 = (width ) * (1-aX); + w1 = (width ) * -aX; - h0 = texture.frame.height * (1-aY); - h1 = texture.frame.height * -aY; + h0 = height * (1-aY); + h1 = height * -aY; } var index = this.currentBatchSize * 4 * this.vertSize; + + var worldTransform = sprite.worldTransform;//.toArray(); + + var a = worldTransform.a;//[0]; + var b = worldTransform.c;//[3]; + var c = worldTransform.b;//[1]; + var d = worldTransform.d;//[4]; + var tx = worldTransform.tx;//[2]; + var ty = worldTransform.ty;///[5]; + + // xy + verticies[index++] = a * w1 + c * h1 + tx; + verticies[index++] = d * h1 + b * w1 + ty; + // uv + verticies[index++] = uvs.x0; + verticies[index++] = uvs.y0; + // color + verticies[index++] = alpha; + verticies[index++] = tint; + + // xy + verticies[index++] = a * w0 + c * h1 + tx; + verticies[index++] = d * h1 + b * w0 + ty; + // uv + verticies[index++] = uvs.x1; + verticies[index++] = uvs.y1; + // color + verticies[index++] = alpha; + verticies[index++] = tint; + + // xy + verticies[index++] = a * w0 + c * h0 + tx; + verticies[index++] = d * h0 + b * w0 + ty; + // uv + verticies[index++] = uvs.x2; + verticies[index++] = uvs.y2; + // color + verticies[index++] = alpha; + verticies[index++] = tint; + + // xy + verticies[index++] = a * w1 + c * h0 + tx; + verticies[index++] = d * h0 + b * w1 + ty; + // uv + verticies[index++] = uvs.x3; + verticies[index++] = uvs.y3; + // color + verticies[index++] = alpha; + verticies[index++] = tint; - var resolution = texture.baseTexture.resolution; - - var worldTransform = sprite.worldTransform; - - var a = worldTransform.a / resolution; - var b = worldTransform.b / resolution; - var c = worldTransform.c / resolution; - var d = worldTransform.d / resolution; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var colors = this.colors; - var positions = this.positions; - - if(this.renderSession.roundPixels) - { - // xy - positions[index] = a * w1 + c * h1 + tx | 0; - positions[index+1] = d * h1 + b * w1 + ty | 0; - - // xy - positions[index+5] = a * w0 + c * h1 + tx | 0; - positions[index+6] = d * h1 + b * w0 + ty | 0; - - // xy - positions[index+10] = a * w0 + c * h0 + tx | 0; - positions[index+11] = d * h0 + b * w0 + ty | 0; - - // xy - positions[index+15] = a * w1 + c * h0 + tx | 0; - positions[index+16] = d * h0 + b * w1 + ty | 0; - } - else - { - // xy - positions[index] = a * w1 + c * h1 + tx; - positions[index+1] = d * h1 + b * w1 + ty; - - // xy - positions[index+5] = a * w0 + c * h1 + tx; - positions[index+6] = d * h1 + b * w0 + ty; - - // xy - positions[index+10] = a * w0 + c * h0 + tx; - positions[index+11] = d * h0 + b * w0 + ty; - - // xy - positions[index+15] = a * w1 + c * h0 + tx; - positions[index+16] = d * h0 + b * w1 + ty; - } - - // uv - positions[index+2] = uvs.x0; - positions[index+3] = uvs.y0; - - // uv - positions[index+7] = uvs.x1; - positions[index+8] = uvs.y1; - - // uv - positions[index+12] = uvs.x2; - positions[index+13] = uvs.y2; - - // uv - positions[index+17] = uvs.x3; - positions[index+18] = uvs.y3; - - // color and alpha - var tint = sprite.tint; - colors[index+4] = colors[index+9] = colors[index+14] = colors[index+19] = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (sprite.worldAlpha * 255 << 24); - // increment the batchsize - this.sprites[this.currentBatchSize++] = sprite; + this.currentBatchSize++; }; /** -* Renders a TilingSprite using the spriteBatch. -* +* Renders a tilingSprite using the spriteBatch * @method renderTilingSprite +* * @param sprite {TilingSprite} the tilingSprite to render */ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) { var texture = tilingSprite.tilingTexture; - // check texture.. - if(this.currentBatchSize >= this.size) + if(texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size) { - //return; this.flush(); this.currentBaseTexture = texture.baseTexture; } + // check blend mode + if(tilingSprite.blendMode !== this.currentBlendMode) + { + this.setBlendMode(tilingSprite.blendMode); + } + // set the textures uvs temporarily // TODO create a separate texture so that we can tile part of a texture @@ -9120,11 +6623,11 @@ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) var uvs = tilingSprite._uvs; - tilingSprite.tilePosition.x %= texture.baseTexture.width * tilingSprite.tileScaleOffset.x; - tilingSprite.tilePosition.y %= texture.baseTexture.height * tilingSprite.tileScaleOffset.y; + tilingSprite.tilePosition.x %= texture.baseTexture.width; + tilingSprite.tilePosition.y %= texture.baseTexture.height; - var offsetX = tilingSprite.tilePosition.x/(texture.baseTexture.width*tilingSprite.tileScaleOffset.x); - var offsetY = tilingSprite.tilePosition.y/(texture.baseTexture.height*tilingSprite.tileScaleOffset.y); + var offsetX = tilingSprite.tilePosition.x/texture.baseTexture.width; + var offsetY = tilingSprite.tilePosition.y/texture.baseTexture.height; var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x); var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y); @@ -9139,21 +6642,20 @@ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) uvs.y2 = (1 * scaleY) - offsetY; uvs.x3 = 0 - offsetX; - uvs.y3 = (1 * scaleY) - offsetY; + uvs.y3 = (1 *scaleY) - offsetY; - // get the tilingSprites current alpha and tint and combining them into a single color + // get the tilingSprites current alpha + var alpha = tilingSprite.worldAlpha; var tint = tilingSprite.tint; - var color = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (tilingSprite.alpha * 255 << 24); - var positions = this.positions; - var colors = this.colors; + var verticies = this.vertices; var width = tilingSprite.width; var height = tilingSprite.height; // TODO trim?? - var aX = tilingSprite.anchor.x; - var aY = tilingSprite.anchor.y; + var aX = tilingSprite.anchor.x; // - tilingSprite.texture.trim.x + var aY = tilingSprite.anchor.y; //- tilingSprite.texture.trim.y var w0 = width * (1-aX); var w1 = width * -aX; @@ -9162,61 +6664,65 @@ PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) var index = this.currentBatchSize * 4 * this.vertSize; - var resolution = texture.baseTexture.resolution; - var worldTransform = tilingSprite.worldTransform; - var a = worldTransform.a / resolution;//[0]; - var b = worldTransform.b / resolution;//[3]; - var c = worldTransform.c / resolution;//[1]; - var d = worldTransform.d / resolution;//[4]; + var a = worldTransform.a;//[0]; + var b = worldTransform.c;//[3]; + var c = worldTransform.b;//[1]; + var d = worldTransform.d;//[4]; var tx = worldTransform.tx;//[2]; - var ty = worldTransform.ty;//[5]; + var ty = worldTransform.ty;///[5]; // xy - positions[index++] = a * w1 + c * h1 + tx; - positions[index++] = d * h1 + b * w1 + ty; + verticies[index++] = a * w1 + c * h1 + tx; + verticies[index++] = d * h1 + b * w1 + ty; // uv - positions[index++] = uvs.x0; - positions[index++] = uvs.y0; + verticies[index++] = uvs.x0; + verticies[index++] = uvs.y0; // color - colors[index++] = color; + verticies[index++] = alpha; + verticies[index++] = tint; // xy - positions[index++] = (a * w0 + c * h1 + tx); - positions[index++] = d * h1 + b * w0 + ty; + verticies[index++] = a * w0 + c * h1 + tx; + verticies[index++] = d * h1 + b * w0 + ty; // uv - positions[index++] = uvs.x1; - positions[index++] = uvs.y1; + verticies[index++] = uvs.x1; + verticies[index++] = uvs.y1; // color - colors[index++] = color; + verticies[index++] = alpha; + verticies[index++] = tint; // xy - positions[index++] = a * w0 + c * h0 + tx; - positions[index++] = d * h0 + b * w0 + ty; + verticies[index++] = a * w0 + c * h0 + tx; + verticies[index++] = d * h0 + b * w0 + ty; // uv - positions[index++] = uvs.x2; - positions[index++] = uvs.y2; + verticies[index++] = uvs.x2; + verticies[index++] = uvs.y2; // color - colors[index++] = color; + verticies[index++] = alpha; + verticies[index++] = tint; // xy - positions[index++] = a * w1 + c * h0 + tx; - positions[index++] = d * h0 + b * w1 + ty; + verticies[index++] = a * w1 + c * h0 + tx; + verticies[index++] = d * h0 + b * w1 + ty; // uv - positions[index++] = uvs.x3; - positions[index++] = uvs.y3; + verticies[index++] = uvs.x3; + verticies[index++] = uvs.y3; // color - colors[index++] = color; + verticies[index++] = alpha; + verticies[index++] = tint; - // increment the batchsize - this.sprites[this.currentBatchSize++] = tilingSprite; + // increment the batchs + this.currentBatchSize++; }; + /** -* Renders the content and empties the current batch. +* Renders the content and empties the current batch * * @method flush +* */ PIXI.WebGLSpriteBatch.prototype.flush = function() { @@ -9224,175 +6730,102 @@ PIXI.WebGLSpriteBatch.prototype.flush = function() if (this.currentBatchSize===0)return; var gl = this.gl; - var shader; + + // bind the current texture + gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.currentBaseTexture, gl)); - if(this.dirty) - { - this.dirty = false; - // bind the main texture - gl.activeTexture(gl.TEXTURE0); - - // bind the buffers - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - shader = this.defaultShader.shaders[gl.id]; - - // this is the same for each shader? - var stride = this.vertSize * 4; - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - - // color attributes will be interpreted as unsigned bytes and normalized - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.UNSIGNED_BYTE, true, stride, 4 * 4); - } - - // upload the verts to the buffer + // upload the verts to the buffer + if(this.currentBatchSize > ( this.size * 0.5 ) ) { gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); } else { - var view = this.positions.subarray(0, this.currentBatchSize * 4 * this.vertSize); + var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); } - var nextTexture, nextBlendMode, nextShader; - var batchSize = 0; - var start = 0; - - var currentBaseTexture = null; - var currentBlendMode = this.renderSession.blendModeManager.currentBlendMode; - var currentShader = null; - - var blendSwap = false; - var shaderSwap = false; - var sprite; - - for (var i = 0, j = this.currentBatchSize; i < j; i++) { - - sprite = this.sprites[i]; - - nextTexture = sprite.texture.baseTexture; - nextBlendMode = sprite.blendMode; - nextShader = sprite.shader || this.defaultShader; - - blendSwap = currentBlendMode !== nextBlendMode; - shaderSwap = currentShader !== nextShader; // should I use _UIDS??? - - if(currentBaseTexture !== nextTexture || blendSwap || shaderSwap) - { - this.renderBatch(currentBaseTexture, batchSize, start); - - start = i; - batchSize = 0; - currentBaseTexture = nextTexture; - - if( blendSwap ) - { - currentBlendMode = nextBlendMode; - this.renderSession.blendModeManager.setBlendMode( currentBlendMode ); - } - - if( shaderSwap ) - { - currentShader = nextShader; - - shader = currentShader.shaders[gl.id]; - - if(!shader) - { - shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc =currentShader.fragmentSrc; - shader.uniforms =currentShader.uniforms; - shader.init(); - - currentShader.shaders[gl.id] = shader; - } - - // set shader function??? - this.renderSession.shaderManager.setShader(shader); - - if(shader.dirty)shader.syncUniforms(); - - // both thease only need to be set if they are changing.. - // set the projection - var projection = this.renderSession.projection; - gl.uniform2f(shader.projectionVector, projection.x, projection.y); - - // TODO - this is temprorary! - var offsetVector = this.renderSession.offset; - gl.uniform2f(shader.offsetVector, offsetVector.x, offsetVector.y); - - // set the pointers - } - } - - batchSize++; - } - - this.renderBatch(currentBaseTexture, batchSize, start); - + // var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); + //gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); + + // now draw those suckas! + gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); + // then reset the batch! this.currentBatchSize = 0; -}; -/** -* @method renderBatch -* @param texture {Texture} -* @param size {Number} -* @param startIndex {Number} -*/ -PIXI.WebGLSpriteBatch.prototype.renderBatch = function(texture, size, startIndex) -{ - if(size === 0)return; - - var gl = this.gl; - - // check if a texture is dirty.. - if(texture._dirty[gl.id]) - { - this.renderSession.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - } - - // now draw those suckas! - gl.drawElements(gl.TRIANGLES, size * 6, gl.UNSIGNED_SHORT, startIndex * 6 * 2); - // increment the draw count this.renderSession.drawCount++; }; /** +* * @method stop +* */ PIXI.WebGLSpriteBatch.prototype.stop = function() { this.flush(); - this.dirty = true; }; /** +* * @method start +* */ PIXI.WebGLSpriteBatch.prototype.start = function() { - this.dirty = true; + var gl = this.gl; + + // bind the main texture + gl.activeTexture(gl.TEXTURE0); + + // bind the buffers + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + + // set the projection + var projection = this.renderSession.projection; + gl.uniform2f(this.shader.projectionVector, projection.x, projection.y); + + // set the pointers + var stride = this.vertSize * 4; + gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); + gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); + gl.vertexAttribPointer(this.shader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4); + + // set the blend mode.. + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } }; /** -* Destroys the SpriteBatch. -* +* Sets-up the given blendMode from WebGL's point of view +* @method setBlendMode +* +* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD +*/ +PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); +}; + +/** +* Destroys the SpriteBatch * @method destroy */ PIXI.WebGLSpriteBatch.prototype.destroy = function() { + this.vertices = null; this.indices = null; @@ -9403,6 +6836,8 @@ PIXI.WebGLSpriteBatch.prototype.destroy = function() this.gl = null; }; + + /** * @author Mat Groves * @@ -9413,66 +6848,27 @@ PIXI.WebGLSpriteBatch.prototype.destroy = function() * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java */ -/** -* @class WebGLFastSpriteBatch -* @constructor -*/ PIXI.WebGLFastSpriteBatch = function(gl) { - /** - * @property vertSize - * @type Number - */ + + this.vertSize = 10; - - /** - * @property maxSize - * @type Number - */ this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize; - - /** - * @property size - * @type Number - */ this.size = this.maxSize; //the total number of floats in our batch var numVerts = this.size * 4 * this.vertSize; - //the total number of indices in our batch var numIndices = this.maxSize * 6; - /** - * Vertex data - * @property vertices - * @type Float32Array - */ - this.vertices = new PIXI.Float32Array(numVerts); - - /** - * Index data - * @property indices - * @type Uint16Array - */ - this.indices = new PIXI.Uint16Array(numIndices); + //vertex data + this.vertices = new Float32Array(numVerts); + //index data + this.indices = new Uint16Array(numIndices); - /** - * @property vertexBuffer - * @type Object - */ this.vertexBuffer = null; - - /** - * @property indexBuffer - * @type Object - */ this.indexBuffer = null; - /** - * @property lastIndexCount - * @type Number - */ this.lastIndexCount = 0; for (var i=0, j=0; i < numIndices; i += 6, j += 4) @@ -9485,59 +6881,21 @@ PIXI.WebGLFastSpriteBatch = function(gl) this.indices[i + 5] = j + 3; } - /** - * @property drawing - * @type Boolean - */ this.drawing = false; - - /** - * @property currentBatchSize - * @type Number - */ this.currentBatchSize = 0; - - /** - * @property currentBaseTexture - * @type BaseTexture - */ this.currentBaseTexture = null; - /** - * @property currentBlendMode - * @type Number - */ this.currentBlendMode = 0; - - /** - * @property renderSession - * @type Object - */ this.renderSession = null; - /** - * @property shader - * @type Object - */ + this.shader = null; - /** - * @property matrix - * @type Matrix - */ this.matrix = null; this.setContext(gl); }; -PIXI.WebGLFastSpriteBatch.prototype.constructor = PIXI.WebGLFastSpriteBatch; - -/** - * Sets the WebGL Context. - * - * @method setContext - * @param gl {WebGLContext} the current WebGL drawing context - */ PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl) { this.gl = gl; @@ -9548,19 +6906,17 @@ PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl) // 65535 is max index, so 65535 / 6 = 10922. + //upload the index data gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); + + this.currentBlendMode = 99999; }; -/** - * @method begin - * @param spriteBatch {WebGLSpriteBatch} - * @param renderSession {Object} - */ PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession) { this.renderSession = renderSession; @@ -9571,20 +6927,15 @@ PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession) this.start(); }; -/** - * @method end - */ PIXI.WebGLFastSpriteBatch.prototype.end = function() { this.flush(); }; -/** - * @method render - * @param spriteBatch {WebGLSpriteBatch} - */ + PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) { + var children = spriteBatch.children; var sprite = children[0]; @@ -9594,12 +6945,10 @@ PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) if(!sprite.texture._uvs)return; this.currentBaseTexture = sprite.texture.baseTexture; - // check blend mode - if(sprite.blendMode !== this.renderSession.blendModeManager.currentBlendMode) + if(sprite.blendMode !== this.currentBlendMode) { - this.flush(); - this.renderSession.blendModeManager.setBlendMode(sprite.blendMode); + this.setBlendMode(sprite.blendMode); } for(var i=0,j= children.length; i ( this.size * 0.5 ) ) { @@ -9780,6 +7124,7 @@ PIXI.WebGLFastSpriteBatch.prototype.flush = function() gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); } + // now draw those suckas! gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); @@ -9791,17 +7136,11 @@ PIXI.WebGLFastSpriteBatch.prototype.flush = function() }; -/** - * @method stop - */ PIXI.WebGLFastSpriteBatch.prototype.stop = function() { this.flush(); }; -/** - * @method start - */ PIXI.WebGLFastSpriteBatch.prototype.start = function() { var gl = this.gl; @@ -9829,9 +7168,26 @@ PIXI.WebGLFastSpriteBatch.prototype.start = function() gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4); gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4); gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4); - + + // set the blend mode.. + if(this.currentBlendMode !== PIXI.blendModes.NORMAL) + { + this.setBlendMode(PIXI.blendModes.NORMAL); + } }; +PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode) +{ + this.flush(); + + this.currentBlendMode = blendMode; + + var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; + this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); +}; + + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -9839,33 +7195,25 @@ PIXI.WebGLFastSpriteBatch.prototype.start = function() /** * @class WebGLFilterManager * @constructor +* @param gl {WebGLContext} the current WebGL drawing context +* @param transparent {Boolean} Whether or not the drawing context should be transparent +* @private */ -PIXI.WebGLFilterManager = function() +PIXI.WebGLFilterManager = function(gl, transparent) { - /** - * @property filterStack - * @type Array - */ + this.transparent = transparent; + this.filterStack = []; - /** - * @property offsetX - * @type Number - */ this.offsetX = 0; - - /** - * @property offsetY - * @type Number - */ this.offsetY = 0; + + this.setContext(gl); }; -PIXI.WebGLFilterManager.prototype.constructor = PIXI.WebGLFilterManager; - +// API /** -* Initialises the context and the properties. -* +* Initialises the context and the properties * @method setContext * @param gl {WebGLContext} the current WebGL drawing context */ @@ -9878,6 +7226,7 @@ PIXI.WebGLFilterManager.prototype.setContext = function(gl) }; /** +* * @method begin * @param renderSession {RenderSession} * @param buffer {ArrayBuffer} @@ -9888,14 +7237,14 @@ PIXI.WebGLFilterManager.prototype.begin = function(renderSession, buffer) this.defaultShader = renderSession.shaderManager.defaultShader; var projection = this.renderSession.projection; + this.width = projection.x * 2; this.height = -projection.y * 2; this.buffer = buffer; }; /** -* Applies the filter and adds it to the current filter stack. -* +* Applies the filter and adds it to the current filter stack * @method pushFilter * @param filterBlock {Object} the filter that will be pushed to the current filter stack */ @@ -9906,7 +7255,6 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) var projection = this.renderSession.projection; var offset = this.renderSession.offset; - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); // filter program // OPTIMISATION - the first filter is free if its a simple color change? @@ -9914,8 +7262,8 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) var filter = filterBlock.filterPasses[0]; - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; var texture = this.texturePool.pop(); if(!texture) @@ -9929,13 +7277,15 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) gl.bindTexture(gl.TEXTURE_2D, texture.texture); - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; + filterBlock.target.filterArea = filterBlock.target.getBounds(); - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; + var filterArea = filterBlock.target.filterArea; + + var padidng = filter.padding; + filterArea.x -= padidng; + filterArea.y -= padidng; + filterArea.width += padidng * 2; + filterArea.height += padidng * 2; // cap filter to screen size.. if(filterArea.x < 0)filterArea.x = 0; @@ -9956,10 +7306,8 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) offset.y = -filterArea.y; // update projection - // now restore the regular shader.. - // this.renderSession.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); + gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); gl.colorMask(true, true, true, true); gl.clearColor(0,0,0, 0); @@ -9969,16 +7317,16 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) }; + /** -* Removes the last filter from the filter stack and doesn't return it. -* +* Removes the last filter from the filter stack and doesn't return it * @method popFilter */ PIXI.WebGLFilterManager.prototype.popFilter = function() { var gl = this.gl; var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; + var filterArea = filterBlock.target.filterArea; var texture = filterBlock._glFilterTexture; var projection = this.renderSession.projection; var offset = this.renderSession.offset; @@ -10015,7 +7363,6 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() var inputTexture = texture; var outputTexture = this.texturePool.pop(); if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height); - outputTexture.resize(this.width, this.height); // need to clear this FBO as it may have some left over elements from a previous filter. gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); @@ -10054,6 +7401,7 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() this.offsetX -= filterArea.x; this.offsetY -= filterArea.y; + var sizeX = this.width; var sizeY = this.height; @@ -10065,12 +7413,12 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() // time to render the filters texture to the previous scene if(this.filterStack.length === 0) { - gl.colorMask(true, true, true, true);//this.transparent); + gl.colorMask(true, true, true, this.transparent); } else { var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; + filterArea = currentFilter.target.filterArea; sizeX = filterArea.width; sizeY = filterArea.height; @@ -10081,14 +7429,16 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() buffer = currentFilter._glFilterTexture.frameBuffer; } - // TODO need to remove these global elements.. + + + // TODO need toremove thease global elements.. projection.x = sizeX/2; projection.y = -sizeY/2; offset.x = offsetX; offset.y = offsetY; - filterArea = filterBlock._filterArea; + filterArea = filterBlock.target.filterArea; var x = filterArea.x-offsetX; var y = filterArea.y-offsetY; @@ -10121,7 +7471,6 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); gl.viewport(0, 0, sizeX, sizeY); - // bind the buffer gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); @@ -10135,10 +7484,10 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() // apply! this.applyFilterPass(filter, filterArea, sizeX, sizeY); - // now restore the regular shader.. should happen automatically now.. - // this.renderSession.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); + // now restore the regular shader.. + gl.useProgram(this.defaultShader.program); + gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); // return the texture to the pool this.texturePool.push(texture); @@ -10147,11 +7496,10 @@ PIXI.WebGLFilterManager.prototype.popFilter = function() /** -* Applies the filter to the specified area. -* +* Applies the filter to the specified area * @method applyFilterPass * @param filter {AbstractFilter} the filter that needs to be applied -* @param filterArea {Texture} TODO - might need an update +* @param filterArea {texture} TODO - might need an update * @param width {Number} the horizontal range of the filter * @param height {Number} the vertical range of the filter */ @@ -10173,9 +7521,7 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, } // set the shader - this.renderSession.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); + gl.useProgram(shader.program); gl.uniform2f(shader.projectionVector, width/2, -height/2); gl.uniform2f(shader.offsetVector, 0,0); @@ -10208,8 +7554,7 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, }; /** -* Initialises the shader buffers. -* +* Initialises the shader buffers * @method initShaderBuffers */ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() @@ -10222,42 +7567,54 @@ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() this.colorBuffer = gl.createBuffer(); this.indexBuffer = gl.createBuffer(); + // bind and upload the vertexs.. // keep a reference to the vertexFloatData.. - this.vertexArray = new PIXI.Float32Array([0.0, 0.0, + this.vertexArray = new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); + gl.bufferData( + gl.ARRAY_BUFFER, + this.vertexArray, + gl.STATIC_DRAW); + // bind and upload the uv buffer - this.uvArray = new PIXI.Float32Array([0.0, 0.0, + this.uvArray = new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0]); gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); + gl.bufferData( + gl.ARRAY_BUFFER, + this.uvArray, + gl.STATIC_DRAW); - this.colorArray = new PIXI.Float32Array([1.0, 0xFFFFFF, + this.colorArray = new Float32Array([1.0, 0xFFFFFF, 1.0, 0xFFFFFF, 1.0, 0xFFFFFF, 1.0, 0xFFFFFF]); gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); + gl.bufferData( + gl.ARRAY_BUFFER, + this.colorArray, + gl.STATIC_DRAW); // bind and upload the index gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array([0, 1, 2, 1, 3, 2]), + gl.STATIC_DRAW); }; /** -* Destroys the filter and removes it from the filter stack. -* +* Destroys the filter and removes it from the filter stack * @method destroy */ PIXI.WebGLFilterManager.prototype.destroy = function() @@ -10271,7 +7628,7 @@ PIXI.WebGLFilterManager.prototype.destroy = function() // destroy textures for (var i = 0; i < this.texturePool.length; i++) { - this.texturePool[i].destroy(); + this.texturePool.destroy(); } this.texturePool = null; @@ -10281,8 +7638,7 @@ PIXI.WebGLFilterManager.prototype.destroy = function() gl.deleteBuffer(this.uvBuffer); gl.deleteBuffer(this.colorBuffer); gl.deleteBuffer(this.indexBuffer); -}; - +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -10293,9 +7649,9 @@ PIXI.WebGLFilterManager.prototype.destroy = function() * @param gl {WebGLContext} the current WebGL drawing context * @param width {Number} the horizontal range of the filter * @param height {Number} the vertical range of the filter -* @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values +* @private */ -PIXI.FilterTexture = function(gl, width, height, scaleMode) +PIXI.FilterTexture = function(gl, width, height) { /** * @property gl @@ -10304,48 +7660,25 @@ PIXI.FilterTexture = function(gl, width, height, scaleMode) this.gl = gl; // next time to create a frame buffer and texture - - /** - * @property frameBuffer - * @type Any - */ this.frameBuffer = gl.createFramebuffer(); - - /** - * @property texture - * @type Any - */ this.texture = gl.createTexture(); - /** - * @property scaleMode - * @type Number - */ - scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); - // required for masking a mask?? - this.renderBuffer = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer); - this.resize(width, height); }; -PIXI.FilterTexture.prototype.constructor = PIXI.FilterTexture; /** -* Clears the filter texture. -* +* Clears the filter texture * @method clear */ PIXI.FilterTexture.prototype.clear = function() @@ -10373,15 +7706,12 @@ PIXI.FilterTexture.prototype.resize = function(width, height) var gl = this.gl; gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width , height , 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - // update the stencil buffer width and height - gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width , height ); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + }; /** -* Destroys the filter texture. -* +* Destroys the filter texture * @method destroy */ PIXI.FilterTexture.prototype.destroy = function() @@ -10393,124 +7723,37 @@ PIXI.FilterTexture.prototype.destroy = function() this.frameBuffer = null; this.texture = null; }; - + /** - * @author Mat Groves http://matgroves.com/ @Doormat23 + * @author Mat Groves + * + * */ - /** - * Creates a Canvas element of the given size. - * - * @class CanvasBuffer - * @constructor - * @param width {Number} the width for the newly created canvas - * @param height {Number} the height for the newly created canvas - */ -PIXI.CanvasBuffer = function(width, height) -{ - /** - * The width of the Canvas in pixels. - * - * @property width - * @type Number - */ - this.width = width; - - /** - * The height of the Canvas in pixels. - * - * @property height - * @type Number - */ - this.height = height; - - /** - * The Canvas object that belongs to this CanvasBuffer. - * - * @property canvas - * @type HTMLCanvasElement - */ - this.canvas = document.createElement("canvas"); - - /** - * A CanvasRenderingContext2D object representing a two-dimensional rendering context. - * - * @property context - * @type CanvasRenderingContext2D - */ - this.context = this.canvas.getContext("2d"); - - this.canvas.width = width; - this.canvas.height = height; -}; - -PIXI.CanvasBuffer.prototype.constructor = PIXI.CanvasBuffer; - -/** - * Clears the canvas that was created by the CanvasBuffer class. - * - * @method clear - * @private - */ -PIXI.CanvasBuffer.prototype.clear = function() -{ - this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.clearRect(0,0, this.width, this.height); -}; - -/** - * Resizes the canvas to the specified width and height. - * - * @method resize - * @param width {Number} the new width of the canvas - * @param height {Number} the new height of the canvas - */ -PIXI.CanvasBuffer.prototype.resize = function(width, height) -{ - this.width = this.canvas.width = width; - this.height = this.canvas.height = height; -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A set of functions used to handle masking. + * A set of functions used to handle masking * * @class CanvasMaskManager - * @constructor */ PIXI.CanvasMaskManager = function() { + }; -PIXI.CanvasMaskManager.prototype.constructor = PIXI.CanvasMaskManager; - /** - * This method adds it to the current stack of masks. + * This method adds it to the current stack of masks * * @method pushMask - * @param maskData {Object} the maskData that will be pushed - * @param renderSession {Object} The renderSession whose context will be used for this mask manager. + * @param maskData the maskData that will be pushed + * @param context {Context2D} the 2d drawing method of the canvas */ -PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, renderSession) +PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, context) { - var context = renderSession.context; - context.save(); var cacheAlpha = maskData.alpha; var transform = maskData.worldTransform; - var resolution = renderSession.resolution; - - context.setTransform(transform.a * resolution, - transform.b * resolution, - transform.c * resolution, - transform.d * resolution, - transform.tx * resolution, - transform.ty * resolution); + context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); PIXI.CanvasGraphics.renderGraphicsMask(maskData, context); @@ -10520,41 +7763,46 @@ PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, renderSession) }; /** - * Restores the current drawing context to the state it was before the mask was applied. + * Restores the current drawing context to the state it was before the mask was applied * * @method popMask - * @param renderSession {Object} The renderSession whose context will be used for this mask manager. + * @param context {Context2D} the 2d drawing method of the canvas */ -PIXI.CanvasMaskManager.prototype.popMask = function(renderSession) +PIXI.CanvasMaskManager.prototype.popMask = function(context) { - renderSession.context.restore(); -}; + context.restore(); +}; /** - * @author Mat Groves http://matgroves.com/ @Doormat23 + * @author Mat Groves + * + * */ /** - * Utility methods for Sprite/Texture tinting. - * * @class CanvasTinter + * @constructor * @static */ PIXI.CanvasTinter = function() { + /// this.textureCach }; +//PIXI.CanvasTinter.cachTint = true; + + /** - * Basically this method just needs a sprite and a color and tints the sprite with the given color. + * Basically this method just needs a sprite and a color and tints the sprite + * with the given color * * @method getTintedTexture - * @static * @param sprite {Sprite} the sprite to tint * @param color {Number} the color to use to tint the sprite with - * @return {HTMLCanvasElement} The tinted canvas */ PIXI.CanvasTinter.getTintedTexture = function(sprite, color) { + var texture = sprite.texture; color = PIXI.CanvasTinter.roundColor(color); @@ -10569,6 +7817,8 @@ PIXI.CanvasTinter.getTintedTexture = function(sprite, color) var canvas = PIXI.CanvasTinter.canvas || document.createElement("canvas"); //PIXI.CanvasTinter.tintWithPerPixel(texture, stringColor, canvas); + + PIXI.CanvasTinter.tintMethod(texture, color, canvas); if(PIXI.CanvasTinter.convertTintToImage) @@ -10581,20 +7831,20 @@ PIXI.CanvasTinter.getTintedTexture = function(sprite, color) } else { + texture.tintCache[stringColor] = canvas; // if we are not converting the texture to an image then we need to lose the reference to the canvas PIXI.CanvasTinter.canvas = null; + } return canvas; }; /** - * Tint a texture using the "multiply" operation. - * + * Tint a texture using the "multiply" operation * @method tintWithMultiply - * @static - * @param texture {Texture} the texture to tint + * @param texture {texture} the texture to tint * @param color {Number} the color to use to tint the sprite with * @param canvas {HTMLCanvasElement} the current canvas */ @@ -10602,46 +7852,44 @@ PIXI.CanvasTinter.tintWithMultiply = function(texture, color, canvas) { var context = canvas.getContext( "2d" ); - var crop = texture.crop; + var frame = texture.frame; - canvas.width = crop.width; - canvas.height = crop.height; + canvas.width = frame.width; + canvas.height = frame.height; context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - context.fillRect(0, 0, crop.width, crop.height); + context.fillRect(0, 0, frame.width, frame.height); context.globalCompositeOperation = "multiply"; context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, + frame.x, + frame.y, + frame.width, + frame.height, 0, 0, - crop.width, - crop.height); + frame.width, + frame.height); context.globalCompositeOperation = "destination-atop"; - + context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, + frame.x, + frame.y, + frame.width, + frame.height, 0, 0, - crop.width, - crop.height); + frame.width, + frame.height); }; /** - * Tint a texture using the "overlay" operation. - * + * Tint a texture using the "overlay" operation * @method tintWithOverlay - * @static - * @param texture {Texture} the texture to tint + * @param texture {texture} the texture to tint * @param color {Number} the color to use to tint the sprite with * @param canvas {HTMLCanvasElement} the current canvas */ @@ -10649,35 +7897,37 @@ PIXI.CanvasTinter.tintWithOverlay = function(texture, color, canvas) { var context = canvas.getContext( "2d" ); - var crop = texture.crop; + var frame = texture.frame; - canvas.width = crop.width; - canvas.height = crop.height; + canvas.width = frame.width; + canvas.height = frame.height; + + context.globalCompositeOperation = "copy"; context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - context.fillRect(0, 0, crop.width, crop.height); + context.fillRect(0, 0, frame.width, frame.height); context.globalCompositeOperation = "destination-atop"; context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, + frame.x, + frame.y, + frame.width, + frame.height, 0, 0, - crop.width, - crop.height); + frame.width, + frame.height); + //context.globalCompositeOperation = "copy"; + }; /** - * Tint a texture pixel per pixel. - * + * Tint a texture pixel per pixel * @method tintPerPixel - * @static - * @param texture {Texture} the texture to tint + * @param texture {texture} the texture to tint * @param color {Number} the color to use to tint the sprite with * @param canvas {HTMLCanvasElement} the current canvas */ @@ -10685,26 +7935,26 @@ PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas) { var context = canvas.getContext( "2d" ); - var crop = texture.crop; + var frame = texture.frame; - canvas.width = crop.width; - canvas.height = crop.height; + canvas.width = frame.width; + canvas.height = frame.height; context.globalCompositeOperation = "copy"; context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, + frame.x, + frame.y, + frame.width, + frame.height, 0, 0, - crop.width, - crop.height); + frame.width, + frame.height); var rgbValues = PIXI.hex2rgb(color); var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2]; - var pixelData = context.getImageData(0, 0, crop.width, crop.height); + var pixelData = context.getImageData(0, 0, frame.width, frame.height); var pixels = pixelData.data; @@ -10719,10 +7969,8 @@ PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas) }; /** - * Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel. - * + * Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel * @method roundColor - * @static * @param color {number} the color to round, should be a hex color */ PIXI.CanvasTinter.roundColor = function(color) @@ -10739,95 +7987,54 @@ PIXI.CanvasTinter.roundColor = function(color) }; /** - * Number of steps which will be used as a cap when rounding colors. + * + * Number of steps which will be used as a cap when rounding colors * - * @property cacheStepsPerColorChannel + * @property cacheStepsPerColorChannel * @type Number - * @static */ PIXI.CanvasTinter.cacheStepsPerColorChannel = 8; - /** - * Tint cache boolean flag. + * + * Number of steps which will be used as a cap when rounding colors * * @property convertTintToImage * @type Boolean - * @static */ PIXI.CanvasTinter.convertTintToImage = false; /** - * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method. + * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method * * @property canUseMultiply * @type Boolean - * @static */ PIXI.CanvasTinter.canUseMultiply = PIXI.canUseNewCanvasBlendModes(); -/** - * The tinting method that will be used. - * - * @method tintMethod - * @static - */ PIXI.CanvasTinter.tintMethod = PIXI.CanvasTinter.canUseMultiply ? PIXI.CanvasTinter.tintWithMultiply : PIXI.CanvasTinter.tintWithPerPixel; + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * The CanvasRenderer draws the Stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. - * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :) + * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. + * Dont forget to add the view to your DOM or you will not see anything :) * * @class CanvasRenderer * @constructor - * @param [width=800] {Number} the width of the canvas view - * @param [height=600] {Number} the height of the canvas view - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.autoResize=false] {Boolean} If the render view is automatically resized, default false - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * @param [options.clearBeforeRender=true] {Boolean} This sets if the CanvasRenderer will clear the canvas or not before the new render pass. + * @param width=800 {Number} the width of the canvas view + * @param height=600 {Number} the height of the canvas view + * @param [view] {HTMLCanvasElement} the canvas to use as a view, optional + * @param [transparent=false] {Boolean} the transparency of the render view, default false */ -PIXI.CanvasRenderer = function(width, height, options) +PIXI.CanvasRenderer = function(width, height, view, transparent) { - if(options) - { - for (var i in PIXI.defaultRenderOptions) - { - if (typeof options[i] === "undefined") options[i] = PIXI.defaultRenderOptions[i]; - } - } - else - { - options = PIXI.defaultRenderOptions; - } + PIXI.defaultRenderer = PIXI.defaultRenderer || this; - if(!PIXI.defaultRenderer) - { - PIXI.sayHello("Canvas"); - PIXI.defaultRenderer = this; - } - - /** - * The renderer type. - * - * @property type - * @type Number - */ this.type = PIXI.CANVAS_RENDERER; - /** - * The resolution of the canvas. - * - * @property resolution - * @type Number - */ - this.resolution = options.resolution; - /** * This sets if the CanvasRenderer will clear the canvas or not before the new render pass. * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color. @@ -10838,7 +8045,17 @@ PIXI.CanvasRenderer = function(width, height, options) * @type Boolean * @default */ - this.clearBeforeRender = options.clearBeforeRender; + this.clearBeforeRender = true; + + /** + * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. + * Handy for crisp pixel art and speed on legacy devices. + * + * @property roundPixels + * @type Boolean + * @default + */ + this.roundPixels = false; /** * Whether the render view is transparent @@ -10846,235 +8063,12 @@ PIXI.CanvasRenderer = function(width, height, options) * @property transparent * @type Boolean */ - this.transparent = options.transparent; + this.transparent = !!transparent; - /** - * Whether the render view should be resized automatically - * - * @property autoResize - * @type Boolean - */ - this.autoResize = options.autoResize || false; - - - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; - - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; - - this.width *= this.resolution; - this.height *= this.resolution; - - /** - * The canvas element that everything is drawn to. - * - * @property view - * @type HTMLCanvasElement - */ - this.view = options.view || document.createElement( "canvas" ); - - /** - * The canvas 2d context that everything is drawn with - * @property context - * @type CanvasRenderingContext2D - */ - this.context = this.view.getContext( "2d", { alpha: this.transparent } ); - - /** - * Boolean flag controlling canvas refresh. - * - * @property refresh - * @type Boolean - */ - this.refresh = true; - - this.view.width = this.width * this.resolution; - this.view.height = this.height * this.resolution; - - /** - * Internal var. - * - * @property count - * @type Number - */ - this.count = 0; - - /** - * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer - * @property CanvasMaskManager - * @type CanvasMaskManager - */ - this.maskManager = new PIXI.CanvasMaskManager(); - - /** - * The render session is just a bunch of parameter used for rendering - * @property renderSession - * @type Object - */ - this.renderSession = { - context: this.context, - maskManager: this.maskManager, - scaleMode: null, - smoothProperty: null, - /** - * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. - * Handy for crisp pixel art and speed on legacy devices. - * - */ - roundPixels: false - }; - - this.mapBlendModes(); - - this.resize(width, height); - - if("imageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "imageSmoothingEnabled"; - else if("webkitImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "webkitImageSmoothingEnabled"; - else if("mozImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "mozImageSmoothingEnabled"; - else if("oImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "oImageSmoothingEnabled"; - else if ("msImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "msImageSmoothingEnabled"; -}; - -// constructor -PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; - -/** - * Renders the Stage to this canvas view - * - * @method render - * @param stage {Stage} the Stage element to be rendered - */ -PIXI.CanvasRenderer.prototype.render = function(stage) -{ - stage.updateTransform(); - - this.context.setTransform(1,0,0,1,0,0); - - this.context.globalAlpha = 1; - - this.renderSession.currentBlendMode = PIXI.blendModes.NORMAL; - this.context.globalCompositeOperation = PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]; - - if (navigator.isCocoonJS && this.view.screencanvas) { - this.context.fillStyle = "black"; - this.context.clear(); - } - - if (this.clearBeforeRender) - { - if (this.transparent) - { - this.context.clearRect(0, 0, this.width, this.height); - } - else - { - this.context.fillStyle = stage.backgroundColorString; - this.context.fillRect(0, 0, this.width , this.height); - } - } - - this.renderDisplayObject(stage); - - // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } -}; - -/** - * Removes everything from the renderer and optionally removes the Canvas DOM element. - * - * @method destroy - * @param [removeView=true] {boolean} Removes the Canvas element from the DOM. - */ -PIXI.CanvasRenderer.prototype.destroy = function(removeView) -{ - if (typeof removeView === "undefined") { removeView = true; } - - if (removeView && this.view.parent) - { - this.view.parent.removeChild(this.view); - } - - this.view = null; - this.context = null; - this.maskManager = null; - this.renderSession = null; - -}; - -/** - * Resizes the canvas view to the specified width and height - * - * @method resize - * @param width {Number} the new width of the canvas view - * @param height {Number} the new height of the canvas view - */ -PIXI.CanvasRenderer.prototype.resize = function(width, height) -{ - this.width = width * this.resolution; - this.height = height * this.resolution; - - this.view.width = this.width; - this.view.height = this.height; - - if (this.autoResize) { - this.view.style.width = this.width / this.resolution + "px"; - this.view.style.height = this.height / this.resolution + "px"; - } -}; - -/** - * Renders a display object - * - * @method renderDisplayObject - * @param displayObject {DisplayObject} The displayObject to render - * @param context {CanvasRenderingContext2D} the context 2d method of the canvas - * @private - */ -PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context) -{ - this.renderSession.context = context || this.context; - this.renderSession.resolution = this.resolution; - displayObject._renderCanvas(this.renderSession); -}; - -/** - * Maps Pixi blend modes to canvas blend modes. - * - * @method mapBlendModes - * @private - */ -PIXI.CanvasRenderer.prototype.mapBlendModes = function() -{ if(!PIXI.blendModesCanvas) { PIXI.blendModesCanvas = []; - + if(PIXI.canUseNewCanvasBlendModes()) { PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; @@ -11117,49 +8111,335 @@ PIXI.CanvasRenderer.prototype.mapBlendModes = function() PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over"; } } + + /** + * The width of the canvas view + * + * @property width + * @type Number + * @default 800 + */ + this.width = width || 800; + + /** + * The height of the canvas view + * + * @property height + * @type Number + * @default 600 + */ + this.height = height || 600; + + /** + * The canvas element that everything is drawn to + * + * @property view + * @type HTMLCanvasElement + */ + this.view = view || document.createElement( "canvas" ); + + /** + * The canvas 2d context that everything is drawn with + * @property context + * @type HTMLCanvasElement 2d Context + */ + this.context = this.view.getContext( "2d", { alpha: this.transparent } ); + + this.refresh = true; + // hack to enable some hardware acceleration! + //this.view.style["transform"] = "translatez(0)"; + + this.view.width = this.width; + this.view.height = this.height; + this.count = 0; + + /** + * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer + * @property CanvasMaskManager + * @type CanvasMaskManager + */ + this.maskManager = new PIXI.CanvasMaskManager(); + + /** + * The render session is just a bunch of parameter used for rendering + * @property renderSession + * @type Object + */ + this.renderSession = { + context: this.context, + maskManager: this.maskManager, + scaleMode: null, + smoothProperty: null + }; + + if("imageSmoothingEnabled" in this.context) + this.renderSession.smoothProperty = "imageSmoothingEnabled"; + else if("webkitImageSmoothingEnabled" in this.context) + this.renderSession.smoothProperty = "webkitImageSmoothingEnabled"; + else if("mozImageSmoothingEnabled" in this.context) + this.renderSession.smoothProperty = "mozImageSmoothingEnabled"; + else if("oImageSmoothingEnabled" in this.context) + this.renderSession.smoothProperty = "oImageSmoothingEnabled"; }; +// constructor +PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; + +/** + * Renders the stage to its canvas view + * + * @method render + * @param stage {Stage} the Stage element to be rendered + */ +PIXI.CanvasRenderer.prototype.render = function(stage) +{ + // update textures if need be + PIXI.texturesToUpdate.length = 0; + PIXI.texturesToDestroy.length = 0; + + stage.updateTransform(); + + this.context.setTransform(1,0,0,1,0,0); + this.context.globalAlpha = 1; + + if (!this.transparent && this.clearBeforeRender) + { + this.context.fillStyle = stage.backgroundColorString; + this.context.fillRect(0, 0, this.width, this.height); + } + else if (this.transparent && this.clearBeforeRender) + { + this.context.clearRect(0, 0, this.width, this.height); + } + + this.renderDisplayObject(stage); + + // run interaction! + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } + + // remove frame updates.. + if(PIXI.Texture.frameUpdates.length > 0) + { + PIXI.Texture.frameUpdates.length = 0; + } +}; + +/** + * Resizes the canvas view to the specified width and height + * + * @method resize + * @param width {Number} the new width of the canvas view + * @param height {Number} the new height of the canvas view + */ +PIXI.CanvasRenderer.prototype.resize = function(width, height) +{ + this.width = width; + this.height = height; + + this.view.width = width; + this.view.height = height; +}; + +/** + * Renders a display object + * + * @method renderDisplayObject + * @param displayObject {DisplayObject} The displayObject to render + * @param context {Context2D} the context 2d method of the canvas + * @private + */ +PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context) +{ + // no longer recursive! + //var transform; + //var context = this.context; + + this.renderSession.context = context || this.context; + displayObject._renderCanvas(this.renderSession); +}; + +/** + * Renders a flat strip + * + * @method renderStripFlat + * @param strip {Strip} The Strip to render + * @private + */ +PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) +{ + var context = this.context; + var verticies = strip.verticies; + + var length = verticies.length/2; + this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = "#FF0000"; + context.fill(); + context.closePath(); +}; + +/** + * Renders a strip + * + * @method renderStrip + * @param strip {Strip} The Strip to render + * @private + */ +PIXI.CanvasRenderer.prototype.renderStrip = function(strip) +{ + var context = this.context; + + // draw triangles!! + var verticies = strip.verticies; + var uvs = strip.uvs; + + var length = verticies.length/2; + this.count++; + + for (var i = 1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; + var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + + context.save(); + context.beginPath(); + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + context.closePath(); + + context.clip(); + + // Compute matrix transform + var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; + var deltaA = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; + var deltaB = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; + var deltaC = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; + var deltaD = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; + var deltaE = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; + var deltaF = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(strip.texture.baseTexture.source, 0, 0); + context.restore(); + } +}; + +/** + * Creates a Canvas element of the given size + * + * @method CanvasBuffer + * @param width {Number} the width for the newly created canvas + * @param height {Number} the height for the newly created canvas + * @static + * @private + */ +PIXI.CanvasBuffer = function(width, height) +{ + this.width = width; + this.height = height; + + this.canvas = document.createElement( "canvas" ); + this.context = this.canvas.getContext( "2d" ); + + this.canvas.width = width; + this.canvas.height = height; +}; + +/** + * Clears the canvas that was created by the CanvasBuffer class + * + * @method clear + * @private + */ +PIXI.CanvasBuffer.prototype.clear = function() +{ + this.context.clearRect(0,0, this.width, this.height); +}; + +/** + * Resizes the canvas that was created by the CanvasBuffer class to the specified width and height + * + * @method resize + * @param width {Number} the new width of the canvas + * @param height {Number} the new height of the canvas + * @private + */ + +PIXI.CanvasBuffer.prototype.resize = function(width, height) +{ + this.width = this.canvas.width = width; + this.height = this.canvas.height = height; +}; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * A set of functions used by the canvas renderer to draw the primitive graphics data. + * A set of functions used by the canvas renderer to draw the primitive graphics data * * @class CanvasGraphics - * @static */ PIXI.CanvasGraphics = function() { + }; + /* - * Renders a PIXI.Graphics object to a canvas. + * Renders the graphics object * - * @method renderGraphics * @static + * @private + * @method renderGraphics * @param graphics {Graphics} the actual graphics object to render - * @param context {CanvasRenderingContext2D} the 2d drawing method of the canvas + * @param context {Context2D} the 2d drawing method of the canvas */ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) { var worldAlpha = graphics.worldAlpha; - - if(graphics.dirty) - { - this.updateGraphicsTint(graphics); - graphics.dirty = false; - } - + var color = ''; for (var i = 0; i < graphics.graphicsData.length; i++) { var data = graphics.graphicsData[i]; - var shape = data.shape; + var points = data.points; - var fillColor = data._fillTint; - var lineColor = data._lineTint; + context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); context.lineWidth = data.lineWidth; @@ -11167,8 +8447,6 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) { context.beginPath(); - var points = shape.points; - context.moveTo(points[0], points[1]); for (var j=1; j < points.length/2; j++) @@ -11176,11 +8454,6 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) context.lineTo(points[j * 2], points[j * 2 + 1]); } - if(shape.closed) - { - context.lineTo(points[0], points[1]); - } - // if the first and last point are the same close the path - much neater :) if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) { @@ -11190,13 +8463,12 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); context.fill(); } if(data.lineWidth) { context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); context.stroke(); } } @@ -11206,46 +8478,48 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) if(data.fillColor || data.fillColor === 0) { context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fillRect(shape.x, shape.y, shape.width, shape.height); + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fillRect(points[0], points[1], points[2], points[3]); } if(data.lineWidth) { context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.strokeRect(shape.x, shape.y, shape.width, shape.height); + context.strokeRect(points[0], points[1], points[2], points[3]); } + } else if(data.type === PIXI.Graphics.CIRC) { // TODO - need to be Undefined! context.beginPath(); - context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI); + context.arc(points[0], points[1], points[2],0,2*Math.PI); context.closePath(); if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); context.fill(); } if(data.lineWidth) { context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); context.stroke(); } } else if(data.type === PIXI.Graphics.ELIP) { + // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var w = shape.width * 2; - var h = shape.height * 2; + var ellipseData = data.points; - var x = shape.x - w/2; - var y = shape.y - h/2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; + + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; context.beginPath(); @@ -11268,50 +8542,12 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) if(data.fill) { context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); context.fill(); } if(data.lineWidth) { context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.stroke(); - } - } - else if (data.type === PIXI.Graphics.RREC) - { - var rx = shape.x; - var ry = shape.y; - var width = shape.width; - var height = shape.height; - var radius = shape.radius; - - var maxRadius = Math.min(width, height) / 2 | 0; - radius = radius > maxRadius ? maxRadius : radius; - - context.beginPath(); - context.moveTo(rx, ry + radius); - context.lineTo(rx, ry + height - radius); - context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height); - context.lineTo(rx + width - radius, ry + height); - context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); - context.lineTo(rx + width, ry + radius); - context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); - context.lineTo(rx + radius, ry); - context.quadraticCurveTo(rx, ry, rx, ry + radius); - context.closePath(); - - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fill(); - - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); context.stroke(); } } @@ -11325,7 +8561,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) * @private * @method renderGraphicsMask * @param graphics {Graphics} the graphics which will be used as a mask - * @param context {CanvasRenderingContext2D} the context 2d method of the canvas + * @param context {Context2D} the context 2d method of the canvas */ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) { @@ -11342,14 +8578,11 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) for (var i = 0; i < 1; i++) { var data = graphics.graphicsData[i]; - var shape = data.shape; + var points = data.points; if(data.type === PIXI.Graphics.POLY) { context.beginPath(); - - var points = shape.points; - context.moveTo(points[0], points[1]); for (var j=1; j < points.length/2; j++) @@ -11367,26 +8600,27 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) else if(data.type === PIXI.Graphics.RECT) { context.beginPath(); - context.rect(shape.x, shape.y, shape.width, shape.height); + context.rect(points[0], points[1], points[2], points[3]); context.closePath(); } else if(data.type === PIXI.Graphics.CIRC) { // TODO - need to be Undefined! context.beginPath(); - context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI); + context.arc(points[0], points[1], points[2],0,2*Math.PI); context.closePath(); } else if(data.type === PIXI.Graphics.ELIP) { // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas + var ellipseData = data.points; - var w = shape.width * 2; - var h = shape.height * 2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; - var x = shape.x - w/2; - var y = shape.y - h/2; + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; context.beginPath(); @@ -11405,86 +8639,19 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); context.closePath(); } - else if (data.type === PIXI.Graphics.RREC) - { - - var pts = shape.points; - var rx = pts[0]; - var ry = pts[1]; - var width = pts[2]; - var height = pts[3]; - var radius = pts[4]; - - var maxRadius = Math.min(width, height) / 2 | 0; - radius = radius > maxRadius ? maxRadius : radius; - - context.beginPath(); - context.moveTo(rx, ry + radius); - context.lineTo(rx, ry + height - radius); - context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height); - context.lineTo(rx + width - radius, ry + height); - context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); - context.lineTo(rx + width, ry + radius); - context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); - context.lineTo(rx + radius, ry); - context.quadraticCurveTo(rx, ry, rx, ry + radius); - context.closePath(); - } } }; - -PIXI.CanvasGraphics.updateGraphicsTint = function(graphics) -{ - if(graphics.tint === 0xFFFFFF)return; - - var tintR = (graphics.tint >> 16 & 0xFF) / 255; - var tintG = (graphics.tint >> 8 & 0xFF) / 255; - var tintB = (graphics.tint & 0xFF)/ 255; - - for (var i = 0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - var fillColor = data.fillColor | 0; - var lineColor = data.lineColor | 0; - - /* - var colorR = (fillColor >> 16 & 0xFF) / 255; - var colorG = (fillColor >> 8 & 0xFF) / 255; - var colorB = (fillColor & 0xFF) / 255; - - colorR *= tintR; - colorG *= tintG; - colorB *= tintB; - - fillColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255); - - colorR = (lineColor >> 16 & 0xFF) / 255; - colorG = (lineColor >> 8 & 0xFF) / 255; - colorB = (lineColor & 0xFF) / 255; - - colorR *= tintR; - colorG *= tintG; - colorB *= tintB; - - lineColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255); - */ - - // super inline cos im an optimization NAZI :) - data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG*255 << 8) + (fillColor & 0xFF) / 255 * tintB*255); - data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG*255 << 8) + (lineColor & 0xFF) / 255 * tintB*255); - - } -}; - - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ + /** - * The Graphics class contains methods used to draw primitive shapes such as lines, circles and rectangles to the display, and color and fill them. - * + * The Graphics class contains a set of methods that you can use to create primitive shapes and lines. + * It is important to know that with the webGL renderer only simple polygons can be filled at this stage + * Complex polygons will not be filled. Heres an example of a complex polygon: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png + * * @class Graphics * @extends DisplayObjectContainer * @constructor @@ -11496,7 +8663,7 @@ PIXI.Graphics = function() this.renderable = true; /** - * The alpha value used when filling the Graphics object. + * The alpha of the fill of this graphics object * * @property fillAlpha * @type Number @@ -11504,7 +8671,7 @@ PIXI.Graphics = function() this.fillAlpha = 1; /** - * The width (thickness) of any lines drawn. + * The width of any lines drawn * * @property lineWidth * @type Number @@ -11512,13 +8679,12 @@ PIXI.Graphics = function() this.lineWidth = 0; /** - * The color of any lines drawn. + * The color of any lines drawn * * @property lineColor * @type String - * @default 0 */ - this.lineColor = 0; + this.lineColor = "black"; /** * Graphics data @@ -11529,17 +8695,18 @@ PIXI.Graphics = function() */ this.graphicsData = []; + /** - * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint. + * The tint applied to the graphic shape. This is a hex value * * @property tint * @type Number * @default 0xFFFFFF */ - this.tint = 0xFFFFFF; - + this.tint = 0xFFFFFF;// * Math.random(); + /** - * The blend mode to be applied to the graphic shape. Apply a value of PIXI.blendModes.NORMAL to reset the blend mode. + * The blend mode to be applied to the graphic shape * * @property blendMode * @type Number @@ -11554,10 +8721,10 @@ PIXI.Graphics = function() * @type Object * @private */ - this.currentPath = null; - + this.currentPath = {points:[]}; + /** - * Array containing some WebGL-related properties used by the WebGL renderer. + * Array containing some WebGL-related properties used by the WebGL renderer * * @property _webGL * @type Array @@ -11566,50 +8733,28 @@ PIXI.Graphics = function() this._webGL = []; /** - * Whether this shape is being used as a mask. + * Whether this shape is being used as a mask * * @property isMask - * @type Boolean + * @type isMask */ this.isMask = false; /** - * The bounds' padding used for bounds calculation. + * The bounds of the graphic shape as rectangle object * - * @property boundsPadding + * @property bounds + * @type Rectangle + */ + this.bounds = null; + + /** + * the bounds' padding used for bounds calculation + * + * @property bounds * @type Number */ - this.boundsPadding = 0; - - this._localBounds = new PIXI.Rectangle(0,0,1,1); - - /** - * Used to detect if the graphics object has changed. If this is set to true then the graphics object will be recalculated. - * - * @property dirty - * @type Boolean - * @private - */ - this.dirty = true; - - /** - * Used to detect if the webgl graphics object has changed. If this is set to true then the graphics object will be recalculated. - * - * @property webGLDirty - * @type Boolean - * @private - */ - this.webGLDirty = false; - - /** - * Used to detect if the cached sprite object needs to be updated. - * - * @property cachedSpriteDirty - * @type Boolean - * @private - */ - this.cachedSpriteDirty = false; - + this.boundsPadding = 10; }; // constructor @@ -11617,14 +8762,14 @@ PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ) PIXI.Graphics.prototype.constructor = PIXI.Graphics; /** - * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite. - * This is useful if your graphics element does not change often, as it will speed up the rendering of the object in exchange for taking up texture memory. - * It is also useful if you need the graphics object to be anti-aliased, because it will be rendered using canvas. - * This is not recommended if you are constantly redrawing the graphics element. + * If cacheAsBitmap is true the graphics object will then be rendered as if it was a sprite. + * This is useful if your graphics element does not change often as it will speed up the rendering of the object + * It is also usful as the graphics object will always be antialiased because it will be rendered using canvas + * Not recommended if you are constanly redrawing the graphics element. * * @property cacheAsBitmap - * @type Boolean * @default false + * @type Boolean * @private */ Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", { @@ -11636,7 +8781,6 @@ Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", { if(this._cacheAsBitmap) { - this._generateCachedSprite(); } else @@ -11648,326 +8792,63 @@ Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", { } }); + /** * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method. * * @method lineStyle - * @param lineWidth {Number} width of the line to draw, will update the objects stored style - * @param color {Number} color of the line to draw, will update the objects stored style - * @param alpha {Number} alpha of the line to draw, will update the objects stored style - * @return {Graphics} + * @param lineWidth {Number} width of the line to draw, will update the object's stored style + * @param color {Number} color of the line to draw, will update the object's stored style + * @param alpha {Number} alpha of the line to draw, will update the object's stored style */ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) { + if (!this.currentPath.points.length) this.graphicsData.pop(); + this.lineWidth = lineWidth || 0; this.lineColor = color || 0; this.lineAlpha = (arguments.length < 3) ? 1 : alpha; - if(this.currentPath) - { - if(this.currentPath.shape.points.length) - { - // halfway through a line? start a new one! - this.drawShape( new PIXI.Polygon( this.currentPath.shape.points.slice(-2) )); - return this; - } + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - // otherwise its empty so lets just set the line properties - this.currentPath.lineWidth = this.lineWidth; - this.currentPath.lineColor = this.lineColor; - this.currentPath.lineAlpha = this.lineAlpha; - - } + this.graphicsData.push(this.currentPath); return this; }; /** - * Moves the current drawing position to x, y. + * Moves the current drawing position to (x, y). * * @method moveTo * @param x {Number} the X coordinate to move to * @param y {Number} the Y coordinate to move to - * @return {Graphics} - */ + */ PIXI.Graphics.prototype.moveTo = function(x, y) { - this.drawShape(new PIXI.Polygon([x,y])); + if (!this.currentPath.points.length) this.graphicsData.pop(); + + this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; + + this.currentPath.points.push(x, y); + + this.graphicsData.push(this.currentPath); return this; }; /** * Draws a line using the current line style from the current drawing position to (x, y); - * The current drawing position is then set to (x, y). + * the current drawing position is then set to (x, y). * * @method lineTo * @param x {Number} the X coordinate to draw to * @param y {Number} the Y coordinate to draw to - * @return {Graphics} */ PIXI.Graphics.prototype.lineTo = function(x, y) { - this.currentPath.shape.points.push(x, y); - this.dirty = true; - - return this; -}; - -/** - * Calculate the points for a quadratic bezier curve and then draws it. - * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c - * - * @method quadraticCurveTo - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Graphics} - */ -PIXI.Graphics.prototype.quadraticCurveTo = function(cpX, cpY, toX, toY) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0)this.currentPath.shape.points = [0,0]; - } - else - { - this.moveTo(0,0); - } - - var xa, - ya, - n = 20, - points = this.currentPath.shape.points; - if(points.length === 0)this.moveTo(0, 0); - - - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - - var j = 0; - for (var i = 1; i <= n; i++ ) - { - j = i / n; - - xa = fromX + ( (cpX - fromX) * j ); - ya = fromY + ( (cpY - fromY) * j ); - - points.push( xa + ( ((cpX + ( (toX - cpX) * j )) - xa) * j ), - ya + ( ((cpY + ( (toY - cpY) * j )) - ya) * j ) ); - } - - - this.dirty = true; - - return this; -}; - -/** - * Calculate the points for a bezier curve and then draws it. - * - * @method bezierCurveTo - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param cpX2 {Number} Second Control point x - * @param cpY2 {Number} Second Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Graphics} - */ -PIXI.Graphics.prototype.bezierCurveTo = function(cpX, cpY, cpX2, cpY2, toX, toY) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0)this.currentPath.shape.points = [0,0]; - } - else - { - this.moveTo(0,0); - } - - var n = 20, - dt, - dt2, - dt3, - t2, - t3, - points = this.currentPath.shape.points; - - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - - var j = 0; - - for (var i=1; i<=n; i++) - { - j = i / n; - - dt = (1 - j); - dt2 = dt * dt; - dt3 = dt2 * dt; - - t2 = j * j; - t3 = t2 * j; - - points.push( dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX, - dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY); - } - - this.dirty = true; - - return this; -}; - -/* - * The arcTo() method creates an arc/curve between two tangents on the canvas. - * - * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google! - * - * @method arcTo - * @param x1 {Number} The x-coordinate of the beginning of the arc - * @param y1 {Number} The y-coordinate of the beginning of the arc - * @param x2 {Number} The x-coordinate of the end of the arc - * @param y2 {Number} The y-coordinate of the end of the arc - * @param radius {Number} The radius of the arc - * @return {Graphics} - */ -PIXI.Graphics.prototype.arcTo = function(x1, y1, x2, y2, radius) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0) - { - this.currentPath.shape.points.push(x1, y1); - } - } - else - { - this.moveTo(x1, y1); - } - - var points = this.currentPath.shape.points; - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - var a1 = fromY - y1; - var b1 = fromX - x1; - var a2 = y2 - y1; - var b2 = x2 - x1; - var mm = Math.abs(a1 * b2 - b1 * a2); - - - if (mm < 1.0e-8 || radius === 0) - { - if( points[points.length-2] !== x1 || points[points.length-1] !== y1) - { - //console.log(">>") - points.push(x1, y1); - } - } - else - { - var dd = a1 * a1 + b1 * b1; - var cc = a2 * a2 + b2 * b2; - var tt = a1 * a2 + b1 * b2; - var k1 = radius * Math.sqrt(dd) / mm; - var k2 = radius * Math.sqrt(cc) / mm; - var j1 = k1 * tt / dd; - var j2 = k2 * tt / cc; - var cx = k1 * b2 + k2 * b1; - var cy = k1 * a2 + k2 * a1; - var px = b1 * (k2 + j1); - var py = a1 * (k2 + j1); - var qx = b2 * (k1 + j2); - var qy = a2 * (k1 + j2); - var startAngle = Math.atan2(py - cy, px - cx); - var endAngle = Math.atan2(qy - cy, qx - cx); - - this.arc(cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1); - } - - this.dirty = true; - - return this; -}; - -/** - * The arc method creates an arc/curve (used to create circles, or parts of circles). - * - * @method arc - * @param cx {Number} The x-coordinate of the center of the circle - * @param cy {Number} The y-coordinate of the center of the circle - * @param radius {Number} The radius of the circle - * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle) - * @param endAngle {Number} The ending angle, in radians - * @param anticlockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise. - * @return {Graphics} - */ -PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise) -{ - var startX = cx + Math.cos(startAngle) * radius; - var startY = cy + Math.sin(startAngle) * radius; - var points; - - if( this.currentPath ) - { - points = this.currentPath.shape.points; - - if(points.length === 0) - { - points.push(startX, startY); - } - else if( points[points.length-2] !== startX || points[points.length-1] !== startY) - { - points.push(startX, startY); - } - } - else - { - this.moveTo(startX, startY); - points = this.currentPath.shape.points; - } - - if (startAngle === endAngle)return this; - - if( !anticlockwise && endAngle <= startAngle ) - { - endAngle += Math.PI * 2; - } - else if( anticlockwise && startAngle <= endAngle ) - { - startAngle += Math.PI * 2; - } - - var sweep = anticlockwise ? (startAngle - endAngle) *-1 : (endAngle - startAngle); - var segs = ( Math.abs(sweep)/ (Math.PI * 2) ) * 40; - - if( sweep === 0 ) return this; - - var theta = sweep/(segs*2); - var theta2 = theta*2; - - var cTheta = Math.cos(theta); - var sTheta = Math.sin(theta); - - var segMinus = segs - 1; - - var remainder = ( segMinus % 1 ) / segMinus; - - for(var i=0; i<=segMinus; i++) - { - var real = i + remainder * i; - - - var angle = ((theta) + startAngle + (theta2 * real)); - - var c = Math.cos(angle); - var s = -Math.sin(angle); - - points.push(( (cTheta * c) + (sTheta * s) ) * radius + cx, - ( (cTheta * -s) + (sTheta * c) ) * radius + cy); - } - + this.currentPath.points.push(x, y); this.dirty = true; return this; @@ -11980,23 +8861,14 @@ PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, ant * @method beginFill * @param color {Number} the color of the fill * @param alpha {Number} the alpha of the fill - * @return {Graphics} */ PIXI.Graphics.prototype.beginFill = function(color, alpha) { + this.filling = true; this.fillColor = color || 0; - this.fillAlpha = (alpha === undefined) ? 1 : alpha; + this.fillAlpha = (arguments.length < 2) ? 1 : alpha; - if(this.currentPath) - { - if(this.currentPath.shape.points.length <= 2) - { - this.currentPath.fill = this.filling; - this.currentPath.fillColor = this.fillColor; - this.currentPath.fillAlpha = this.fillAlpha; - } - } return this; }; @@ -12004,7 +8876,6 @@ PIXI.Graphics.prototype.beginFill = function(color, alpha) * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. * * @method endFill - * @return {Graphics} */ PIXI.Graphics.prototype.endFill = function() { @@ -12022,27 +8893,17 @@ PIXI.Graphics.prototype.endFill = function() * @param y {Number} The Y coord of the top-left of the rectangle * @param width {Number} The width of the rectangle * @param height {Number} The height of the rectangle - * @return {Graphics} */ PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) { - this.drawShape(new PIXI.Rectangle(x,y, width, height)); + if (!this.currentPath.points.length) this.graphicsData.pop(); - return this; -}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.RECT}; -/** - * @method drawRoundedRect - * - * @param x {Number} The X coord of the top-left of the rectangle - * @param y {Number} The Y coord of the top-left of the rectangle - * @param width {Number} The width of the rectangle - * @param height {Number} The height of the rectangle - * @param radius {Number} Radius of the rectangle corners - */ -PIXI.Graphics.prototype.drawRoundedRect = function( x, y, width, height, radius ) -{ - this.drawShape(new PIXI.RoundedRectangle(x, y, width, height, radius)); + this.graphicsData.push(this.currentPath); + this.dirty = true; return this; }; @@ -12054,11 +8915,18 @@ PIXI.Graphics.prototype.drawRoundedRect = function( x, y, width, height, radius * @param x {Number} The X coordinate of the center of the circle * @param y {Number} The Y coordinate of the center of the circle * @param radius {Number} The radius of the circle - * @return {Graphics} */ -PIXI.Graphics.prototype.drawCircle = function(x, y, radius) +PIXI.Graphics.prototype.drawCircle = function( x, y, radius) { - this.drawShape(new PIXI.Circle(x,y, radius)); + + if (!this.currentPath.points.length) this.graphicsData.pop(); + + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; + + this.graphicsData.push(this.currentPath); + this.dirty = true; return this; }; @@ -12067,30 +8935,23 @@ PIXI.Graphics.prototype.drawCircle = function(x, y, radius) * Draws an ellipse. * * @method drawEllipse - * @param x {Number} The X coordinate of the center of the ellipse - * @param y {Number} The Y coordinate of the center of the ellipse - * @param width {Number} The half width of the ellipse - * @param height {Number} The half height of the ellipse - * @return {Graphics} + * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse + * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse + * @param width {Number} The width of the ellipse + * @param height {Number} The height of the ellipse */ -PIXI.Graphics.prototype.drawEllipse = function(x, y, width, height) +PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height) { - this.drawShape(new PIXI.Ellipse(x, y, width, height)); - return this; -}; + if (!this.currentPath.points.length) this.graphicsData.pop(); + + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.ELIP}; + + this.graphicsData.push(this.currentPath); + this.dirty = true; -/** - * Draws a polygon using the given path. - * - * @method drawPolygon - * @param path {Array} The path data used to construct the polygon. - * @return {Graphics} - */ -PIXI.Graphics.prototype.drawPolygon = function(path) -{ - if(!(path instanceof Array))path = Array.prototype.slice.call(arguments); - this.drawShape(new PIXI.Polygon(path)); return this; }; @@ -12098,7 +8959,6 @@ PIXI.Graphics.prototype.drawPolygon = function(path) * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. * * @method clear - * @return {Graphics} */ PIXI.Graphics.prototype.clear = function() { @@ -12109,6 +8969,8 @@ PIXI.Graphics.prototype.clear = function() this.clearDirty = true; this.graphicsData = []; + this.bounds = null; //new PIXI.Rectangle(); + return this; }; @@ -12117,22 +8979,14 @@ PIXI.Graphics.prototype.clear = function() * This can be quite useful if your geometry is complicated and needs to be reused multiple times. * * @method generateTexture - * @param resolution {Number} The resolution of the texture being generated - * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts * @return {Texture} a texture of the graphics object */ -PIXI.Graphics.prototype.generateTexture = function(resolution, scaleMode) +PIXI.Graphics.prototype.generateTexture = function() { - resolution = resolution || 1; - var bounds = this.getBounds(); - - var canvasBuffer = new PIXI.CanvasBuffer(bounds.width * resolution, bounds.height * resolution); - - var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas, scaleMode); - texture.baseTexture.resolution = resolution; - canvasBuffer.context.scale(resolution, resolution); + var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height); + var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); canvasBuffer.context.translate(-bounds.x,-bounds.y); @@ -12152,23 +9006,19 @@ PIXI.Graphics.prototype._renderWebGL = function(renderSession) { // if the sprite is not visible or the alpha is 0 then no need to render this element if(this.visible === false || this.alpha === 0 || this.isMask === true)return; - + if(this._cacheAsBitmap) { - - if(this.dirty || this.cachedSpriteDirty) + + if(this.dirty) { - this._generateCachedSprite(); - // we will also need to update the texture on the gpu too! - this.updateCachedSpriteTexture(); - - this.cachedSpriteDirty = false; - this.dirty = false; + PIXI.updateWebGLTexture(this._cachedSprite.texture.baseTexture, renderSession.gl); + + this.dirty = false; } - this._cachedSprite.worldAlpha = this.worldAlpha; PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession); return; @@ -12176,9 +9026,8 @@ PIXI.Graphics.prototype._renderWebGL = function(renderSession) else { renderSession.spriteBatch.stop(); - renderSession.blendModeManager.setBlendMode(this.blendMode); - if(this._mask)renderSession.maskManager.pushMask(this._mask, renderSession); + if(this._mask)renderSession.maskManager.pushMask(this.mask, renderSession); if(this._filters)renderSession.filterManager.pushFilter(this._filterBlock); // check blend mode @@ -12188,14 +9037,7 @@ PIXI.Graphics.prototype._renderWebGL = function(renderSession) var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; renderSession.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); } - - // check if the webgl graphic needs to be updated - if(this.webGLDirty) - { - this.dirty = true; - this.webGLDirty = false; - } - + PIXI.WebGLGraphics.renderGraphics(this, renderSession); // only render if it has children! @@ -12213,7 +9055,7 @@ PIXI.Graphics.prototype._renderWebGL = function(renderSession) } if(this._filters)renderSession.filterManager.popFilter(); - if(this._mask)renderSession.maskManager.popMask(this.mask, renderSession); + if(this._mask)renderSession.maskManager.popMask(renderSession); renderSession.drawCount++; @@ -12233,60 +9075,22 @@ PIXI.Graphics.prototype._renderCanvas = function(renderSession) // if the sprite is not visible or the alpha is 0 then no need to render this element if(this.visible === false || this.alpha === 0 || this.isMask === true)return; - if(this._cacheAsBitmap) + var context = renderSession.context; + var transform = this.worldTransform; + + if(this.blendMode !== renderSession.currentBlendMode) { - if(this.dirty || this.cachedSpriteDirty) - { - this._generateCachedSprite(); - - // we will also need to update the texture - this.updateCachedSpriteTexture(); - - this.cachedSpriteDirty = false; - this.dirty = false; - } - - this._cachedSprite.alpha = this.alpha; - PIXI.Sprite.prototype._renderCanvas.call(this._cachedSprite, renderSession); - - return; + renderSession.currentBlendMode = this.blendMode; + context.globalCompositeOperation = PIXI.blendModesCanvas[renderSession.currentBlendMode]; } - else + + context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty); + PIXI.CanvasGraphics.renderGraphics(this, context); + + // simple render children! + for(var i=0, j=this.children.length; i maxX ? x1 : maxX; maxX = x2 > maxX ? x2 : maxX; maxX = x3 > maxX ? x3 : maxX; maxX = x4 > maxX ? x4 : maxX; + maxY = y1 > maxY ? y1 : maxY; maxY = y2 > maxY ? y2 : maxY; maxY = y3 > maxY ? y3 : maxY; maxY = y4 > maxY ? y4 : maxY; - this._bounds.x = minX; - this._bounds.width = maxX - minX; + var bounds = this._bounds; - this._bounds.y = minY; - this._bounds.height = maxY - minY; + bounds.x = minX; + bounds.width = maxX - minX; - return this._bounds; + bounds.y = minY; + bounds.height = maxY - minY; + + return bounds; }; /** * Update the bounds of the object * - * @method updateLocalBounds + * @method updateBounds */ -PIXI.Graphics.prototype.updateLocalBounds = function() +PIXI.Graphics.prototype.updateBounds = function() { + var minX = Infinity; var maxX = -Infinity; var minY = Infinity; var maxY = -Infinity; - if(this.graphicsData.length) - { - var shape, points, x, y, w, h; + var points, x, y, w, h; - for (var i = 0; i < this.graphicsData.length; i++) { - var data = this.graphicsData[i]; - var type = data.type; - var lineWidth = data.lineWidth; - shape = data.shape; - + for (var i = 0; i < this.graphicsData.length; i++) { + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; - if(type === PIXI.Graphics.RECT || type === PIXI.Graphics.RREC) + points = data.points; + + if(type === PIXI.Graphics.RECT) + { + x = points[0] - lineWidth/2; + y = points[1] - lineWidth/2; + w = points[2] + lineWidth; + h = points[3] + lineWidth; + + minX = x < minX ? x : minX; + maxX = x + w > maxX ? x + w : maxX; + + minY = y < minY ? x : minY; + maxY = y + h > maxY ? y + h : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points[0]; + y = points[1]; + w = points[2] + lineWidth/2; + h = points[3] + lineWidth/2; + + minX = x - w < minX ? x - w : minX; + maxX = x + w > maxX ? x + w : maxX; + + minY = y - h < minY ? y - h : minY; + maxY = y + h > maxY ? y + h : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) { - x = shape.x - lineWidth/2; - y = shape.y - lineWidth/2; - w = shape.width + lineWidth; - h = shape.height + lineWidth; - minX = x < minX ? x : minX; - maxX = x + w > maxX ? x + w : maxX; + x = points[j]; + y = points[j+1]; + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - minY = y < minY ? y : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else if(type === PIXI.Graphics.CIRC) - { - x = shape.x; - y = shape.y; - w = shape.radius + lineWidth/2; - h = shape.radius + lineWidth/2; - - minX = x - w < minX ? x - w : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y - h < minY ? y - h : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else if(type === PIXI.Graphics.ELIP) - { - x = shape.x; - y = shape.y; - w = shape.width + lineWidth/2; - h = shape.height + lineWidth/2; - - minX = x - w < minX ? x - w : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y - h < minY ? y - h : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else - { - // POLY - points = shape.points; - - for (var j = 0; j < points.length; j+=2) - { - - x = points[j]; - y = points[j+1]; - minX = x-lineWidth < minX ? x-lineWidth : minX; - maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - - minY = y-lineWidth < minY ? y-lineWidth : minY; - maxY = y+lineWidth > maxY ? y+lineWidth : maxY; - } + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; } } } - else - { - minX = 0; - maxX = 0; - minY = 0; - maxY = 0; - } var padding = this.boundsPadding; - - this._localBounds.x = minX - padding; - this._localBounds.width = (maxX - minX) + padding * 2; - - this._localBounds.y = minY - padding; - this._localBounds.height = (maxY - minY) + padding * 2; + this.bounds = new PIXI.Rectangle(minX - padding, minY - padding, (maxX - minX) + padding * 2, (maxY - minY) + padding * 2); }; + /** * Generates the cached sprite when the sprite has cacheAsBitmap = true * @@ -12500,43 +9271,10 @@ PIXI.Graphics.prototype._generateCachedSprite = function() // this._cachedSprite.buffer.context.save(); this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y); - // make sure we set the alpha of the graphics to 1 for the render.. - this.worldAlpha = 1; - - // now render the graphic.. PIXI.CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context); - this._cachedSprite.alpha = this.alpha; + // this._cachedSprite.buffer.context.restore(); }; -/** - * Updates texture size based on canvas size - * - * @method updateCachedSpriteTexture - * @private - */ -PIXI.Graphics.prototype.updateCachedSpriteTexture = function() -{ - var cachedSprite = this._cachedSprite; - var texture = cachedSprite.texture; - var canvas = cachedSprite.buffer.canvas; - - texture.baseTexture.width = canvas.width; - texture.baseTexture.height = canvas.height; - texture.crop.width = texture.frame.width = canvas.width; - texture.crop.height = texture.frame.height = canvas.height; - - cachedSprite._width = canvas.width; - cachedSprite._height = canvas.height; - - // update the dirty base textures - texture.baseTexture.dirty(); -}; - -/** - * Destroys a previous cached sprite. - * - * @method destroyCachedSprite - */ PIXI.Graphics.prototype.destroyCachedSprite = function() { this._cachedSprite.texture.destroy(true); @@ -12546,449 +9284,102 @@ PIXI.Graphics.prototype.destroyCachedSprite = function() this._cachedSprite = null; }; -/** - * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. - * - * @method drawShape - * @param {Circle|Rectangle|Ellipse|Line|Polygon} shape The Shape object to draw. - * @return {GraphicsData} The generated GraphicsData object. - */ -PIXI.Graphics.prototype.drawShape = function(shape) -{ - if(this.currentPath) - { - // check current path! - if(this.currentPath.shape.points.length <= 2)this.graphicsData.pop(); - } - - this.currentPath = null; - - var data = new PIXI.GraphicsData(this.lineWidth, this.lineColor, this.lineAlpha, this.fillColor, this.fillAlpha, this.filling, shape); - - this.graphicsData.push(data); - - if(data.type === PIXI.Graphics.POLY) - { - data.shape.closed = this.filling; - this.currentPath = data; - } - - this.dirty = true; - - return data; -}; - -/** - * A GraphicsData object. - * - * @class GraphicsData - * @constructor - */ -PIXI.GraphicsData = function(lineWidth, lineColor, lineAlpha, fillColor, fillAlpha, fill, shape) -{ - this.lineWidth = lineWidth; - this.lineColor = lineColor; - this.lineAlpha = lineAlpha; - this._lineTint = lineColor; - - this.fillColor = fillColor; - this.fillAlpha = fillAlpha; - this._fillTint = fillColor; - this.fill = fill; - - this.shape = shape; - this.type = shape.type; -}; // SOME TYPES: PIXI.Graphics.POLY = 0; PIXI.Graphics.RECT = 1; PIXI.Graphics.CIRC = 2; PIXI.Graphics.ELIP = 3; -PIXI.Graphics.RREC = 4; - -PIXI.Polygon.prototype.type = PIXI.Graphics.POLY; -PIXI.Rectangle.prototype.type = PIXI.Graphics.RECT; -PIXI.Circle.prototype.type = PIXI.Graphics.CIRC; -PIXI.Ellipse.prototype.type = PIXI.Graphics.ELIP; -PIXI.RoundedRectangle.prototype.type = PIXI.Graphics.RREC; - - + /** * @author Mat Groves http://matgroves.com/ */ /** - * + * * @class Strip * @extends DisplayObjectContainer * @constructor * @param texture {Texture} The texture to use - * @param width {Number} the width + * @param width {Number} the width * @param height {Number} the height - * + * */ -PIXI.Strip = function(texture) +PIXI.Strip = function(texture, width, height) { PIXI.DisplayObjectContainer.call( this ); - - - /** - * The texture of the strip - * - * @property texture - * @type Texture - */ this.texture = texture; - - // set up the main bits.. - this.uvs = new PIXI.Float32Array([0, 1, - 1, 1, - 1, 0, - 0, 1]); - - this.vertices = new PIXI.Float32Array([0, 0, - 100, 0, - 100, 100, - 0, 100]); - - this.colors = new PIXI.Float32Array([1, 1, 1, 1]); - - this.indices = new PIXI.Uint16Array([0, 1, 2, 3]); - - /** - * Whether the strip is dirty or not - * - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * The blend mode to be applied to the sprite. Set to PIXI.blendModes.NORMAL to remove any blend mode. - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ this.blendMode = PIXI.blendModes.NORMAL; - /** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles to overlap a bit with each other. - * - * @property canvasPadding - * @type Number - */ - this.canvasPadding = 0; + try + { + this.uvs = new Float32Array([0, 1, + 1, 1, + 1, 0, 0,1]); - this.drawMode = PIXI.Strip.DrawModes.TRIANGLE_STRIP; + this.verticies = new Float32Array([0, 0, + 0,0, + 0,0, 0, + 0, 0]); + this.colors = new Float32Array([1, 1, 1, 1]); + + this.indices = new Uint16Array([0, 1, 2, 3]); + } + catch(error) + { + this.uvs = [0, 1, + 1, 1, + 1, 0, 0,1]; + + this.verticies = [0, 0, + 0,0, + 0,0, 0, + 0, 0]; + + this.colors = [1, 1, 1, 1]; + + this.indices = [0, 1, 2, 3]; + } + + + /* + this.uvs = new Float32Array() + this.verticies = new Float32Array() + this.colors = new Float32Array() + this.indices = new Uint16Array() + */ + + this.width = width; + this.height = height; + + // load the texture! + if(texture.baseTexture.hasLoaded) + { + this.width = this.texture.frame.width; + this.height = this.texture.frame.height; + this.updateFrame = true; + } + else + { + this.onTextureUpdateBind = this.onTextureUpdate.bind(this); + this.texture.addEventListener( 'update', this.onTextureUpdateBind ); + } + + this.renderable = true; }; // constructor PIXI.Strip.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); PIXI.Strip.prototype.constructor = PIXI.Strip; -PIXI.Strip.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(!this.visible || this.alpha <= 0)return; - // render triangle strip.. - - renderSession.spriteBatch.stop(); - - // init! init! - if(!this._vertexBuffer)this._initWebGL(renderSession); - - renderSession.shaderManager.setShader(renderSession.shaderManager.stripShader); - - this._renderStrip(renderSession); - - ///renderSession.shaderManager.activateDefaultShader(); - - renderSession.spriteBatch.start(); - - //TODO check culling -}; - -PIXI.Strip.prototype._initWebGL = function(renderSession) -{ - // build the strip! - var gl = renderSession.gl; - - this._vertexBuffer = gl.createBuffer(); - this._indexBuffer = gl.createBuffer(); - this._uvBuffer = gl.createBuffer(); - this._colorBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); -}; - -PIXI.Strip.prototype._renderStrip = function(renderSession) -{ - var gl = renderSession.gl; - var projection = renderSession.projection, - offset = renderSession.offset, - shader = renderSession.shaderManager.stripShader; - - var drawMode = this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP ? gl.TRIANGLE_STRIP : gl.TRIANGLES; - - // gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mat4Real); - - renderSession.blendModeManager.setBlendMode(this.blendMode); - - - // set uniforms - gl.uniformMatrix3fv(shader.translationMatrix, false, this.worldTransform.toArray(true)); - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - gl.uniform1f(shader.alpha, this.worldAlpha); - - if(!this.dirty) - { - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { - renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - - - } - else - { - - this.dirty = false; - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { - renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - } - //console.log(gl.TRIANGLE_STRIP) - // - // - gl.drawElements(drawMode, this.indices.length, gl.UNSIGNED_SHORT, 0); - - -}; - - - -PIXI.Strip.prototype._renderCanvas = function(renderSession) -{ - var context = renderSession.context; - - var transform = this.worldTransform; - - if (renderSession.roundPixels) - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); - } - else - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); - } - - if (this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP) - { - this._renderCanvasTriangleStrip(context); - } - else - { - this._renderCanvasTriangles(context); - } -}; - -PIXI.Strip.prototype._renderCanvasTriangleStrip = function(context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - - var length = vertices.length / 2; - this.count++; - - for (var i = 0; i < length - 2; i++) { - // draw some triangles! - var index = i * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); - } -}; - -PIXI.Strip.prototype._renderCanvasTriangles = function(context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - var indices = this.indices; - - var length = indices.length; - this.count++; - - for (var i = 0; i < length; i += 3) { - // draw some triangles! - var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); - } -}; - -PIXI.Strip.prototype._renderCanvasDrawTriangle = function(context, vertices, uvs, index0, index1, index2) -{ - var textureSource = this.texture.baseTexture.source; - var textureWidth = this.texture.width; - var textureHeight = this.texture.height; - - var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; - var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; - - var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; - var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; - - if (this.canvasPadding > 0) { - var paddingX = this.canvasPadding / this.worldTransform.a; - var paddingY = this.canvasPadding / this.worldTransform.d; - var centerX = (x0 + x1 + x2) / 3; - var centerY = (y0 + y1 + y2) / 3; - - var normX = x0 - centerX; - var normY = y0 - centerY; - - var dist = Math.sqrt(normX * normX + normY * normY); - x0 = centerX + (normX / dist) * (dist + paddingX); - y0 = centerY + (normY / dist) * (dist + paddingY); - - // - - normX = x1 - centerX; - normY = y1 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x1 = centerX + (normX / dist) * (dist + paddingX); - y1 = centerY + (normY / dist) * (dist + paddingY); - - normX = x2 - centerX; - normY = y2 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x2 = centerX + (normX / dist) * (dist + paddingX); - y2 = centerY + (normY / dist) * (dist + paddingY); - } - - context.save(); - context.beginPath(); - - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - context.closePath(); - - context.clip(); - - // Compute matrix transform - var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); - var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); - var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); - var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); - var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); - var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); - var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); - - context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); - - context.drawImage(textureSource, 0, 0); - context.restore(); -}; - - - -/** - * Renders a flat strip +/* + * Sets the texture that the Strip will use * - * @method renderStripFlat - * @param strip {Strip} The Strip to render + * @method setTexture + * @param texture {Texture} the texture that will be used * @private */ -PIXI.Strip.prototype.renderStripFlat = function(strip) -{ - var context = this.context; - var vertices = strip.vertices; - - var length = vertices.length/2; - this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; - var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - } - - context.fillStyle = '#FF0000'; - context.fill(); - context.closePath(); -}; - -/* PIXI.Strip.prototype.setTexture = function(texture) { //TODO SET THE TEXTURES @@ -13000,7 +9391,6 @@ PIXI.Strip.prototype.setTexture = function(texture) this.height = texture.frame.height; this.updateFrame = true; }; -*/ /** * When the texture is updated, this event will fire to update the scale and frame @@ -13009,105 +9399,40 @@ PIXI.Strip.prototype.setTexture = function(texture) * @param event * @private */ - PIXI.Strip.prototype.onTextureUpdate = function() { this.updateFrame = true; -}; - -/** - * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. - * - * @method getBounds - * @param matrix {Matrix} the transformation matrix of the sprite - * @return {Rectangle} the framing rectangle - */ -PIXI.Strip.prototype.getBounds = function(matrix) -{ - var worldTransform = matrix || this.worldTransform; - - var a = worldTransform.a; - var b = worldTransform.b; - var c = worldTransform.c; - var d = worldTransform.d; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) - { - var rawX = vertices[i], rawY = vertices[i + 1]; - var x = (a * rawX) + (c * rawY) + tx; - var y = (d * rawY) + (b * rawX) + ty; - - minX = x < minX ? x : minX; - minY = y < minY ? y : minY; - - maxX = x > maxX ? x : maxX; - maxY = y > maxY ? y : maxY; - } - - if (minX === -Infinity || maxY === Infinity) - { - return PIXI.EmptyRectangle; - } - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** - * Different drawing buffer modes supported - * - * @property - * @type {{TRIANGLE_STRIP: number, TRIANGLES: number}} - * @static - */ -PIXI.Strip.DrawModes = { - TRIANGLE_STRIP: 0, - TRIANGLES: 1 -}; - -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * @copyright Mat Groves, Rovanion Luckey +}; +/* @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * + * * @class Rope * @constructor - * @extends Strip - * @param {Texture} texture - The texture to use on the rope. - * @param {Array} points - An array of {PIXI.Point}. - * + * @param texture {Texture} The texture to use + * @param points {Array} + * */ PIXI.Rope = function(texture, points) { PIXI.Strip.call( this, texture ); this.points = points; - this.vertices = new PIXI.Float32Array(points.length * 4); - this.uvs = new PIXI.Float32Array(points.length * 4); - this.colors = new PIXI.Float32Array(points.length * 2); - this.indices = new PIXI.Uint16Array(points.length * 2); - + try + { + this.verticies = new Float32Array(points.length * 4); + this.uvs = new Float32Array(points.length * 4); + this.colors = new Float32Array(points.length * 2); + this.indices = new Uint16Array(points.length * 2); + } + catch(error) + { + this.verticies = new Array(points.length * 4); + this.uvs = new Array(points.length * 4); + this.colors = new Array(points.length * 2); + this.indices = new Array(points.length * 2); + } this.refresh(); }; @@ -13118,7 +9443,7 @@ PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype ); PIXI.Rope.prototype.constructor = PIXI.Rope; /* - * Refreshes + * Refreshes * * @method refresh */ @@ -13135,8 +9460,9 @@ PIXI.Rope.prototype.refresh = function() this.count-=0.2; + uvs[0] = 0; - uvs[1] = 0; + uvs[1] = 1; uvs[2] = 0; uvs[3] = 1; @@ -13151,6 +9477,7 @@ PIXI.Rope.prototype.refresh = function() for (var i = 1; i < total; i++) { + point = points[i]; index = i * 4; // time to do some smart drawing! @@ -13163,6 +9490,7 @@ PIXI.Rope.prototype.refresh = function() uvs[index+2] = amount; uvs[index+3] = 1; + } else { @@ -13203,11 +9531,17 @@ PIXI.Rope.prototype.updateTransform = function() this.count-=0.2; - var vertices = this.vertices; + var verticies = this.verticies; + verticies[0] = lastPoint.x + perp.x; + verticies[1] = lastPoint.y + perp.y; //+ 200 + verticies[2] = lastPoint.x - perp.x; + verticies[3] = lastPoint.y - perp.y;//+200 + // time to do some smart drawing! + var total = points.length, point, index, ratio, perpLength, num; - for (var i = 0; i < total; i++) + for (var i = 1; i < total; i++) { point = points[i]; index = i * 4; @@ -13236,10 +9570,10 @@ PIXI.Rope.prototype.updateTransform = function() perp.x *= num; perp.y *= num; - vertices[index] = point.x + perp.x; - vertices[index+1] = point.y + perp.y; - vertices[index+2] = point.x - perp.x; - vertices[index+3] = point.y - perp.y; + verticies[index] = point.x + perp.x; + verticies[index+1] = point.y + perp.y; + verticies[index+2] = point.x - perp.x; + verticies[index+3] = point.y - perp.y; lastPoint = point; } @@ -13247,7 +9581,7 @@ PIXI.Rope.prototype.updateTransform = function() PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); }; /* - * Sets the texture that the Rope will use + * Sets the texture that the Rope will use * * @method setTexture * @param texture {Texture} the texture that will be used @@ -13256,9 +9590,9 @@ PIXI.Rope.prototype.setTexture = function(texture) { // stop current texture this.texture = texture; - //this.updateFrame = true; + this.updateFrame = true; }; - + /** * @author Mat Groves http://matgroves.com/ */ @@ -13267,7 +9601,7 @@ PIXI.Rope.prototype.setTexture = function(texture) * A tiling sprite is a fast way of rendering a tiling image * * @class TilingSprite - * @extends Sprite + * @extends DisplayObjectContainer * @constructor * @param texture {Texture} the texture of the tiling sprite * @param width {Number} the width of the tiling sprite @@ -13283,15 +9617,14 @@ PIXI.TilingSprite = function(texture, width, height) * @property width * @type Number */ - this._width = width || 100; - + this.width = width || 100; /** * The height of the tiling sprite * * @property height * @type Number */ - this._height = height || 100; + this.height = height || 100; /** * The scaling of the image that is being tiled @@ -13317,6 +9650,7 @@ PIXI.TilingSprite = function(texture, width, height) */ this.tilePosition = new PIXI.Point(0,0); + /** * Whether this sprite is renderable or not * @@ -13343,9 +9677,6 @@ PIXI.TilingSprite = function(texture, width, height) * @default PIXI.blendModes.NORMAL; */ this.blendMode = PIXI.blendModes.NORMAL; - - - }; // constructor @@ -13384,15 +9715,16 @@ Object.defineProperty(PIXI.TilingSprite.prototype, 'height', { } }); -PIXI.TilingSprite.prototype.setTexture = function(texture) +/** + * When the texture is updated, this event will be fired to update the scale and frame + * + * @method onTextureUpdate + * @param event + * @private + */ +PIXI.TilingSprite.prototype.onTextureUpdate = function() { - if (this.texture === texture) return; - - this.texture = texture; - - this.refreshTexture = true; - - this.cachedTint = 0xFFFFFF; + this.updateFrame = true; }; /** @@ -13404,52 +9736,53 @@ PIXI.TilingSprite.prototype.setTexture = function(texture) */ PIXI.TilingSprite.prototype._renderWebGL = function(renderSession) { - if (this.visible === false || this.alpha === 0) return; + + if(this.visible === false || this.alpha === 0)return; + var i,j; - if (this._mask) + if(this.mask || this.filters) { - renderSession.spriteBatch.stop(); - renderSession.maskManager.pushMask(this.mask, renderSession); - renderSession.spriteBatch.start(); - } - - if (this._filters) - { - renderSession.spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - - - - if (!this.tilingTexture || this.refreshTexture) - { - this.generateTilingTexture(true); - - if (this.tilingTexture && this.tilingTexture.needsUpdate) + if(this.mask) { - //TODO - tweaking - PIXI.updateWebGLTexture(this.tilingTexture.baseTexture, renderSession.gl); - this.tilingTexture.needsUpdate = false; - // this.tilingTexture._uvs = null; + renderSession.spriteBatch.stop(); + renderSession.maskManager.pushMask(this.mask, renderSession); + renderSession.spriteBatch.start(); } + + if(this.filters) + { + renderSession.spriteBatch.flush(); + renderSession.filterManager.pushFilter(this._filterBlock); + } + + if(!this.tilingTexture)this.generateTilingTexture(true); + else renderSession.spriteBatch.renderTilingSprite(this); + + // simple render children! + for(i=0,j=this.children.length; i 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 = {}; @@ -14035,7 +10153,7 @@ spine.Skin.prototype = { _attachAll: function (skeleton, oldSkin) { for (var key in oldSkin.attachments) { var colon = key.indexOf(":"); - var slotIndex = parseInt(key.substring(0, colon)); + var slotIndex = parseInt(key.substring(0, colon), 10); var name = key.substring(colon + 1); var slot = skeleton.slots[slotIndex]; if (slot.attachment && slot.attachment.name == name) { @@ -14052,26 +10170,21 @@ spine.Animation = function (name, timelines, duration) { this.duration = duration; }; spine.Animation.prototype = { - apply: function (skeleton, lastTime, time, loop, events) { - if (loop && this.duration != 0) { - time %= this.duration; - lastTime %= this.duration; - } + apply: function (skeleton, time, loop) { + if (loop && this.duration) time %= this.duration; var timelines = this.timelines; for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, 1); + timelines[i].apply(skeleton, time, 1); }, - mix: function (skeleton, lastTime, time, loop, events, alpha) { - if (loop && this.duration != 0) { - time %= this.duration; - lastTime %= this.duration; - } + mix: function (skeleton, time, loop, alpha) { + if (loop && this.duration) time %= this.duration; var timelines = this.timelines; for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, lastTime, time, events, alpha); + timelines[i].apply(skeleton, time, alpha); } }; -spine.Animation.binarySearch = function (values, target, step) { + +spine.binarySearch = function (values, target, step) { var low = 0; var high = Math.floor(values.length / step) - 2; if (!high) return step; @@ -14085,56 +10198,69 @@ spine.Animation.binarySearch = function (values, target, 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) { +spine.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*/; + this.curves = []; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... + this.curves.length = (frameCount - 1) * 6; }; spine.Curves.prototype = { setLinear: function (frameIndex) { - this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 0/*LINEAR*/; + this.curves[frameIndex * 6] = 0/*LINEAR*/; }, setStepped: function (frameIndex) { - this.curves[frameIndex * 19/*BEZIER_SIZE*/] = 1/*STEPPED*/; + this.curves[frameIndex * 6] = -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 subdiv_step = 1 / 10/*BEZIER_SEGMENTS*/; + var subdiv_step2 = subdiv_step * subdiv_step; + var subdiv_step3 = subdiv_step2 * subdiv_step; + var pre1 = 3 * subdiv_step; + var pre2 = 3 * subdiv_step2; + var pre4 = 6 * subdiv_step2; + var pre5 = 6 * subdiv_step3; + var tmp1x = -cx1 * 2 + cx2; + var tmp1y = -cy1 * 2 + cy2; + var tmp2x = (cx1 - cx2) * 3 + 1; + var tmp2y = (cy1 - cy2) * 3 + 1; + var i = frameIndex * 6; var curves = this.curves; - curves[i++] = 2/*BEZIER*/; - + curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; + curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; + curves[i + 2] = tmp1x * pre4 + tmp2x * pre5; + curves[i + 3] = tmp1y * pre4 + tmp2y * pre5; + curves[i + 4] = tmp2x * pre5; + curves[i + 5] = tmp2y * pre5; + }, + getCurvePercent: function (frameIndex, percent) { + percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent); + var curveIndex = frameIndex * 6; + var curves = this.curves; + var dfx = curves[curveIndex]; + if (!dfx/*LINEAR*/) return percent; + if (dfx == -1/*STEPPED*/) return 0; + var dfy = curves[curveIndex + 1]; + var ddfx = curves[curveIndex + 2]; + var ddfy = curves[curveIndex + 3]; + var dddfx = curves[curveIndex + 4]; + var dddfy = curves[curveIndex + 5]; var x = dfx, y = dfy; - for (var n = i + 19/*BEZIER_SIZE*/ - 1; i < n; i += 2) { - curves[i] = x; - curves[i + 1] = y; + var i = 10/*BEZIER_SEGMENTS*/ - 2; + while (true) { + if (x >= percent) { + var lastX = x - dfx; + var lastY = y - dfy; + return lastY + (y - lastY) * (percent - lastX) / (x - lastX); + } + if (!i) break; + i--; dfx += ddfx; dfy += ddfy; ddfx += dddfx; @@ -14142,31 +10268,6 @@ spine.Curves.prototype = { 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. } }; @@ -14186,14 +10287,16 @@ spine.RotateTimeline.prototype = { this.frames[frameIndex] = time; this.frames[frameIndex + 1] = angle; }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { - var frames = this.frames; + apply: function (skeleton, time, alpha) { + var frames = this.frames, + amount; + 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; + amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation; while (amount > 180) amount -= 360; while (amount < -180) @@ -14202,19 +10305,19 @@ spine.RotateTimeline.prototype = { return; } - // Interpolate between the previous frame and the current frame. - var frameIndex = spine.Animation.binarySearch(frames, time, 2); - var prevFrameValue = frames[frameIndex - 1]; + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 2); + var lastFrameValue = frames[frameIndex - 1]; var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*PREV_FRAME_TIME*/] - frameTime); + var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*LAST_FRAME_TIME*/] - frameTime); percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent); - var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - prevFrameValue; + amount = frames[frameIndex + 1/*FRAME_VALUE*/] - lastFrameValue; while (amount > 180) amount -= 360; while (amount < -180) amount += 360; - amount = bone.data.rotation + (prevFrameValue + amount * percent) - bone.rotation; + amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation; while (amount > 180) amount -= 360; while (amount < -180) @@ -14239,7 +10342,7 @@ spine.TranslateTimeline.prototype = { this.frames[frameIndex + 1] = x; this.frames[frameIndex + 2] = y; }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { + apply: function (skeleton, time, alpha) { var frames = this.frames; if (time < frames[0]) return; // Time is before first frame. @@ -14251,16 +10354,16 @@ spine.TranslateTimeline.prototype = { 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]; + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 3); + var lastFrameX = frames[frameIndex - 2]; + var lastFrameY = frames[frameIndex - 1]; var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime); + var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_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; + bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.x) * alpha; + bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.y) * alpha; } }; @@ -14280,28 +10383,28 @@ spine.ScaleTimeline.prototype = { this.frames[frameIndex + 1] = x; this.frames[frameIndex + 2] = y; }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { + apply: function (skeleton, time, 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; + bone.scaleX += (bone.data.scaleX - 1 + frames[frames.length - 2] - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - 1 + 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]; + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 3); + var lastFrameX = frames[frameIndex - 2]; + var lastFrameY = frames[frameIndex - 1]; var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*PREV_FRAME_TIME*/] - frameTime); + var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_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; + bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.scaleY) * alpha; } }; @@ -14313,9 +10416,9 @@ spine.ColorTimeline = function (frameCount) { spine.ColorTimeline.prototype = { slotIndex: 0, getFrameCount: function () { - return this.frames.length / 5; + return this.frames.length / 2; }, - setFrame: function (frameIndex, time, r, g, b, a) { + setFrame: function (frameIndex, time, x, y) { frameIndex *= 5; this.frames[frameIndex] = time; this.frames[frameIndex + 1] = r; @@ -14323,35 +10426,35 @@ spine.ColorTimeline.prototype = { this.frames[frameIndex + 3] = b; this.frames[frameIndex + 4] = a; }, - apply: function (skeleton, lastTime, time, firedEvents, alpha) { + apply: function (skeleton, time, 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 (time >= frames[frames.length - 5]) { // Time is after last frame. + var i = frames.length - 1; + slot.r = frames[i - 3]; + slot.g = frames[i - 2]; + slot.b = frames[i - 1]; + slot.a = frames[i]; + return; + } + + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 5); + var lastFrameR = frames[frameIndex - 4]; + var lastFrameG = frames[frameIndex - 3]; + var lastFrameB = frames[frameIndex - 2]; + var lastFrameA = frames[frameIndex - 1]; + var frameTime = frames[frameIndex]; + var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*LAST_FRAME_TIME*/] - frameTime); + percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent); + + var r = lastFrameR + (frames[frameIndex + 1/*FRAME_R*/] - lastFrameR) * percent; + var g = lastFrameG + (frames[frameIndex + 2/*FRAME_G*/] - lastFrameG) * percent; + var b = lastFrameB + (frames[frameIndex + 3/*FRAME_B*/] - lastFrameB) * percent; + var a = lastFrameA + (frames[frameIndex + 4/*FRAME_A*/] - lastFrameA) * percent; if (alpha < 1) { slot.r += (r - slot.r) * alpha; slot.g += (g - slot.g) * alpha; @@ -14370,95 +10473,19 @@ spine.AttachmentTimeline = function (frameCount) { this.curves = new spine.Curves(frameCount); this.frames = []; // time, ... this.frames.length = frameCount; - this.attachmentNames = []; + this.attachmentNames = []; // time, ... this.attachmentNames.length = frameCount; }; spine.AttachmentTimeline.prototype = { slotIndex: 0, getFrameCount: function () { - return this.frames.length; + 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) { + apply: function (skeleton, time, alpha) { var frames = this.frames; if (time < frames[0]) return; // Time is before first frame. @@ -14466,182 +10493,10 @@ spine.DrawOrderTimeline.prototype = { if (time >= frames[frames.length - 1]) // Time is after last frame. frameIndex = frames.length - 1; else - frameIndex = spine.Animation.binarySearch1(frames, time) - 1; + frameIndex = spine.binarySearch(frames, time, 1) - 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[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[boneIndex].flipY = frames[frameIndex + 1] != 0; + var attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex].setAttachment(!attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName)); } }; @@ -14649,15 +10504,10 @@ 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; @@ -14695,25 +10545,11 @@ spine.SkeletonData.prototype = { 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; } }; @@ -14724,25 +10560,18 @@ spine.Skeleton = function (skeletonData) { 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.bones.push(new spine.Bone(boneData, parent)); } this.slots = []; this.drawOrder = []; - for (var i = 0, n = skeletonData.slots.length; i < n; i++) { + for (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); + var slot = new spine.Slot(slotData, this, 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, @@ -14750,62 +10579,13 @@ spine.Skeleton.prototype = { 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 flipX = this.flipX; + var flipY = this.flipY; 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++; - } + for (var i = 0, n = bones.length; i < n; i++) + bones[i].updateWorldTransform(flipX, flipY); }, /** Sets the bones and slots to their setup pose values. */ setToSetupPose: function () { @@ -14816,21 +10596,11 @@ spine.Skeleton.prototype = { 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]; + for (var i = 0, n = slots.length; i < n; i++) slots[i].setToSetupPose(i); - } }, /** @return May return null. */ getRootBone: function () { @@ -14869,26 +10639,11 @@ spine.Skeleton.prototype = { 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. + /** Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments + * from the new skin are attached if the corresponding attachment from the old skin was attached. * @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); - } - } - } - } + if (this.skin && newSkin) newSkin._attachAll(this, this.skin); this.skin = newSkin; }, /** @return May be null. */ @@ -14907,13 +10662,13 @@ spine.Skeleton.prototype = { /** @param attachmentName May be null. */ setAttachment: function (slotName, attachmentName) { var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { + for (var i = 0, n = slots.size; 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; + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName; } slot.setAttachment(attachment); return; @@ -14921,58 +10676,26 @@ spine.Skeleton.prototype = { } 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; + 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 + region: 0 }; -spine.RegionAttachment = function (name) { - this.name = name; +spine.RegionAttachment = function () { 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, @@ -15006,7 +10729,7 @@ spine.RegionAttachment.prototype = { 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 radians = this.rotation * Math.PI / 180; var cos = Math.cos(radians); var sin = Math.sin(radians); var localXCos = localX * cos + this.x; @@ -15030,7 +10753,10 @@ spine.RegionAttachment.prototype = { 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 m00 = bone.m00; + var m01 = bone.m01; + var m10 = bone.m10; + var 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; @@ -15041,170 +10767,14 @@ spine.RegionAttachment.prototype = { 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, + defaultMix: 0, setMixByName: function (fromName, toName, duration) { var from = this.skeletonData.findAnimation(fromName); if (!from) throw "Animation not found: " + fromName; @@ -15216,199 +10786,109 @@ spine.AnimationStateData.prototype = { 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; + var time = this.animationToMixTime[from.name + ":" + to.name]; + return time ? time : 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 = []; + this.queue = []; }; spine.AnimationState.prototype = { - onStart: null, - onEnd: null, - onComplete: null, - onEvent: null, - timeScale: 1, + current: null, + previous: null, + currentTime: 0, + previousTime: 0, + currentLoop: false, + previousLoop: false, + mixTime: 0, + mixDuration: 0, update: function (delta) { - delta *= this.timeScale; - for (var i = 0; i < this.tracks.length; i++) { - var current = this.tracks[i]; - if (!current) continue; + this.currentTime += delta; + this.previousTime += delta; + this.mixTime += delta; - 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); + if (this.queue.length > 0) { + var entry = this.queue[0]; + if (this.currentTime >= entry.delay) { + this._setAnimation(entry.animation, entry.loop); + this.queue.shift(); } } }, 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); + if (!this.current) return; + if (this.previous) { + this.previous.apply(skeleton, this.previousTime, this.previousLoop); + var alpha = this.mixTime / this.mixDuration; + if (alpha >= 1) { + alpha = 1; + this.previous = null; } - - 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; - } + this.current.mix(skeleton, this.currentTime, this.currentLoop, alpha); + } else + this.current.apply(skeleton, this.currentTime, this.currentLoop); }, - clearTracks: function () { - for (var i = 0, n = this.tracks.length; i < n; i++) - this.clearTrack(i); - this.tracks.length = 0; + clearAnimation: function () { + this.previous = null; + this.current = null; + this.queue.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; + _setAnimation: function (animation, loop) { + this.previous = null; + if (animation && this.current) { + this.mixDuration = this.data.getMix(this.current, animation); + if (this.mixDuration > 0) { + this.mixTime = 0; + this.previous = this.current; + this.previousTime = this.currentTime; + this.previousLoop = this.currentLoop; } } - - this.tracks[index] = entry; - - if (entry.onStart) entry.onStart(index); - if (this.onStart) this.onStart(index); + this.current = animation; + this.currentLoop = loop; + this.currentTime = 0; }, - setAnimationByName: function (trackIndex, animationName, loop) { + /** @see #setAnimation(Animation, Boolean) */ + setAnimationByName: function (animationName, loop) { var animation = this.data.skeletonData.findAnimation(animationName); if (!animation) throw "Animation not found: " + animationName; - return this.setAnimation(trackIndex, animation, loop); + this.setAnimation(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; + /** Set the current animation. Any queued animations are cleared and the current animation time is set to 0. + * @param animation May be null. */ + setAnimation: function (animation, loop) { + this.queue.length = 0; + this._setAnimation(animation, loop); }, - addAnimationByName: function (trackIndex, animationName, loop, delay) { + /** @see #addAnimation(Animation, Boolean, Number) */ + addAnimationByName: function (animationName, loop, delay) { var animation = this.data.skeletonData.findAnimation(animationName); if (!animation) throw "Animation not found: " + animationName; - return this.addAnimation(trackIndex, animation, loop, delay); + this.addAnimation(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(); + addAnimation: function (animation, loop, delay) { + var entry = {}; 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); + if (!delay || delay <= 0) { + var previousAnimation = this.queue.length ? this.queue[this.queue.length - 1].animation : this.current; + if (previousAnimation != null) + delay = previousAnimation.duration - this.data.getMix(previousAnimation, animation) + (delay || 0); else delay = 0; } entry.delay = delay; - return entry; + this.queue.push(entry); }, - /** May be null. */ - getCurrent: function (trackIndex) { - if (trackIndex >= this.tracks.length) return null; - return this.tracks[trackIndex]; + /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */ + isComplete: function () { + return !this.current || this.currentTime >= this.current.duration; } }; @@ -15417,18 +10897,10 @@ spine.SkeletonJson = function (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; - } + readSkeletonData: function (root) { + /*jshint -W069*/ + var skeletonData = new spine.SkeletonData(), + boneData; // Bones. var bones = root["bones"]; @@ -15439,60 +10911,33 @@ spine.SkeletonJson.prototype = { parent = skeletonData.findBone(boneMap["parent"]); if (!parent) throw "Parent bone not found: " + boneMap["parent"]; } - var boneData = new spine.BoneData(boneMap["name"], parent); + 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; + boneData.scaleX = boneMap["scaleX"] || 1; + boneData.scaleY = boneMap["scaleY"] || 1; 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++) { + for (i = 0, n = slots.length; i < n; i++) { var slotMap = slots[i]; - var boneData = skeletonData.findBone(slotMap["bone"]); + 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.r = spine.SkeletonJson.toColor(color, 0); + slotData.g = spine.SkeletonJson.toColor(color, 1); + slotData.b = spine.SkeletonJson.toColor(color, 2); + slotData.a = spine.SkeletonJson.toColor(color, 3); } slotData.attachmentName = slotMap["attachment"]; - slotData.additiveBlending = slotMap["additive"] && slotMap["additive"] == "true"; skeletonData.slots.push(slotData); } @@ -15510,25 +10955,13 @@ spine.SkeletonJson.prototype = { 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); + if (attachment != null) 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) { @@ -15539,152 +10972,40 @@ spine.SkeletonJson.prototype = { return skeletonData; }, readAttachment: function (skin, name, map) { + /*jshint -W069*/ 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 attachment = new spine.RegionAttachment(); + attachment.x = (map["x"] || 0) * this.scale; + attachment.y = (map["y"] || 0) * this.scale; + attachment.scaleX = map["scaleX"] || 1; + attachment.scaleY = map["scaleY"] || 1; + attachment.rotation = map["rotation"] || 0; + attachment.width = (map["width"] || 32) * this.scale; + attachment.height = (map["height"] || 32) * this.scale; + attachment.updateOffset(); - 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); + attachment.rendererObject = {}; + attachment.rendererObject.name = name; + attachment.rendererObject.scale = {}; + attachment.rendererObject.scale.x = attachment.scaleX; + attachment.rendererObject.scale.y = attachment.scaleY; + attachment.rendererObject.rotation = -attachment.rotation * Math.PI / 180; return attachment; } - throw "Unknown attachment type: " + type; + + throw "Unknown attachment type: " + type; }, + readAnimation: function (name, map, skeletonData) { + /*jshint -W069*/ 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]); - - } 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]); - - } else - throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"; - } - } + var frameIndex, timeline, timelineName, valueMap, values, + i, n; var bones = map["bones"]; for (var boneName in bones) { @@ -15693,25 +11014,24 @@ spine.SkeletonJson.prototype = { if (boneIndex == -1) throw "Bone not found: " + boneName; var boneMap = bones[boneName]; - for (var timelineName in boneMap) { + for (timelineName in boneMap) { if (!boneMap.hasOwnProperty(timelineName)) continue; - var values = boneMap[timelineName]; + values = boneMap[timelineName]; if (timelineName == "rotate") { - var timeline = new spine.RotateTimeline(values.length); + 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]; + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]); - this.readCurve(timeline, frameIndex, valueMap); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.push(timeline); duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); } else if (timelineName == "translate" || timelineName == "scale") { - var timeline; var timelineScale = 1; if (timelineName == "scale") timeline = new spine.ScaleTimeline(values.length); @@ -15721,215 +11041,82 @@ spine.SkeletonJson.prototype = { } timeline.boneIndex = boneIndex; - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + 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); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); frameIndex++; } timelines.push(timeline); duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]); - } 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]); } else throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"; } } + var slots = map["slots"]; + for (var slotName in slots) { + if (!slots.hasOwnProperty(slotName)) continue; + var slotMap = slots[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); - 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]); - } - - 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; + for (timelineName in slotMap) { + if (!slotMap.hasOwnProperty(timelineName)) continue; + values = slotMap[timelineName]; + if (timelineName == "color") { + timeline = new spine.ColorTimeline(values.length); 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 = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + var color = valueMap["color"]; + var r = spine.SkeletonJson.toColor(color, 0); + var g = spine.SkeletonJson.toColor(color, 1); + var b = spine.SkeletonJson.toColor(color, 2); + var a = spine.SkeletonJson.toColor(color, 3); + timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); frameIndex++; } - timelines[timelines.length] = timeline; - duration = Math.max(duration, timeline.frames[timeline.frameCount - 1]); - } - } - } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]); - 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++; + } else if (timelineName == "attachment") { + timeline = new spine.AttachmentTimeline(values.length); + timeline.slotIndex = slotIndex; + + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]); } - // 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]); - } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - 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); + } else + throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"; } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); } - 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.SkeletonJson.readCurve = function (timeline, frameIndex, valueMap) { + /*jshint -W069*/ + var curve = valueMap["curve"]; + if (!curve) return; + if (curve == "stepped") + timeline.curves.setStepped(frameIndex); + else if (curve instanceof Array) + timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); +}; +spine.SkeletonJson.toColor = function (hexString, colorIndex) { + if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString; + return parseInt(hexString.substring(colorIndex * 2, 2), 16) / 255; +}; spine.Atlas = function (atlasText, textureLoader) { this.textureLoader = textureLoader; @@ -15942,7 +11129,7 @@ spine.Atlas = function (atlasText, textureLoader) { var page = null; while (true) { var line = reader.readLine(); - if (line === null) break; + if (line == null) break; line = reader.trim(line); if (!line.length) page = null; @@ -15950,12 +11137,7 @@ spine.Atlas = function (atlasText, textureLoader) { 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]]; + page.format = spine.Atlas.Format[reader.readValue()]; reader.readTuple(tuple); page.minFilter = spine.Atlas.TextureFilter[tuple[0]]; @@ -15971,7 +11153,7 @@ spine.Atlas = function (atlasText, textureLoader) { else if (direction == "xy") page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat; - textureLoader.load(page, line, this); + textureLoader.load(page, line); this.pages.push(page); @@ -15983,12 +11165,12 @@ spine.Atlas = function (atlasText, textureLoader) { region.rotate = reader.readValue() == "true"; reader.readTuple(tuple); - var x = parseInt(tuple[0]); - var y = parseInt(tuple[1]); + var x = parseInt(tuple[0], 10); + var y = parseInt(tuple[1], 10); reader.readTuple(tuple); - var width = parseInt(tuple[0]); - var height = parseInt(tuple[1]); + var width = parseInt(tuple[0], 10); + var height = parseInt(tuple[1], 10); region.u = x / page.width; region.v = y / page.height; @@ -16005,23 +11187,23 @@ spine.Atlas = function (atlasText, textureLoader) { 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])]; + region.splits = [parseInt(tuple[0], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; 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])]; + region.pads = [parseInt(tuple[0], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; reader.readTuple(tuple); } } - region.originalWidth = parseInt(tuple[0]); - region.originalHeight = parseInt(tuple[1]); + region.originalWidth = parseInt(tuple[0], 10); + region.originalHeight = parseInt(tuple[1], 10); reader.readTuple(tuple); - region.offsetX = parseInt(tuple[0]); - region.offsetY = parseInt(tuple[1]); + region.offsetX = parseInt(tuple[0], 10); + region.offsetY = parseInt(tuple[1], 10); - region.index = parseInt(reader.readValue()); + region.index = parseInt(reader.readValue(), 10); this.regions.push(region); } @@ -16108,7 +11290,7 @@ spine.AtlasRegion.prototype = { index: 0, rotate: false, splits: null, - pads: null + pads: null, }; spine.AtlasReader = function (text) { @@ -16129,291 +11311,53 @@ spine.AtlasReader.prototype = { 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). */ + /** Returns the number of tuple values read (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; + var i = 0, lastMatch= colon + 1; for (; i < 3; i++) { var comma = line.indexOf(",", lastMatch); - if (comma == -1) break; + if (comma == -1) { + if (!i) throw "Invalid line: " + line; + 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); + newAttachment: function (skin, type, name) { + switch (type) { + case spine.AttachmentType.region: + var region = this.atlas.findRegion(name); + if (!region) throw "Region not found in atlas: " + name + " (" + type + ")"; + 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; + } + throw "Unknown attachment type: " + type; } -}; - -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; - } -}; - -/* Esoteric Software SPINE wrapper for pixi.js */ +} spine.Bone.yDown = true; PIXI.AnimCache = {}; -/** - * Supporting class to load images from spine atlases as per spine spec. - * - * @class SpineTextureLoader - * @uses EventTarget - * @constructor - * @param basePath {String} Tha base path where to look for the images to be loaded - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.SpineTextureLoader = function(basePath, crossorigin) -{ - PIXI.EventTarget.call(this); - - this.basePath = basePath; - this.crossorigin = crossorigin; - this.loadingCount = 0; -}; - -/* constructor */ -PIXI.SpineTextureLoader.prototype = PIXI.SpineTextureLoader; - -/** - * Starts loading a base texture as per spine specification - * - * @method load - * @param page {spine.AtlasPage} Atlas page to which texture belongs - * @param file {String} The file to load, this is just the file path relative to the base path configured in the constructor - */ -PIXI.SpineTextureLoader.prototype.load = function(page, file) -{ - page.rendererObject = PIXI.BaseTexture.fromImage(this.basePath + '/' + file, this.crossorigin); - if (!page.rendererObject.hasLoaded) - { - var scope = this; - ++scope.loadingCount; - page.rendererObject.addEventListener('loaded', function(){ - --scope.loadingCount; - scope.dispatchEvent({ - type: 'loadedBaseTexture', - content: scope - }); - }); - } -}; - -/** - * Unloads a previously loaded texture as per spine specification - * - * @method unload - * @param texture {BaseTexture} Texture object to destroy - */ -PIXI.SpineTextureLoader.prototype.unload = function(texture) -{ - texture.destroy(true); -}; - /** * A class that enables the you to import and run your spine animations in pixi. * Spine animation data needs to be loaded using the PIXI.AssetLoader or PIXI.SpineLoader before it can be used by this class @@ -16430,7 +11374,7 @@ PIXI.Spine = function (url) { this.spineData = PIXI.AnimCache[url]; if (!this.spineData) { - throw new Error('Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: ' + url); + throw new Error("Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: " + url); } this.skeleton = new spine.Skeleton(this.spineData); @@ -16447,67 +11391,31 @@ PIXI.Spine = function (url) { var slotContainer = new PIXI.DisplayObjectContainer(); this.slotContainers.push(slotContainer); this.addChild(slotContainer); - - if (attachment instanceof spine.RegionAttachment) - { - var spriteName = attachment.rendererObject.name; - var sprite = this.createSprite(slot, attachment); - slot.currentSprite = sprite; - slot.currentSpriteName = spriteName; - slotContainer.addChild(sprite); - } - else if (attachment instanceof spine.MeshAttachment) - { - var mesh = this.createMesh(slot, attachment); - slot.currentMesh = mesh; - slot.currentMeshName = attachment.name; - slotContainer.addChild(mesh); - } - else - { + if (!(attachment instanceof spine.RegionAttachment)) { continue; } - + var spriteName = attachment.rendererObject.name; + var sprite = this.createSprite(slot, attachment.rendererObject); + slot.currentSprite = sprite; + slot.currentSpriteName = spriteName; + slotContainer.addChild(sprite); } - - this.autoUpdate = true; }; PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); PIXI.Spine.prototype.constructor = PIXI.Spine; -/** - * If this flag is set to true, the spine animation will be autoupdated every time - * the object id drawn. The down side of this approach is that the delta time is - * automatically calculated and you could miss out on cool effects like slow motion, - * pause, skip ahead and the sorts. Most of these effects can be achieved even with - * autoupdate enabled but are harder to achieve. +/* + * Updates the object transform for rendering * - * @property autoUpdate - * @type { Boolean } - * @default true + * @method updateTransform + * @private */ -Object.defineProperty(PIXI.Spine.prototype, 'autoUpdate', { - get: function() - { - return (this.updateTransform === PIXI.Spine.prototype.autoUpdateTransform); - }, - - set: function(value) - { - this.updateTransform = value ? PIXI.Spine.prototype.autoUpdateTransform : PIXI.DisplayObjectContainer.prototype.updateTransform; - } -}); - -/** - * Update the spine skeleton and its animations by delta time (dt) - * - * @method update - * @param dt {Number} Delta time. Time by which the animation should be updated - */ -PIXI.Spine.prototype.update = function(dt) -{ - this.state.update(dt); +PIXI.Spine.prototype.updateTransform = function () { + this.lastTime = this.lastTime || Date.now(); + var timeDelta = (Date.now() - this.lastTime) * 0.001; + this.lastTime = Date.now(); + this.state.update(timeDelta); this.state.apply(this.skeleton); this.skeleton.updateWorldTransform(); @@ -16516,181 +11424,79 @@ PIXI.Spine.prototype.update = function(dt) var slot = drawOrder[i]; var attachment = slot.attachment; var slotContainer = this.slotContainers[i]; - - if (!attachment) - { + if (!(attachment instanceof spine.RegionAttachment)) { slotContainer.visible = 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.visible = false; - } - slot.sprites = slot.sprites || {}; - if (slot.sprites[spriteName] !== undefined) - { - slot.sprites[spriteName].visible = true; - } - else - { - var sprite = this.createSprite(slot, attachment); - slotContainer.addChild(sprite); - } - slot.currentSprite = slot.sprites[spriteName]; - slot.currentSpriteName = spriteName; + if (attachment.rendererObject) { + if (!slot.currentSpriteName || slot.currentSpriteName != attachment.name) { + var spriteName = attachment.rendererObject.name; + if (slot.currentSprite !== undefined) { + slot.currentSprite.visible = false; } + slot.sprites = slot.sprites || {}; + if (slot.sprites[spriteName] !== undefined) { + slot.sprites[spriteName].visible = true; + } else { + var sprite = this.createSprite(slot, attachment.rendererObject); + slotContainer.addChild(sprite); + } + slot.currentSprite = slot.sprites[spriteName]; + slot.currentSpriteName = spriteName; } - - var bone = slot.bone; - - slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01; - slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11; - slotContainer.scale.x = bone.worldScaleX; - slotContainer.scale.y = bone.worldScaleY; - - slotContainer.rotation = -(slot.bone.worldRotation * spine.degRad); - - slot.currentSprite.tint = PIXI.rgb2hex([slot.r,slot.g,slot.b]); - } - else if (type === spine.AttachmentType.skinnedmesh) - { - if (!slot.currentMeshName || slot.currentMeshName !== attachment.name) - { - var meshName = attachment.name; - if (slot.currentMesh !== undefined) - { - slot.currentMesh.visible = false; - } - - slot.meshes = slot.meshes || {}; - - if (slot.meshes[meshName] !== undefined) - { - slot.meshes[meshName].visible = true; - } - else - { - var mesh = this.createMesh(slot, attachment); - slotContainer.addChild(mesh); - } - - slot.currentMesh = slot.meshes[meshName]; - slot.currentMeshName = meshName; - } - - attachment.computeWorldVertices(slot.bone.skeleton.x, slot.bone.skeleton.y, slot, slot.currentMesh.vertices); - - } - else - { - slotContainer.visible = false; - continue; } slotContainer.visible = true; - slotContainer.alpha = slot.a; + var bone = slot.bone; + + slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01; + slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11; + slotContainer.scale.x = bone.worldScaleX; + slotContainer.scale.y = bone.worldScaleY; + + slotContainer.rotation = -(slot.bone.worldRotation * Math.PI / 180); } -}; - -/** - * When autoupdate is set to yes this function is used as pixi's updateTransform function - * - * @method autoUpdateTransform - * @private - */ -PIXI.Spine.prototype.autoUpdateTransform = function () { - this.lastTime = this.lastTime || Date.now(); - var timeDelta = (Date.now() - this.lastTime) * 0.001; - this.lastTime = Date.now(); - - this.update(timeDelta); PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); }; -/** - * Create a new sprite to be used with spine.RegionAttachment - * - * @method createSprite - * @param slot {spine.Slot} The slot to which the attachment is parented - * @param attachment {spine.RegionAttachment} The attachment that the sprite will represent - * @private - */ -PIXI.Spine.prototype.createSprite = function (slot, attachment) { - var descriptor = attachment.rendererObject; - var baseTexture = descriptor.page.rendererObject; - var spriteRect = new PIXI.Rectangle(descriptor.x, - descriptor.y, - descriptor.rotate ? descriptor.height : descriptor.width, - descriptor.rotate ? descriptor.width : descriptor.height); - var spriteTexture = new PIXI.Texture(baseTexture, spriteRect); - var sprite = new PIXI.Sprite(spriteTexture); - var baseRotation = descriptor.rotate ? Math.PI * 0.5 : 0.0; - sprite.scale.set(descriptor.width / descriptor.originalWidth, descriptor.height / descriptor.originalHeight); - sprite.rotation = baseRotation - (attachment.rotation * spine.degRad); +PIXI.Spine.prototype.createSprite = function (slot, descriptor) { + var name = PIXI.TextureCache[descriptor.name] ? descriptor.name : descriptor.name + ".png"; + var sprite = new PIXI.Sprite(PIXI.Texture.fromFrame(name)); + sprite.scale = descriptor.scale; + sprite.rotation = descriptor.rotation; sprite.anchor.x = sprite.anchor.y = 0.5; slot.sprites = slot.sprites || {}; slot.sprites[descriptor.name] = sprite; return sprite; }; - -PIXI.Spine.prototype.createMesh = function (slot, attachment) { - var descriptor = attachment.rendererObject; - var baseTexture = descriptor.page.rendererObject; - var texture = new PIXI.Texture(baseTexture); - - var strip = new PIXI.Strip(texture); - strip.drawMode = PIXI.Strip.DrawModes.TRIANGLES; - strip.canvasPadding = 1.5; - - strip.vertices = new PIXI.Float32Array(attachment.uvs.length); - strip.uvs = attachment.uvs; - strip.indices = attachment.triangles; - - slot.meshes = slot.meshes || {}; - slot.meshes[attachment.name] = strip; - - return strip; -}; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ PIXI.BaseTextureCache = {}; +PIXI.texturesToUpdate = []; +PIXI.texturesToDestroy = []; PIXI.BaseTextureCacheIdGenerator = 0; /** - * A texture stores the information that represents an image. All textures have a base texture. + * A texture stores the information that represents an image. All textures have a base texture * * @class BaseTexture * @uses EventTarget * @constructor * @param source {String} the source object (image or canvas) - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values + * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts */ PIXI.BaseTexture = function(source, scaleMode) { - /** - * The Resolution of the texture. - * - * @property resolution - * @type Number - */ - this.resolution = 1; - + PIXI.EventTarget.call( this ); + /** * [read-only] The width of the base texture set when the image has loaded * @@ -16711,15 +11517,14 @@ PIXI.BaseTexture = function(source, scaleMode) /** * The scale mode to apply when scaling this texture - * * @property scaleMode - * @type {Number} + * @type PIXI.scaleModes * @default PIXI.scaleModes.LINEAR */ this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; /** - * [read-only] Set to true once the base texture has loaded + * [read-only] Describes if the base texture has loaded or not * * @property hasLoaded * @type Boolean @@ -16728,108 +11533,52 @@ PIXI.BaseTexture = function(source, scaleMode) this.hasLoaded = false; /** - * The image source that is used to create the texture. + * The source that is loaded to create the texture * * @property source * @type Image */ this.source = source; - this._UID = PIXI._UID++; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * - * @property premultipliedAlpha - * @type Boolean - * @default true - */ - this.premultipliedAlpha = true; - - // used for webGL - - /** - * @property _glTextures - * @type Array - * @private - */ - this._glTextures = []; - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @property mipmap - * @type {Boolean} - */ - this.mipmap = false; - - // used for webGL texture updating... - // TODO - this needs to be addressed - - /** - * @property _dirty - * @type Array - * @private - */ - this._dirty = [ - true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, - true, true, true, true, true, true, true, true, true, true, - ]; - if(!source)return; - if((this.source.complete || this.source.getContext) && this.source.width && this.source.height) + if(this.source.complete || this.source.getContext) { this.hasLoaded = true; - this.width = this.source.naturalWidth || this.source.width; - this.height = this.source.naturalHeight || this.source.height; - this.dirty(); + this.width = this.source.width; + this.height = this.source.height; + + PIXI.texturesToUpdate.push(this); } else { - var scope = this; + var scope = this; this.source.onload = function() { scope.hasLoaded = true; - scope.width = scope.source.naturalWidth || scope.source.width; - scope.height = scope.source.naturalHeight || scope.source.height; - - scope.dirty(); + scope.width = scope.source.width; + scope.height = scope.source.height; // add it to somewhere... + PIXI.texturesToUpdate.push(scope); scope.dispatchEvent( { type: 'loaded', content: scope } ); }; - - this.source.onerror = function() { - scope.dispatchEvent( { type: 'error', content: scope } ); - }; } - /** - * @property imageUrl - * @type String - */ this.imageUrl = null; - - /** - * @property _powerOf2 - * @type Boolean - * @private - */ this._powerOf2 = false; + //TODO will be used for futer pixi 1.5... + this.id = PIXI.BaseTextureCacheIdGenerator++; + + // used for webGL + this._glTextures = []; + }; PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; -PIXI.EventTarget.mixin(PIXI.BaseTexture.prototype); - /** * Destroys this base texture * @@ -16840,17 +11589,11 @@ PIXI.BaseTexture.prototype.destroy = function() if(this.imageUrl) { delete PIXI.BaseTextureCache[this.imageUrl]; - delete PIXI.TextureCache[this.imageUrl]; this.imageUrl = null; - if (!navigator.isCocoonJS) this.source.src = ''; - } - else if (this.source && this.source._pixiId) - { - delete PIXI.BaseTextureCache[this.source._pixiId]; + this.source.src = null; } this.source = null; - - this.unloadFromGPU(); + PIXI.texturesToDestroy.push(this); }; /** @@ -16867,62 +11610,20 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) }; /** - * Sets all glTextures to be dirty. - * - * @method dirty - */ -PIXI.BaseTexture.prototype.dirty = function() -{ - for (var i = 0; i < this._glTextures.length; i++) - { - this._dirty[i] = true; - } -}; - -/** - * Removes the base texture from the GPU, useful for managing resources on the GPU. - * Atexture is still 100% usable and will simply be reuploaded if there is a sprite on screen that is using it. - * - * @method unloadFromGPU - */ -PIXI.BaseTexture.prototype.unloadFromGPU = function() -{ - this.dirty(); - - // delete the webGL textures if any. - for (var i = this._glTextures.length - 1; i >= 0; i--) - { - var glTexture = this._glTextures[i]; - var gl = PIXI.glContexts[i]; - - if(gl && glTexture) - { - gl.deleteTexture(glTexture); - } - - } - - this._glTextures.length = 0; - - this.dirty(); -}; - -/** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. + * Helper function that returns a base texture based on an image url + * If the image is not in the base texture cache it will be created and loaded * * @static * @method fromImage * @param imageUrl {String} The image url of the texture - * @param crossorigin {Boolean} - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values + * @param crossorigin {Boolean} + * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts * @return BaseTexture */ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) { var baseTexture = PIXI.BaseTextureCache[imageUrl]; - - if(crossorigin === undefined && imageUrl.indexOf('data:') === -1) crossorigin = true; + crossorigin = !crossorigin; if(!baseTexture) { @@ -16933,31 +11634,15 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) { image.crossOrigin = ''; } - image.src = imageUrl; baseTexture = new PIXI.BaseTexture(image, scaleMode); baseTexture.imageUrl = imageUrl; PIXI.BaseTextureCache[imageUrl] = baseTexture; - - // if there is an @2x at the end of the url we are going to assume its a highres image - if( imageUrl.indexOf(PIXI.RETINA_PREFIX + '.') !== -1) - { - baseTexture.resolution = 2; - } } return baseTexture; }; -/** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @method fromCanvas - * @param canvas {Canvas} The canvas element source of the texture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return BaseTexture - */ PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode) { if(!canvas._pixiId) @@ -16976,6 +11661,8 @@ PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode) return baseTexture; }; + + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -16987,39 +11674,29 @@ PIXI.TextureCacheIdGenerator = 0; /** * A texture stores the information that represents an image or part of an image. It cannot be added - * to the display list directly. Instead use it as the texture for a PIXI.Sprite. If no frame is provided then the whole image is used. + * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used * * @class Texture * @uses EventTarget * @constructor * @param baseTexture {BaseTexture} The base texture source to create the texture from * @param frame {Rectangle} The rectangle frame of the texture to show - * @param [crop] {Rectangle} The area of original texture - * @param [trim] {Rectangle} Trimmed texture rectangle */ -PIXI.Texture = function(baseTexture, frame, crop, trim) +PIXI.Texture = function(baseTexture, frame) { - /** - * Does this Texture have any frame data assigned to it? - * - * @property noFrame - * @type Boolean - */ - this.noFrame = false; + PIXI.EventTarget.call( this ); - if (!frame) + if(!frame) { this.noFrame = true; frame = new PIXI.Rectangle(0,0,1,1); } - if (baseTexture instanceof PIXI.Texture) - { + if(baseTexture instanceof PIXI.Texture) baseTexture = baseTexture.baseTexture; - } /** - * The base texture that this texture uses. + * The base texture of that this texture uses * * @property baseTexture * @type BaseTexture @@ -17035,93 +11712,47 @@ PIXI.Texture = function(baseTexture, frame, crop, trim) this.frame = frame; /** - * The texture trim data. + * The trim point * * @property trim * @type Rectangle */ - this.trim = trim; + this.trim = null; + + this.scope = this; - /** - * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. - * - * @property valid - * @type Boolean - */ - this.valid = false; - - /** - * This will let a renderer know that a texture has been updated (used mainly for webGL uv updates) - * - * @property requiresUpdate - * @type Boolean - */ - this.requiresUpdate = false; - - /** - * The WebGL UV data cache. - * - * @property _uvs - * @type Object - * @private - */ - this._uvs = null; - - /** - * The width of the Texture in pixels. - * - * @property width - * @type Number - */ - this.width = 0; - - /** - * The height of the Texture in pixels. - * - * @property height - * @type Number - */ - this.height = 0; - - /** - * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering, - * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases) - * - * @property crop - * @type Rectangle - */ - this.crop = crop || new PIXI.Rectangle(0, 0, 1, 1); - - if (baseTexture.hasLoaded) + if(baseTexture.hasLoaded) { - if (this.noFrame) frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height); + if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + this.setFrame(frame); } else { - baseTexture.addEventListener('loaded', this.onBaseTextureLoaded.bind(this)); + var scope = this; + baseTexture.addEventListener('loaded', function(){ scope.onBaseTextureLoaded(); }); } }; PIXI.Texture.prototype.constructor = PIXI.Texture; -PIXI.EventTarget.mixin(PIXI.Texture.prototype); /** * Called when the base texture is loaded * * @method onBaseTextureLoaded + * @param event * @private */ PIXI.Texture.prototype.onBaseTextureLoaded = function() { var baseTexture = this.baseTexture; - baseTexture.removeEventListener('loaded', this.onLoaded); - - if (this.noFrame) this.frame = new PIXI.Rectangle(0, 0, baseTexture.width, baseTexture.height); + baseTexture.removeEventListener( 'loaded', this.onLoaded ); + if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + this.setFrame(this.frame); - this.dispatchEvent( { type: 'update', content: this } ); + this.scope.dispatchEvent( { type: 'update', content: this } ); }; /** @@ -17132,63 +11763,42 @@ PIXI.Texture.prototype.onBaseTextureLoaded = function() */ PIXI.Texture.prototype.destroy = function(destroyBase) { - if (destroyBase) this.baseTexture.destroy(); - - this.valid = false; + if(destroyBase) this.baseTexture.destroy(); }; /** - * Specifies the region of the baseTexture that this texture will use. + * Specifies the rectangle region of the baseTexture * * @method setFrame * @param frame {Rectangle} The frame of the texture to set it to */ PIXI.Texture.prototype.setFrame = function(frame) { - this.noFrame = false; - this.frame = frame; this.width = frame.width; this.height = frame.height; - this.crop.x = frame.x; - this.crop.y = frame.y; - this.crop.width = frame.width; - this.crop.height = frame.height; - - if (!this.trim && (frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height)) + if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) { throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); } - this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded; + this.updateFrame = true; - if (this.trim) - { - this.width = this.trim.width; - this.height = this.trim.height; - this.frame.width = this.trim.width; - this.frame.height = this.trim.height; - } - - if (this.valid) this._updateUvs(); + PIXI.Texture.frameUpdates.push(this); + + //this.dispatchEvent( { type: 'update', content: this } ); }; -/** - * Updates the internal WebGL UV cache. - * - * @method _updateUvs - * @private - */ -PIXI.Texture.prototype._updateUvs = function() +PIXI.Texture.prototype._updateWebGLuvs = function() { if(!this._uvs)this._uvs = new PIXI.TextureUvs(); - var frame = this.crop; + var frame = this.frame; var tw = this.baseTexture.width; var th = this.baseTexture.height; - + this._uvs.x0 = frame.x / tw; this._uvs.y0 = frame.y / th; @@ -17203,14 +11813,13 @@ PIXI.Texture.prototype._updateUvs = function() }; /** - * Helper function that creates a Texture object from the given image url. - * If the image is not in the texture cache it will be created and loaded. + * Helper function that returns a texture based on an image url + * If the image is not in the texture cache it will be created and loaded * * @static * @method fromImage * @param imageUrl {String} The image url of the texture * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values * @return Texture */ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) @@ -17227,8 +11836,8 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) }; /** - * Helper function that returns a Texture objected based on the given frame id. - * If the frame id is not in the texture cache an error will be thrown. + * Helper function that returns a texture based on a frame id + * If the frame id is not in the texture cache an error will be thrown * * @static * @method fromFrame @@ -17243,12 +11852,12 @@ PIXI.Texture.fromFrame = function(frameId) }; /** - * Helper function that creates a new a Texture based on the given canvas element. + * Helper function that returns a texture based on a canvas element + * If the canvas is not in the texture cache it will be created and loaded * * @static * @method fromCanvas * @param canvas {Canvas} The canvas element source of the texture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values * @return Texture */ PIXI.Texture.fromCanvas = function(canvas, scaleMode) @@ -17259,13 +11868,14 @@ PIXI.Texture.fromCanvas = function(canvas, scaleMode) }; + /** - * Adds a texture to the global PIXI.TextureCache. This cache is shared across the whole PIXI object. + * Adds a texture to the textureCache. * * @static * @method addTextureToCache - * @param texture {Texture} The Texture to add to the cache. - * @param id {String} The id that the texture will be stored against. + * @param texture {Texture} + * @param id {String} the id that the texture will be stored against. */ PIXI.Texture.addTextureToCache = function(texture, id) { @@ -17273,21 +11883,23 @@ PIXI.Texture.addTextureToCache = function(texture, id) }; /** - * Remove a texture from the global PIXI.TextureCache. + * Remove a texture from the textureCache. * * @static * @method removeTextureFromCache - * @param id {String} The id of the texture to be removed - * @return {Texture} The texture that was removed + * @param id {String} the id of the texture to be removed + * @return {Texture} the texture that was removed */ PIXI.Texture.removeTextureFromCache = function(id) { var texture = PIXI.TextureCache[id]; - delete PIXI.TextureCache[id]; - delete PIXI.BaseTextureCache[id]; + PIXI.TextureCache[id] = null; return texture; }; +// this is more for webGL.. it contains updated frames.. +PIXI.Texture.frameUpdates = []; + PIXI.TextureUvs = function() { this.x0 = 0; @@ -17300,48 +11912,48 @@ PIXI.TextureUvs = function() this.y2 = 0; this.x3 = 0; - this.y3 = 0; + this.y4 = 0; + + }; -PIXI.Texture.emptyTexture = new PIXI.Texture(new PIXI.BaseTexture()); - - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * A RenderTexture is a special texture that allows any Pixi display object to be rendered to it. - * - * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded otherwise black rectangles will be drawn instead. - * - * A RenderTexture takes a snapshot of any Display Object given to its render method. The position and rotation of the given Display Objects is ignored. For example: - * - * var renderTexture = new PIXI.RenderTexture(800, 600); - * var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); - * sprite.position.x = 800/2; - * sprite.position.y = 600/2; - * sprite.anchor.x = 0.5; - * sprite.anchor.y = 0.5; - * renderTexture.render(sprite); - * - * The Sprite in this case will be rendered to a position of 0,0. To render this sprite at its actual position a DisplayObjectContainer should be used: - * - * var doc = new PIXI.DisplayObjectContainer(); - * doc.addChild(sprite); - * renderTexture.render(doc); // Renders to center of renderTexture - * + A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it. + + __Hint__: All DisplayObjects (exmpl. Sprites) that render on RenderTexture should be preloaded. + Otherwise black rectangles will be drawn instead. + + RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example: + + var renderTexture = new PIXI.RenderTexture(800, 600); + var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); + sprite.position.x = 800/2; + sprite.position.y = 600/2; + sprite.anchor.x = 0.5; + sprite.anchor.y = 0.5; + renderTexture.render(sprite); + + Sprite in this case will be rendered to 0,0 position. To render this sprite at center DisplayObjectContainer should be used: + + var doc = new PIXI.DisplayObjectContainer(); + doc.addChild(sprite); + renderTexture.render(doc); // Renders to center of renderTexture + * @class RenderTexture * @extends Texture * @constructor * @param width {Number} The width of the render texture * @param height {Number} The height of the render texture - * @param renderer {CanvasRenderer|WebGLRenderer} The renderer used for this RenderTexture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @param resolution {Number} The resolution of the texture being generated */ -PIXI.RenderTexture = function(width, height, renderer, scaleMode, resolution) +PIXI.RenderTexture = function(width, height, renderer) { + PIXI.EventTarget.call( this ); + /** * The with of the render texture * @@ -17349,7 +11961,6 @@ PIXI.RenderTexture = function(width, height, renderer, scaleMode, resolution) * @type Number */ this.width = width || 100; - /** * The height of the render texture * @@ -17358,30 +11969,13 @@ PIXI.RenderTexture = function(width, height, renderer, scaleMode, resolution) */ this.height = height || 100; - /** - * The Resolution of the texture. - * - * @property resolution - * @type Number - */ - this.resolution = resolution || 1; - /** * The framing rectangle of the render texture * * @property frame * @type Rectangle */ - this.frame = new PIXI.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); - - /** - * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering, - * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases) - * - * @property crop - * @type Rectangle - */ - this.crop = new PIXI.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); + this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); /** * The base texture object that this texture uses @@ -17390,107 +11984,63 @@ PIXI.RenderTexture = function(width, height, renderer, scaleMode, resolution) * @type BaseTexture */ this.baseTexture = new PIXI.BaseTexture(); - this.baseTexture.width = this.width * this.resolution; - this.baseTexture.height = this.height * this.resolution; + this.baseTexture.width = this.width; + this.baseTexture.height = this.height; this.baseTexture._glTextures = []; - this.baseTexture.resolution = this.resolution; - - this.baseTexture.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; this.baseTexture.hasLoaded = true; - PIXI.Texture.call(this, - this.baseTexture, - new PIXI.Rectangle(0, 0, this.width, this.height) - ); - - /** - * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. - * - * @property renderer - * @type CanvasRenderer|WebGLRenderer - */ + // each render texture can only belong to one renderer at the moment if its webGL this.renderer = renderer || PIXI.defaultRenderer; if(this.renderer.type === PIXI.WEBGL_RENDERER) { var gl = this.renderer.gl; - this.baseTexture._dirty[gl.id] = false; - this.textureBuffer = new PIXI.FilterTexture(gl, this.width * this.resolution, this.height * this.resolution, this.baseTexture.scaleMode); + this.textureBuffer = new PIXI.FilterTexture(gl, this.width, this.height); this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; this.render = this.renderWebGL; - this.projection = new PIXI.Point(this.width*0.5, -this.height*0.5); + this.projection = new PIXI.Point(this.width/2 , -this.height/2); } else { this.render = this.renderCanvas; - this.textureBuffer = new PIXI.CanvasBuffer(this.width* this.resolution, this.height* this.resolution); + this.textureBuffer = new PIXI.CanvasBuffer(this.width, this.height); this.baseTexture.source = this.textureBuffer.canvas; } - /** - * @property valid - * @type Boolean - */ - this.valid = true; + PIXI.Texture.frameUpdates.push(this); + - this._updateUvs(); }; PIXI.RenderTexture.prototype = Object.create(PIXI.Texture.prototype); PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; -/** - * Resizes the RenderTexture. - * - * @method resize - * @param width {Number} The width to resize to. - * @param height {Number} The height to resize to. - * @param updateBase {Boolean} Should the baseTexture.width and height values be resized as well? - */ -PIXI.RenderTexture.prototype.resize = function(width, height, updateBase) +PIXI.RenderTexture.prototype.resize = function(width, height) { - if (width === this.width && height === this.height)return; + this.width = width; + this.height = height; - this.valid = (width > 0 && height > 0); + this.frame.width = this.width; + this.frame.height = this.height; - this.width = this.frame.width = this.crop.width = width; - this.height = this.frame.height = this.crop.height = height; - - if (updateBase) - { - this.baseTexture.width = this.width; - this.baseTexture.height = this.height; - } - - if (this.renderer.type === PIXI.WEBGL_RENDERER) + if(this.renderer.type === PIXI.WEBGL_RENDERER) { this.projection.x = this.width / 2; this.projection.y = -this.height / 2; + + var gl = this.renderer.gl; + gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTextures[gl.id]); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } - - if(!this.valid)return; - - this.textureBuffer.resize(this.width * this.resolution, this.height * this.resolution); -}; - -/** - * Clears the RenderTexture. - * - * @method clear - */ -PIXI.RenderTexture.prototype.clear = function() -{ - if(!this.valid)return; - - if (this.renderer.type === PIXI.WEBGL_RENDERER) + else { - this.renderer.gl.bindFramebuffer(this.renderer.gl.FRAMEBUFFER, this.textureBuffer.frameBuffer); + this.textureBuffer.resize(this.width, this.height); } - this.textureBuffer.clear(); + PIXI.Texture.frameUpdates.push(this); }; /** @@ -17498,47 +12048,50 @@ PIXI.RenderTexture.prototype.clear = function() * * @method renderWebGL * @param displayObject {DisplayObject} The display object to render this texture on - * @param [matrix] {Matrix} Optional matrix to apply to the display object before rendering. - * @param [clear] {Boolean} If true the texture will be cleared before the displayObject is drawn + * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn * @private */ -PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, matrix, clear) +PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) { - if(!this.valid)return; //TOOD replace position with matrix.. - - //Lets create a nice matrix to apply to our display object. Frame buffers come in upside down so we need to flip the matrix - var wt = displayObject.worldTransform; - wt.identity(); - wt.translate(0, this.projection.y * 2); - if(matrix)wt.append(matrix); - wt.scale(1,-1); - - // setWorld Alpha to ensure that the object is renderer at full opacity - displayObject.worldAlpha = 1; - - // Time to update all the children of the displayObject with the new matrix.. - var children = displayObject.children; - - for(var i=0,j=children.length; i} assetURLs an array of image/sprite sheet urls that you would like loaded * supported. Supported image formats include 'jpeg', 'jpg', 'png', 'gif'. Supported * sprite sheet data formats only include 'JSON' at this time. Supported bitmap font * data formats include 'xml' and 'fnt'. @@ -17834,11 +12152,13 @@ PIXI.VideoTexture.fromUrl = function( videoSrc, scaleMode ) */ PIXI.AssetLoader = function(assetURLs, crossorigin) { + PIXI.EventTarget.call(this); + /** * The array of asset URLs that are going to be loaded * * @property assetURLs - * @type Array(String) + * @type Array */ this.assetURLs = assetURLs; @@ -17861,7 +12181,6 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) 'jpeg': PIXI.ImageLoader, 'png': PIXI.ImageLoader, 'gif': PIXI.ImageLoader, - 'webp': PIXI.ImageLoader, 'json': PIXI.JsonLoader, 'atlas': PIXI.AtlasLoader, 'anim': PIXI.SpineLoader, @@ -17870,8 +12189,6 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) }; }; -PIXI.EventTarget.mixin(PIXI.AssetLoader.prototype); - /** * Fired when an item has loaded * @event onProgress @@ -17886,7 +12203,7 @@ PIXI.EventTarget.mixin(PIXI.AssetLoader.prototype); PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader; /** - * Given a filename, returns its extension. + * Given a filename, returns its extension, wil * * @method _getDataType * @param str {String} the name of the asset @@ -17928,7 +12245,7 @@ PIXI.AssetLoader.prototype.load = function() var scope = this; function onLoad(evt) { - scope.onAssetLoaded(evt.data.content); + scope.onAssetLoaded(evt.loader); } this.loadCount = this.assetURLs.length; @@ -17949,7 +12266,7 @@ PIXI.AssetLoader.prototype.load = function() var loader = new Constructor(fileName, this.crossorigin); - loader.on('loaded', onLoad); + loader.addEventListener('loaded', onLoad); loader.load(); } }; @@ -17963,16 +12280,16 @@ PIXI.AssetLoader.prototype.load = function() PIXI.AssetLoader.prototype.onAssetLoaded = function(loader) { this.loadCount--; - this.emit('onProgress', { content: this, loader: loader }); + this.dispatchEvent({ type: 'onProgress', content: this, loader: loader }); if (this.onProgress) this.onProgress(loader); if (!this.loadCount) { - this.emit('onComplete', { content: this }); + this.dispatchEvent({type: 'onComplete', content: this}); if(this.onComplete) this.onComplete(); } }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -17989,6 +12306,8 @@ PIXI.AssetLoader.prototype.onAssetLoaded = function(loader) * @param crossorigin {Boolean} Whether requests should be treated as crossorigin */ PIXI.JsonLoader = function (url, crossorigin) { + PIXI.EventTarget.call(this); + /** * The url of the bitmap font data * @@ -18027,7 +12346,6 @@ PIXI.JsonLoader = function (url, crossorigin) { // constructor PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader; -PIXI.EventTarget.mixin(PIXI.JsonLoader.prototype); /** * Loads the JSON data @@ -18035,53 +12353,15 @@ PIXI.EventTarget.mixin(PIXI.JsonLoader.prototype); * @method load */ PIXI.JsonLoader.prototype.load = function () { + this.ajaxRequest = new PIXI.AjaxRequest(this.crossorigin); + var scope = this; + this.ajaxRequest.onreadystatechange = function () { + scope.onJSONLoaded(); + }; - if(window.XDomainRequest && this.crossorigin) - { - this.ajaxRequest = new window.XDomainRequest(); - - // XDomainRequest has a few quirks. Occasionally it will abort requests - // A way to avoid this is to make sure ALL callbacks are set even if not used - // More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9 - this.ajaxRequest.timeout = 3000; - - this.ajaxRequest.onerror = this.onError.bind(this); - - this.ajaxRequest.ontimeout = this.onError.bind(this); - - this.ajaxRequest.onprogress = function() {}; - - this.ajaxRequest.onload = this.onJSONLoaded.bind(this); - } - else - { - if (window.XMLHttpRequest) - { - this.ajaxRequest = new window.XMLHttpRequest(); - } - else - { - this.ajaxRequest = new window.ActiveXObject('Microsoft.XMLHTTP'); - } - - this.ajaxRequest.onreadystatechange = this.onReadyStateChanged.bind(this); - } - - this.ajaxRequest.open('GET',this.url,true); - - this.ajaxRequest.send(); -}; - -/** - * Bridge function to be able to use the more reliable onreadystatechange in XMLHttpRequest. - * - * @method onReadyStateChanged - * @private - */ -PIXI.JsonLoader.prototype.onReadyStateChanged = function () { - if (this.ajaxRequest.readyState === 4 && (this.ajaxRequest.status === 200 || window.location.href.indexOf('http') === -1)) { - this.onJSONLoaded(); - } + this.ajaxRequest.open('GET', this.url, true); + if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); + this.ajaxRequest.send(null); }; /** @@ -18091,111 +12371,67 @@ PIXI.JsonLoader.prototype.onReadyStateChanged = function () { * @private */ PIXI.JsonLoader.prototype.onJSONLoaded = function () { + if (this.ajaxRequest.readyState === 4) { + if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1) { + this.json = JSON.parse(this.ajaxRequest.responseText); - if(!this.ajaxRequest.responseText ) - { - this.onError(); - return; - } - - this.json = JSON.parse(this.ajaxRequest.responseText); - - if(this.json.frames && this.json.meta && this.json.meta.image) - { - // sprite sheet - var textureUrl = this.baseUrl + this.json.meta.image; - var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); - var frameData = this.json.frames; - - this.texture = image.texture.baseTexture; - image.addEventListener('loaded', this.onLoaded.bind(this)); - - for (var i in frameData) - { - var rect = frameData[i].frame; - - if (rect) + if(this.json.frames) { - var textureSize = new PIXI.Rectangle(rect.x, rect.y, rect.w, rect.h); - var crop = textureSize.clone(); - var trim = null; + // sprite sheet + var scope = this; + var textureUrl = this.baseUrl + this.json.meta.image; + var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); + var frameData = this.json.frames; - // Check to see if the sprite is trimmed - if (frameData[i].trimmed) - { - var actualSize = frameData[i].sourceSize; - var realSize = frameData[i].spriteSourceSize; - trim = new PIXI.Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h); + this.texture = image.texture.baseTexture; + image.addEventListener('loaded', function() { + scope.onLoaded(); + }); + + for (var i in frameData) { + var rect = frameData[i].frame; + if (rect) { + PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { + x: rect.x, + y: rect.y, + width: rect.w, + height: rect.h + }); + + // check to see ifthe sprite ha been trimmed.. + if (frameData[i].trimmed) { + + var texture = PIXI.TextureCache[i]; + + var actualSize = frameData[i].sourceSize; + var realSize = frameData[i].spriteSourceSize; + + texture.trim = new PIXI.Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h); + } + } } - PIXI.TextureCache[i] = new PIXI.Texture(this.texture, textureSize, crop, trim); + + image.load(); + + } + else if(this.json.bones) + { + // spine animation + var spineJsonParser = new spine.SkeletonJson(); + var skeletonData = spineJsonParser.readSkeletonData(this.json); + PIXI.AnimCache[this.url] = skeletonData; + this.onLoaded(); + } + else + { + this.onLoaded(); } - } - - image.load(); - - } - else if(this.json.bones) - { - /* check if the json was loaded before */ - if (PIXI.AnimCache[this.url]) - { - this.onLoaded(); } else { - /* use a bit of hackery to load the atlas file, here we assume that the .json, .atlas and .png files - * that correspond to the spine file are in the same base URL and that the .json and .atlas files - * have the same name - */ - var atlasPath = this.url.substr(0, this.url.lastIndexOf('.')) + '.atlas'; - var atlasLoader = new PIXI.JsonLoader(atlasPath, this.crossorigin); - // save a copy of the current object for future reference // - var originalLoader = this; - // before loading the file, replace the "onJSONLoaded" function for our own // - atlasLoader.onJSONLoaded = function() - { - // at this point "this" points at the atlasLoader (JsonLoader) instance // - if(!this.ajaxRequest.responseText) - { - this.onError(); // FIXME: hmm, this is funny because we are not responding to errors yet - return; - } - // create a new instance of a spine texture loader for this spine object // - var textureLoader = new PIXI.SpineTextureLoader(this.url.substring(0, this.url.lastIndexOf('/'))); - // create a spine atlas using the loaded text and a spine texture loader instance // - var spineAtlas = new spine.Atlas(this.ajaxRequest.responseText, textureLoader); - // now we use an atlas attachment loader // - var attachmentLoader = new spine.AtlasAttachmentLoader(spineAtlas); - // spine animation - var spineJsonParser = new spine.SkeletonJson(attachmentLoader); - var skeletonData = spineJsonParser.readSkeletonData(originalLoader.json); - PIXI.AnimCache[originalLoader.url] = skeletonData; - originalLoader.spine = skeletonData; - originalLoader.spineAtlas = spineAtlas; - originalLoader.spineAtlasLoader = atlasLoader; - // wait for textures to finish loading if needed - if (textureLoader.loadingCount > 0) - { - textureLoader.addEventListener('loadedBaseTexture', function(evt){ - if (evt.content.content.loadingCount <= 0) - { - originalLoader.onLoaded(); - } - }); - } - else - { - originalLoader.onLoaded(); - } - }; - // start the loading // - atlasLoader.load(); + this.onError(); } } - else - { - this.onLoaded(); - } }; /** @@ -18219,32 +12455,28 @@ PIXI.JsonLoader.prototype.onLoaded = function () { * @private */ PIXI.JsonLoader.prototype.onError = function () { - this.dispatchEvent({ type: 'error', content: this }); -}; - +}; /** * @author Martin Kelm http://mkelm.github.com */ /** - * The atlas file loader is used to load in Texture Atlas data and parse it. When loaded this class will dispatch a 'loaded' event. If loading fails this class will dispatch an 'error' event. - * - * To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format. - * - * It is highly recommended to use texture atlases (also know as 'sprite sheets') as it allowed sprites to be batched and drawn together for highly increased rendering speed. - * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() - * + * The atlas file loader is used to load in Atlas data and parse it + * When loaded this class will dispatch a 'loaded' event + * If loading fails this class will dispatch an 'error' event * @class AtlasLoader - * @uses EventTarget + * @extends EventTarget * @constructor - * @param url {String} The url of the JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin + * @param {String} url the url of the JSON file + * @param {Boolean} crossorigin */ + PIXI.AtlasLoader = function (url, crossorigin) { + PIXI.EventTarget.call(this); this.url = url; this.baseUrl = url.replace(/[^\/]*$/, ''); this.crossorigin = crossorigin; @@ -18255,7 +12487,6 @@ PIXI.AtlasLoader = function (url, crossorigin) { // constructor PIXI.AtlasLoader.constructor = PIXI.AtlasLoader; -PIXI.EventTarget.mixin(PIXI.AtlasLoader.prototype); /** * Starts loading the JSON file @@ -18272,8 +12503,7 @@ PIXI.AtlasLoader.prototype.load = function () { }; /** - * Invoked when the Atlas has fully loaded. Parses the JSON and builds the texture frames. - * + * Invoke when JSON file is loaded * @method onAtlasLoaded * @private */ @@ -18377,7 +12607,7 @@ PIXI.AtlasLoader.prototype.onAtlasLoaded = function () { this.currentImageId = 0; for (j = 0; j < this.images.length; j++) { - this.images[j].on('loaded', selfOnLoaded); + this.images[j].addEventListener('loaded', selfOnLoaded); } this.images[this.currentImageId].load(); @@ -18392,8 +12622,7 @@ PIXI.AtlasLoader.prototype.onAtlasLoaded = function () { }; /** - * Invoked when json file has loaded. - * + * Invoke when json file has loaded * @method onLoaded * @private */ @@ -18403,20 +12632,25 @@ PIXI.AtlasLoader.prototype.onLoaded = function () { this.images[this.currentImageId].load(); } else { this.loaded = true; - this.emit('loaded', { content: this }); + this.dispatchEvent({ + type: 'loaded', + content: this + }); } }; /** - * Invoked when an error occurs. - * + * Invoke when error occured * @method onError * @private */ PIXI.AtlasLoader.prototype.onError = function () { - this.emit('error', { content: this }); + this.dispatchEvent({ + type: 'error', + content: this + }); }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -18437,9 +12671,15 @@ PIXI.AtlasLoader.prototype.onError = function () { * @param crossorigin {Boolean} Whether requests should be treated as crossorigin */ PIXI.SpriteSheetLoader = function (url, crossorigin) { + /* + * i use texture packer to load the assets.. + * http://www.codeandweb.com/texturepacker + * make sure to set the format as 'JSON' + */ + PIXI.EventTarget.call(this); /** - * The url of the atlas data + * The url of the bitmap font data * * @property url * @type String @@ -18483,8 +12723,6 @@ PIXI.SpriteSheetLoader = function (url, crossorigin) { // constructor PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader; -PIXI.EventTarget.mixin(PIXI.SpriteSheetLoader.prototype); - /** * This will begin loading the JSON file * @@ -18493,8 +12731,8 @@ PIXI.EventTarget.mixin(PIXI.SpriteSheetLoader.prototype); PIXI.SpriteSheetLoader.prototype.load = function () { var scope = this; var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.on('loaded', function (event) { - scope.json = event.data.content.json; + jsonLoader.addEventListener('loaded', function (event) { + scope.json = event.content.json; scope.onLoaded(); }); jsonLoader.load(); @@ -18507,18 +12745,19 @@ PIXI.SpriteSheetLoader.prototype.load = function () { * @private */ PIXI.SpriteSheetLoader.prototype.onLoaded = function () { - this.emit('loaded', { + this.dispatchEvent({ + type: 'loaded', content: this }); }; - + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** * The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif') - * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrame() and PIXI.Sprite.fromFrame() + * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() * When loaded this class will dispatch a 'loaded' event * * @class ImageLoader @@ -18529,6 +12768,8 @@ PIXI.SpriteSheetLoader.prototype.onLoaded = function () { */ PIXI.ImageLoader = function(url, crossorigin) { + PIXI.EventTarget.call(this); + /** * The texture being loaded * @@ -18541,9 +12782,6 @@ PIXI.ImageLoader = function(url, crossorigin) * if the image is loaded with loadFramedSpriteSheet * frames will contain the sprite sheet frames * - * @property frames - * @type Array - * @readOnly */ this.frames = []; }; @@ -18551,8 +12789,6 @@ PIXI.ImageLoader = function(url, crossorigin) // constructor PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader; -PIXI.EventTarget.mixin(PIXI.ImageLoader.prototype); - /** * Loads image or takes it from cache * @@ -18562,7 +12798,11 @@ PIXI.ImageLoader.prototype.load = function() { if(!this.texture.baseTexture.hasLoaded) { - this.texture.baseTexture.on('loaded', this.onLoaded.bind(this)); + var scope = this; + this.texture.baseTexture.addEventListener('loaded', function() + { + scope.onLoaded(); + }); } else { @@ -18578,12 +12818,13 @@ PIXI.ImageLoader.prototype.load = function() */ PIXI.ImageLoader.prototype.onLoaded = function() { - this.emit('loaded', { content: this }); + this.dispatchEvent({type: 'loaded', content: this}); }; /** * Loads image and split it to uniform sized frames * + * * @method loadFramedSpriteSheet * @param frameWidth {Number} width of each frame * @param frameHeight {Number} height of each frame @@ -18600,7 +12841,7 @@ PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHei { for (var x=0; x/im, - bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im, - hasLocation = typeof location !== 'undefined' && location.href, - defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), - defaultHostName = hasLocation && location.hostname, - defaultPort = hasLocation && (location.port || undefined), - buildMap = {}, - masterConfig = (module.config && module.config()) || {}; - - text = { - version: '2.0.14', - - strip: function (content) { - //Strips declarations so that external SVG and XML - //documents can be added to a document without worry. Also, if the string - //is an HTML document, only the part inside the body tag is returned. - if (content) { - content = content.replace(xmlRegExp, ""); - var matches = content.match(bodyRegExp); - if (matches) { - content = matches[1]; - } - } else { - content = ""; - } - return content; - }, - - jsEscape: function (content) { - return content.replace(/(['\\])/g, '\\$1') - .replace(/[\f]/g, "\\f") - .replace(/[\b]/g, "\\b") - .replace(/[\n]/g, "\\n") - .replace(/[\t]/g, "\\t") - .replace(/[\r]/g, "\\r") - .replace(/[\u2028]/g, "\\u2028") - .replace(/[\u2029]/g, "\\u2029"); - }, - - createXhr: masterConfig.createXhr || function () { - //Would love to dump the ActiveX crap in here. Need IE 6 to die first. - var xhr, i, progId; - if (typeof XMLHttpRequest !== "undefined") { - return new XMLHttpRequest(); - } else if (typeof ActiveXObject !== "undefined") { - for (i = 0; i < 3; i += 1) { - progId = progIds[i]; - try { - xhr = new ActiveXObject(progId); - } catch (e) {} - - if (xhr) { - progIds = [progId]; // so faster next time - break; - } - } - } - - return xhr; - }, - - /** - * Parses a resource name into its component parts. Resource names - * look like: module/name.ext!strip, where the !strip part is - * optional. - * @param {String} name the resource name - * @returns {Object} with properties "moduleName", "ext" and "strip" - * where strip is a boolean. - */ - parseName: function (name) { - var modName, ext, temp, - strip = false, - index = name.lastIndexOf("."), - isRelative = name.indexOf('./') === 0 || - name.indexOf('../') === 0; - - if (index !== -1 && (!isRelative || index > 1)) { - modName = name.substring(0, index); - ext = name.substring(index + 1); - } else { - modName = name; - } - - temp = ext || modName; - index = temp.indexOf("!"); - if (index !== -1) { - //Pull off the strip arg. - strip = temp.substring(index + 1) === "strip"; - temp = temp.substring(0, index); - if (ext) { - ext = temp; - } else { - modName = temp; - } - } - - return { - moduleName: modName, - ext: ext, - strip: strip - }; - }, - - xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, - - /** - * Is an URL on another domain. Only works for browser use, returns - * false in non-browser environments. Only used to know if an - * optimized .js version of a text resource should be loaded - * instead. - * @param {String} url - * @returns Boolean - */ - useXhr: function (url, protocol, hostname, port) { - var uProtocol, uHostName, uPort, - match = text.xdRegExp.exec(url); - if (!match) { - return true; - } - uProtocol = match[2]; - uHostName = match[3]; - - uHostName = uHostName.split(':'); - uPort = uHostName[1]; - uHostName = uHostName[0]; - - return (!uProtocol || uProtocol === protocol) && - (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && - ((!uPort && !uHostName) || uPort === port); - }, - - finishLoad: function (name, strip, content, onLoad) { - content = strip ? text.strip(content) : content; - if (masterConfig.isBuild) { - buildMap[name] = content; - } - onLoad(content); - }, - - load: function (name, req, onLoad, config) { - //Name has format: some.module.filext!strip - //The strip part is optional. - //if strip is present, then that means only get the string contents - //inside a body tag in an HTML string. For XML/SVG content it means - //removing the declarations so the content can be inserted - //into the current doc without problems. - - // Do not bother with the work if a build and text will - // not be inlined. - if (config && config.isBuild && !config.inlineText) { - onLoad(); - return; - } - - masterConfig.isBuild = config && config.isBuild; - - var parsed = text.parseName(name), - nonStripName = parsed.moduleName + - (parsed.ext ? '.' + parsed.ext : ''), - url = req.toUrl(nonStripName), - useXhr = (masterConfig.useXhr) || - text.useXhr; - - // Do not load if it is an empty: url - if (url.indexOf('empty:') === 0) { - onLoad(); - return; - } - - //Load the text. Use XHR if possible and in a browser. - if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { - text.get(url, function (content) { - text.finishLoad(name, parsed.strip, content, onLoad); - }, function (err) { - if (onLoad.error) { - onLoad.error(err); - } - }); - } else { - //Need to fetch the resource across domains. Assume - //the resource has been optimized into a JS module. Fetch - //by the module name + extension, but do not include the - //!strip part to avoid file system issues. - req([nonStripName], function (content) { - text.finishLoad(parsed.moduleName + '.' + parsed.ext, - parsed.strip, content, onLoad); - }); - } - }, - - write: function (pluginName, moduleName, write, config) { - if (buildMap.hasOwnProperty(moduleName)) { - var content = text.jsEscape(buildMap[moduleName]); - write.asModule(pluginName + "!" + moduleName, - "define(function () { return '" + - content + - "';});\n"); - } - }, - - writeFile: function (pluginName, moduleName, req, write, config) { - var parsed = text.parseName(moduleName), - extPart = parsed.ext ? '.' + parsed.ext : '', - nonStripName = parsed.moduleName + extPart, - //Use a '.js' file name so that it indicates it is a - //script that can be loaded across domains. - fileName = req.toUrl(parsed.moduleName + extPart) + '.js'; - - //Leverage own load() method to load plugin value, but only - //write out values that do not have the strip argument, - //to avoid any potential issues with ! in file names. - text.load(nonStripName, req, function (value) { - //Use own write() method to construct full module value. - //But need to create shell that translates writeFile's - //write() to the right interface. - var textWrite = function (contents) { - return write(fileName, contents); - }; - textWrite.asModule = function (moduleName, contents) { - return write.asModule(moduleName, fileName, contents); - }; - - text.write(pluginName, nonStripName, textWrite, config); - }, config); - } - }; - - if (masterConfig.env === 'node' || (!masterConfig.env && - typeof process !== "undefined" && - process.versions && - !!process.versions.node && - !process.versions['node-webkit'] && - !process.versions['atom-shell'])) { - //Using special require.nodeRequire, something added by r.js. - fs = require.nodeRequire('fs'); - - text.get = function (url, callback, errback) { - try { - var file = fs.readFileSync(url, 'utf8'); - //Remove BOM (Byte Mark Order) from utf8 files if it is there. - if (file[0] === '\uFEFF') { - file = file.substring(1); - } - callback(file); - } catch (e) { - if (errback) { - errback(e); - } - } - }; - } else if (masterConfig.env === 'xhr' || (!masterConfig.env && - text.createXhr())) { - text.get = function (url, callback, errback, headers) { - var xhr = text.createXhr(), header; - xhr.open('GET', url, true); - - //Allow plugins direct access to xhr headers - if (headers) { - for (header in headers) { - if (headers.hasOwnProperty(header)) { - xhr.setRequestHeader(header.toLowerCase(), headers[header]); - } - } - } - - //Allow overrides specified in config - if (masterConfig.onXhr) { - masterConfig.onXhr(xhr, url); - } - - xhr.onreadystatechange = function (evt) { - var status, err; - //Do not explicitly handle errors, those should be - //visible via console output in the browser. - if (xhr.readyState === 4) { - status = xhr.status || 0; - if (status > 399 && status < 600) { - //An http 4xx or 5xx error. Signal an error. - err = new Error(url + ' HTTP status: ' + status); - err.xhr = xhr; - if (errback) { - errback(err); - } - } else { - callback(xhr.responseText); - } - - if (masterConfig.onXhrComplete) { - masterConfig.onXhrComplete(xhr, url); - } - } - }; - xhr.send(null); - }; - } else if (masterConfig.env === 'rhino' || (!masterConfig.env && - typeof Packages !== 'undefined' && typeof java !== 'undefined')) { - //Why Java, why is this so awkward? - text.get = function (url, callback) { - var stringBuffer, line, - encoding = "utf-8", - file = new java.io.File(url), - lineSeparator = java.lang.System.getProperty("line.separator"), - input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), - content = ''; - try { - stringBuffer = new java.lang.StringBuffer(); - line = input.readLine(); - - // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 - // http://www.unicode.org/faq/utf_bom.html - - // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 - if (line && line.length() && line.charAt(0) === 0xfeff) { - // Eat the BOM, since we've already found the encoding on this file, - // and we plan to concatenating this buffer with others; the BOM should - // only appear at the top of a file. - line = line.substring(1); - } - - if (line !== null) { - stringBuffer.append(line); - } - - while ((line = input.readLine()) !== null) { - stringBuffer.append(lineSeparator); - stringBuffer.append(line); - } - //Make sure we return a JavaScript string and not a Java string. - content = String(stringBuffer.toString()); //String - } finally { - input.close(); - } - callback(content); - }; - } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env && - typeof Components !== 'undefined' && Components.classes && - Components.interfaces)) { - //Avert your gaze! - Cc = Components.classes; - Ci = Components.interfaces; - Components.utils['import']('resource://gre/modules/FileUtils.jsm'); - xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc); - - text.get = function (url, callback) { - var inStream, convertStream, fileObj, - readData = {}; - - if (xpcIsWindows) { - url = url.replace(/\//g, '\\'); - } - - fileObj = new FileUtils.File(url); - - //XPCOM, you so crazy - try { - inStream = Cc['@mozilla.org/network/file-input-stream;1'] - .createInstance(Ci.nsIFileInputStream); - inStream.init(fileObj, 1, 0, false); - - convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] - .createInstance(Ci.nsIConverterInputStream); - convertStream.init(inStream, "utf-8", inStream.available(), - Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); - - convertStream.readString(inStream.available(), readData); - convertStream.close(); - inStream.close(); - callback(readData.value); - } catch (e) { - throw new Error((fileObj && fileObj.path || '') + ': ' + e); - } - }; - } - return text; -}); \ No newline at end of file diff --git a/app/Lib/Vendor/RubeLoader.js b/app/Lib/Vendor/RubeLoader.js index b1f3b83..49674c3 100644 --- a/app/Lib/Vendor/RubeLoader.js +++ b/app/Lib/Vendor/RubeLoader.js @@ -152,7 +152,8 @@ function (Box2D) { if ( bodyJson.hasOwnProperty('linearVelocity') && bodyJson.linearVelocity instanceof Object ) bd.linearVelocity.SetV( bodyJson.linearVelocity ); if ( bodyJson.hasOwnProperty('position') && bodyJson.position instanceof Object ) - bd.position.SetV( this.getVectorValue(bodyJson.position) ); + bodyJson.position.y *= -1; + bd.position.SetV( bodyJson.position ); if ( bodyJson.hasOwnProperty('awake') ) bd.awake = bodyJson.awake; else @@ -168,7 +169,6 @@ function (Box2D) { body.name = bodyJson.name; if ( bodyJson.hasOwnProperty('customProperties') ) body.customProperties = bodyJson.customProperties; - return body; } @@ -231,7 +231,8 @@ function (Box2D) { RubeLoader.prototype.getVectorValue = function (val) { if ( val instanceof Object ) { - return { x: val.x, y: val.y * -1 }; + val.y *= -1; + return val; } else { return { x:0, y:0 }; } @@ -426,7 +427,7 @@ function (Box2D) { var scene = { bodies: loadedBodies, - joints: loadedJoints + // joints: loadedJoints }; return scene; diff --git a/app/Lib/Vendor/Screenfull.js b/app/Lib/Vendor/Screenfull.js index 227db38..ad4eb40 100644 --- a/app/Lib/Vendor/Screenfull.js +++ b/app/Lib/Vendor/Screenfull.js @@ -1,3 +1,3 @@ -define(["screenfull"], function() { +define(["/screenfull.js"], function() { return screenfull; }); \ No newline at end of file diff --git a/app/Lib/Vendor/SocketIO.js b/app/Lib/Vendor/SocketIO.js index e7e0089..062fb3c 100755 --- a/app/Lib/Vendor/SocketIO.js +++ b/app/Lib/Vendor/SocketIO.js @@ -1,3 +1,3 @@ -define(["socketio"], function(io) { +define(["/socket.io/socket.io.js"], function() { return io; -}); +}); \ No newline at end of file diff --git a/app/Lib/Vendor/Stats.js b/app/Lib/Vendor/Stats.js index 06cfb43..a66f82b 100755 --- a/app/Lib/Vendor/Stats.js +++ b/app/Lib/Vendor/Stats.js @@ -1,153 +1,9 @@ define(function() { - /** - * @author mrdoob / http://mrdoob.com/ - */ - - var Stats = function () { - - var startTime = Date.now(), prevTime = startTime; - var ms = 0, msMin = Infinity, msMax = 0; - var fps = 0, fpsMin = Infinity, fpsMax = 0; - var frames = 0, mode = 0; - - var container = document.createElement( 'div' ); - container.id = 'stats'; - container.addEventListener( 'mousedown', function ( event ) { event.preventDefault(); setMode( ++ mode % 2 ) }, false ); - container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer'; - - var fpsDiv = document.createElement( 'div' ); - fpsDiv.id = 'fps'; - fpsDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#002'; - container.appendChild( fpsDiv ); - - var fpsText = document.createElement( 'div' ); - fpsText.id = 'fpsText'; - fpsText.style.cssText = 'color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; - fpsText.innerHTML = 'FPS'; - fpsDiv.appendChild( fpsText ); - - var fpsGraph = document.createElement( 'div' ); - fpsGraph.id = 'fpsGraph'; - fpsGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0ff'; - fpsDiv.appendChild( fpsGraph ); - - while ( fpsGraph.children.length < 74 ) { - - var bar = document.createElement( 'span' ); - bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#113'; - fpsGraph.appendChild( bar ); - - } - - var msDiv = document.createElement( 'div' ); - msDiv.id = 'ms'; - msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;display:none'; - container.appendChild( msDiv ); - - var msText = document.createElement( 'div' ); - msText.id = 'msText'; - msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; - msText.innerHTML = 'MS'; - msDiv.appendChild( msText ); - - var msGraph = document.createElement( 'div' ); - msGraph.id = 'msGraph'; - msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0'; - msDiv.appendChild( msGraph ); - - while ( msGraph.children.length < 74 ) { - - var bar = document.createElement( 'span' ); - bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131'; - msGraph.appendChild( bar ); - - } - - var setMode = function ( value ) { - - mode = value; - - switch ( mode ) { - - case 0: - fpsDiv.style.display = 'block'; - msDiv.style.display = 'none'; - break; - case 1: - fpsDiv.style.display = 'none'; - msDiv.style.display = 'block'; - break; - } - - }; - - var updateGraph = function ( dom, value ) { - - var child = dom.appendChild( dom.firstChild ); - child.style.height = value + 'px'; - - }; - - return { - - REVISION: 12, - - domElement: container, - - setMode: setMode, - - begin: function () { - - startTime = Date.now(); - - }, - - end: function () { - - var time = Date.now(); - - ms = time - startTime; - msMin = Math.min( msMin, ms ); - msMax = Math.max( msMax, ms ); - - msText.textContent = ms + ' MS (' + msMin + '-' + msMax + ')'; - updateGraph( msGraph, Math.min( 30, 30 - ( ms / 200 ) * 30 ) ); - - frames ++; - - if ( time > prevTime + 1000 ) { - - fps = Math.round( ( frames * 1000 ) / ( time - prevTime ) ); - fpsMin = Math.min( fpsMin, fps ); - fpsMax = Math.max( fpsMax, fps ); - - fpsText.textContent = fps + ' FPS (' + fpsMin + '-' + fpsMax + ')'; - updateGraph( fpsGraph, Math.min( 30, 30 - ( fps / 100 ) * 30 ) ); - - prevTime = time; - frames = 0; - - } - - return time; - - }, - - update: function () { - - startTime = this.end(); - - } - - } - - }; - - if ( typeof module === 'object' ) { - - module.exports = Stats; - - } + var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; + i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); + k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= + "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= + a+"px",m=b,r=0);return b},update:function(){l=this.end()}}}; return Stats; }); diff --git a/app/Lib/Vendor/src/pixi/InteractionData.js b/app/Lib/Vendor/src/pixi/InteractionData.js deleted file mode 100644 index b0d8a6a..0000000 --- a/app/Lib/Vendor/src/pixi/InteractionData.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * Holds all information related to an Interaction event - * - * @class InteractionData - * @constructor - */ -PIXI.InteractionData = function() -{ - /** - * This point stores the global coords of where the touch/mouse event happened - * - * @property global - * @type Point - */ - this.global = new PIXI.Point(); - - /** - * The target Sprite that was interacted with - * - * @property target - * @type Sprite - */ - this.target = null; - - /** - * When passed to an event handler, this will be the original DOM Event that was captured - * - * @property originalEvent - * @type Event - */ - this.originalEvent = null; -}; - -/** - * This will return the local coordinates of the specified displayObject for this InteractionData - * - * @method getLocalPosition - * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off - * @param [point] {Point} A Point object in which to store the value, optional (otherwise will create a new point) - * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject - */ -PIXI.InteractionData.prototype.getLocalPosition = function(displayObject, point) -{ - var worldTransform = displayObject.worldTransform; - var global = this.global; - - // do a cheeky transform to get the mouse coords; - var a00 = worldTransform.a, a01 = worldTransform.c, a02 = worldTransform.tx, - a10 = worldTransform.b, a11 = worldTransform.d, a12 = worldTransform.ty, - id = 1 / (a00 * a11 + a01 * -a10); - - point = point || new PIXI.Point(); - - point.x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; - point.y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - - // set the mouse coords... - return point; -}; - -// constructor -PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; diff --git a/app/Lib/Vendor/src/pixi/InteractionManager.js b/app/Lib/Vendor/src/pixi/InteractionManager.js deleted file mode 100644 index 2d08d6c..0000000 --- a/app/Lib/Vendor/src/pixi/InteractionManager.js +++ /dev/null @@ -1,870 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - /** - * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive - * if its interactive parameter is set to true - * This manager also supports multitouch. - * - * @class InteractionManager - * @constructor - * @param stage {Stage} The stage to handle interactions - */ -PIXI.InteractionManager = function(stage) -{ - /** - * A reference to the stage - * - * @property stage - * @type Stage - */ - this.stage = stage; - - /** - * The mouse data - * - * @property mouse - * @type InteractionData - */ - this.mouse = new PIXI.InteractionData(); - - /** - * An object that stores current touches (InteractionData) by id reference - * - * @property touches - * @type Object - */ - this.touches = {}; - - /** - * @property tempPoint - * @type Point - * @private - */ - this.tempPoint = new PIXI.Point(); - - /** - * @property mouseoverEnabled - * @type Boolean - * @default - */ - this.mouseoverEnabled = true; - - /** - * Tiny little interactiveData pool ! - * - * @property pool - * @type Array - */ - this.pool = []; - - /** - * An array containing all the iterative items from the our interactive tree - * @property interactiveItems - * @type Array - * @private - */ - this.interactiveItems = []; - - /** - * Our canvas - * @property interactionDOMElement - * @type HTMLCanvasElement - * @private - */ - this.interactionDOMElement = null; - - //this will make it so that you don't have to call bind all the time - - /** - * @property onMouseMove - * @type Function - */ - this.onMouseMove = this.onMouseMove.bind( this ); - - /** - * @property onMouseDown - * @type Function - */ - this.onMouseDown = this.onMouseDown.bind(this); - - /** - * @property onMouseOut - * @type Function - */ - this.onMouseOut = this.onMouseOut.bind(this); - - /** - * @property onMouseUp - * @type Function - */ - this.onMouseUp = this.onMouseUp.bind(this); - - /** - * @property onTouchStart - * @type Function - */ - this.onTouchStart = this.onTouchStart.bind(this); - - /** - * @property onTouchEnd - * @type Function - */ - this.onTouchEnd = this.onTouchEnd.bind(this); - - /** - * @property onTouchMove - * @type Function - */ - this.onTouchMove = this.onTouchMove.bind(this); - - /** - * @property last - * @type Number - */ - this.last = 0; - - /** - * The css style of the cursor that is being used - * @property currentCursorStyle - * @type String - */ - this.currentCursorStyle = 'inherit'; - - /** - * Is set to true when the mouse is moved out of the canvas - * @property mouseOut - * @type Boolean - */ - this.mouseOut = false; - - /** - * @property resolution - * @type Number - */ - this.resolution = 1; - - // used for hit testing - this._tempPoint = new PIXI.Point(); -}; - -// constructor -PIXI.InteractionManager.prototype.constructor = PIXI.InteractionManager; - -/** - * Collects an interactive sprite recursively to have their interactions managed - * - * @method collectInteractiveSprite - * @param displayObject {DisplayObject} the displayObject to collect - * @param iParent {DisplayObject} the display object's parent - * @private - */ -PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObject, iParent) -{ - var children = displayObject.children; - var length = children.length; - - // make an interaction tree... {item.__interactiveParent} - for (var i = length - 1; i >= 0; i--) - { - var child = children[i]; - - // push all interactive bits - if (child._interactive) - { - iParent.interactiveChildren = true; - //child.__iParent = iParent; - this.interactiveItems.push(child); - - if (child.children.length > 0) { - this.collectInteractiveSprite(child, child); - } - } - else - { - child.__iParent = null; - if (child.children.length > 0) - { - this.collectInteractiveSprite(child, iParent); - } - } - - } -}; - -/** - * Sets the target for event delegation - * - * @method setTarget - * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to - * @private - */ -PIXI.InteractionManager.prototype.setTarget = function(target) -{ - this.target = target; - this.resolution = target.resolution; - - // Check if the dom element has been set. If it has don't do anything. - if (this.interactionDOMElement !== null) return; - - this.setTargetDomElement (target.view); -}; - -/** - * Sets the DOM element which will receive mouse/touch events. This is useful for when you have other DOM - * elements on top of the renderers Canvas element. With this you'll be able to delegate another DOM element - * to receive those events - * - * @method setTargetDomElement - * @param domElement {DOMElement} the DOM element which will receive mouse and touch events - * @private - */ -PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) -{ - this.removeEvents(); - - if (window.navigator.msPointerEnabled) - { - // time to remove some of that zoom in ja.. - domElement.style['-ms-content-zooming'] = 'none'; - domElement.style['-ms-touch-action'] = 'none'; - } - - this.interactionDOMElement = domElement; - - domElement.addEventListener('mousemove', this.onMouseMove, true); - domElement.addEventListener('mousedown', this.onMouseDown, true); - domElement.addEventListener('mouseout', this.onMouseOut, true); - - // aint no multi touch just yet! - domElement.addEventListener('touchstart', this.onTouchStart, true); - domElement.addEventListener('touchend', this.onTouchEnd, true); - domElement.addEventListener('touchmove', this.onTouchMove, true); - - window.addEventListener('mouseup', this.onMouseUp, true); -}; - -/** - * @method removeEvents - * @private - */ -PIXI.InteractionManager.prototype.removeEvents = function() -{ - if (!this.interactionDOMElement) return; - - this.interactionDOMElement.style['-ms-content-zooming'] = ''; - this.interactionDOMElement.style['-ms-touch-action'] = ''; - - this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true); - this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true); - this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true); - - // aint no multi touch just yet! - this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true); - this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true); - this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true); - - this.interactionDOMElement = null; - - window.removeEventListener('mouseup', this.onMouseUp, true); -}; - -/** - * updates the state of interactive objects - * - * @method update - * @private - */ -PIXI.InteractionManager.prototype.update = function() -{ - if (!this.target) return; - - // frequency of 30fps?? - var now = Date.now(); - var diff = now - this.last; - diff = (diff * PIXI.INTERACTION_FREQUENCY ) / 1000; - if (diff < 1) return; - this.last = now; - - var i = 0; - - // ok.. so mouse events?? - // yes for now :) - // OPTIMISE - how often to check?? - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - // loop through interactive objects! - var length = this.interactiveItems.length; - var cursor = 'inherit'; - var over = false; - - for (i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - // OPTIMISATION - only calculate every time if the mousemove function exists.. - // OK so.. does the object have any other interactive functions? - // hit-test the clip! - // if (item.mouseover || item.mouseout || item.buttonMode) - // { - // ok so there are some functions so lets hit test it.. - item.__hit = this.hitTest(item, this.mouse); - this.mouse.target = item; - // ok so deal with interactions.. - // looks like there was a hit! - if (item.__hit && !over) - { - if (item.buttonMode) cursor = item.defaultCursor; - - if (!item.interactiveChildren) - { - over = true; - } - - if (!item.__isOver) - { - if (item.mouseover) - { - item.mouseover (this.mouse); - } - item.__isOver = true; - } - } - else - { - if (item.__isOver) - { - // roll out! - if (item.mouseout) - { - item.mouseout (this.mouse); - } - item.__isOver = false; - } - } - } - - if (this.currentCursorStyle !== cursor) - { - this.currentCursorStyle = cursor; - this.interactionDOMElement.style.cursor = cursor; - } -}; - -/** - * @method rebuildInteractiveGraph - * @private - */ -PIXI.InteractionManager.prototype.rebuildInteractiveGraph = function() -{ - this.dirty = false; - - var len = this.interactiveItems.length; - - for (var i = 0; i < len; i++) { - this.interactiveItems[i].interactiveChildren = false; - } - - this.interactiveItems = []; - - if (this.stage.interactive) - { - this.interactiveItems.push(this.stage); - } - - // Go through and collect all the objects that are interactive.. - this.collectInteractiveSprite(this.stage, this.stage); -}; - -/** - * Is called when the mouse moves across the renderer element - * - * @method onMouseMove - * @param event {Event} The DOM event of the mouse moving - * @private - */ -PIXI.InteractionManager.prototype.onMouseMove = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - - // TODO optimize by not check EVERY TIME! maybe half as often? // - var rect = this.interactionDOMElement.getBoundingClientRect(); - - this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width) / this.resolution; - this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height) / this.resolution; - - var length = this.interactiveItems.length; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - // Call the function! - if (item.mousemove) - { - item.mousemove(this.mouse); - } - } -}; - -/** - * Is called when the mouse button is pressed down on the renderer element - * - * @method onMouseDown - * @param event {Event} The DOM event of a mouse button being pressed down - * @private - */ -PIXI.InteractionManager.prototype.onMouseDown = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - - if (PIXI.AUTO_PREVENT_DEFAULT) - { - this.mouse.originalEvent.preventDefault(); - } - - // loop through interaction tree... - // hit test each item! -> - // get interactive items under point?? - //stage.__i - var length = this.interactiveItems.length; - - var e = this.mouse.originalEvent; - var isRightButton = e.button === 2 || e.which === 3; - var downFunction = isRightButton ? 'rightdown' : 'mousedown'; - var clickFunction = isRightButton ? 'rightclick' : 'click'; - var buttonIsDown = isRightButton ? '__rightIsDown' : '__mouseIsDown'; - var isDown = isRightButton ? '__isRightDown' : '__isDown'; - - // while - // hit test - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if (item[downFunction] || item[clickFunction]) - { - item[buttonIsDown] = true; - item.__hit = this.hitTest(item, this.mouse); - - if (item.__hit) - { - //call the function! - if (item[downFunction]) - { - item[downFunction](this.mouse); - } - item[isDown] = true; - - // just the one! - if (!item.interactiveChildren) break; - } - } - } -}; - -/** - * Is called when the mouse is moved out of the renderer element - * - * @method onMouseOut - * @param event {Event} The DOM event of a mouse being moved out - * @private - */ -PIXI.InteractionManager.prototype.onMouseOut = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - - var length = this.interactiveItems.length; - - this.interactionDOMElement.style.cursor = 'inherit'; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - if (item.__isOver) - { - this.mouse.target = item; - if (item.mouseout) - { - item.mouseout(this.mouse); - } - item.__isOver = false; - } - } - - this.mouseOut = true; - - // move the mouse to an impossible position - this.mouse.global.x = -10000; - this.mouse.global.y = -10000; -}; - -/** - * Is called when the mouse button is released on the renderer element - * - * @method onMouseUp - * @param event {Event} The DOM event of a mouse button being released - * @private - */ -PIXI.InteractionManager.prototype.onMouseUp = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - this.mouse.originalEvent = event; - - var length = this.interactiveItems.length; - var up = false; - - var e = this.mouse.originalEvent; - var isRightButton = e.button === 2 || e.which === 3; - - var upFunction = isRightButton ? 'rightup' : 'mouseup'; - var clickFunction = isRightButton ? 'rightclick' : 'click'; - var upOutsideFunction = isRightButton ? 'rightupoutside' : 'mouseupoutside'; - var isDown = isRightButton ? '__isRightDown' : '__isDown'; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if (item[clickFunction] || item[upFunction] || item[upOutsideFunction]) - { - item.__hit = this.hitTest(item, this.mouse); - - if (item.__hit && !up) - { - //call the function! - if (item[upFunction]) - { - item[upFunction](this.mouse); - } - if (item[isDown]) - { - if (item[clickFunction]) - { - item[clickFunction](this.mouse); - } - } - - if (!item.interactiveChildren) - { - up = true; - } - } - else - { - if (item[isDown]) - { - if (item[upOutsideFunction]) item[upOutsideFunction](this.mouse); - } - } - - item[isDown] = false; - } - } -}; - -/** - * Tests if the current mouse coordinates hit a sprite - * - * @method hitTest - * @param item {DisplayObject} The displayObject to test for a hit - * @param interactionData {InteractionData} The interactionData object to update in the case there is a hit - * @private - */ -PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) -{ - var global = interactionData.global; - - if (!item.worldVisible) - { - return false; - } - - // map the global point to local space. - item.worldTransform.applyInverse(global, this._tempPoint); - - var x = this._tempPoint.x, - y = this._tempPoint.y, - i; - - interactionData.target = item; - - //a sprite or display object with a hit area defined - if (item.hitArea && item.hitArea.contains) - { - return item.hitArea.contains(x, y); - } - // a sprite with no hitarea defined - else if(item instanceof PIXI.Sprite) - { - var width = item.texture.frame.width; - var height = item.texture.frame.height; - var x1 = -width * item.anchor.x; - var y1; - - if (x > x1 && x < x1 + width) - { - y1 = -height * item.anchor.y; - - if (y > y1 && y < y1 + height) - { - // set the target property if a hit is true! - return true; - } - } - } - else if(item instanceof PIXI.Graphics) - { - var graphicsData = item.graphicsData; - for (i = 0; i < graphicsData.length; i++) - { - var data = graphicsData[i]; - if(!data.fill)continue; - - // only deal with fills.. - if(data.shape) - { - if(data.shape.contains(x, y)) - { - //interactionData.target = item; - return true; - } - } - } - } - - var length = item.children.length; - - for (i = 0; i < length; i++) - { - var tempItem = item.children[i]; - var hit = this.hitTest(tempItem, interactionData); - if (hit) - { - // hmm.. TODO SET CORRECT TARGET? - interactionData.target = item; - return true; - } - } - return false; -}; - -/** - * Is called when a touch is moved across the renderer element - * - * @method onTouchMove - * @param event {Event} The DOM event of a touch moving across the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchMove = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - var touchData; - var i = 0; - - for (i = 0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - touchData = this.touches[touchEvent.identifier]; - touchData.originalEvent = event; - - // update the touch position - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - - for (var j = 0; j < this.interactiveItems.length; j++) - { - var item = this.interactiveItems[j]; - if (item.touchmove && item.__touchData && item.__touchData[touchEvent.identifier]) - { - item.touchmove(touchData); - } - } - } -}; - -/** - * Is called when a touch is started on the renderer element - * - * @method onTouchStart - * @param event {Event} The DOM event of a touch starting on the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchStart = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - var rect = this.interactionDOMElement.getBoundingClientRect(); - - if (PIXI.AUTO_PREVENT_DEFAULT) - { - event.preventDefault(); - } - - var changedTouches = event.changedTouches; - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - - var touchData = this.pool.pop(); - if (!touchData) - { - touchData = new PIXI.InteractionData(); - } - - touchData.originalEvent = event; - - this.touches[touchEvent.identifier] = touchData; - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - - var length = this.interactiveItems.length; - - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - - if (item.touchstart || item.tap) - { - item.__hit = this.hitTest(item, touchData); - - if (item.__hit) - { - //call the function! - if (item.touchstart)item.touchstart(touchData); - item.__isDown = true; - item.__touchData = item.__touchData || {}; - item.__touchData[touchEvent.identifier] = touchData; - - if (!item.interactiveChildren) break; - } - } - } - } -}; - -/** - * Is called when a touch is ended on the renderer element - * - * @method onTouchEnd - * @param event {Event} The DOM event of a touch ending on the renderer view - * @private - */ -PIXI.InteractionManager.prototype.onTouchEnd = function(event) -{ - if (this.dirty) - { - this.rebuildInteractiveGraph(); - } - - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - var touchData = this.touches[touchEvent.identifier]; - var up = false; - touchData.global.x = ( (touchEvent.clientX - rect.left) * (this.target.width / rect.width) ) / this.resolution; - touchData.global.y = ( (touchEvent.clientY - rect.top) * (this.target.height / rect.height) ) / this.resolution; - if (navigator.isCocoonJS && !rect.left && !rect.top && !event.target.style.width && !event.target.style.height) - { - //Support for CocoonJS fullscreen scale modes - touchData.global.x = touchEvent.clientX; - touchData.global.y = touchEvent.clientY; - } - - var length = this.interactiveItems.length; - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - - if (item.__touchData && item.__touchData[touchEvent.identifier]) - { - - item.__hit = this.hitTest(item, item.__touchData[touchEvent.identifier]); - - // so this one WAS down... - touchData.originalEvent = event; - // hitTest?? - - if (item.touchend || item.tap) - { - if (item.__hit && !up) - { - if (item.touchend) - { - item.touchend(touchData); - } - if (item.__isDown && item.tap) - { - item.tap(touchData); - } - if (!item.interactiveChildren) - { - up = true; - } - } - else - { - if (item.__isDown && item.touchendoutside) - { - item.touchendoutside(touchData); - } - } - - item.__isDown = false; - } - - item.__touchData[touchEvent.identifier] = null; - } - } - // remove the touch.. - this.pool.push(touchData); - this.touches[touchEvent.identifier] = null; - } -}; diff --git a/app/Lib/Vendor/src/pixi/Intro.js b/app/Lib/Vendor/src/pixi/Intro.js deleted file mode 100644 index 07d01da..0000000 --- a/app/Lib/Vendor/src/pixi/Intro.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -(function(){ - - var root = this; diff --git a/app/Lib/Vendor/src/pixi/Outro.js b/app/Lib/Vendor/src/pixi/Outro.js deleted file mode 100644 index bf38bbc..0000000 --- a/app/Lib/Vendor/src/pixi/Outro.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - if (typeof exports !== 'undefined') { - if (typeof module !== 'undefined' && module.exports) { - exports = module.exports = PIXI; - } - exports.PIXI = PIXI; - } else if (typeof define !== 'undefined' && define.amd) { - define(PIXI); - } else { - root.PIXI = PIXI; - } -}).call(this); \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/Pixi.js b/app/Lib/Vendor/src/pixi/Pixi.js deleted file mode 100644 index 52f001c..0000000 --- a/app/Lib/Vendor/src/pixi/Pixi.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The [pixi.js](http://www.pixijs.com/) module/namespace. - * - * @module PIXI - */ - -/** - * Namespace-class for [pixi.js](http://www.pixijs.com/). - * - * Contains assorted static properties and enumerations. - * - * @class PIXI - * @static - */ -var PIXI = PIXI || {}; - -/** - * @property {Number} WEBGL_RENDERER - * @protected - * @static - */ -PIXI.WEBGL_RENDERER = 0; -/** - * @property {Number} CANVAS_RENDERER - * @protected - * @static - */ -PIXI.CANVAS_RENDERER = 1; - -/** - * Version of pixi that is loaded. - * @property {String} VERSION - * @static - */ -PIXI.VERSION = "v2.2.0"; - -/** - * Various blend modes supported by pixi. IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes. - * @property {Object} blendModes - * @property {Number} blendModes.NORMAL - * @property {Number} blendModes.ADD - * @property {Number} blendModes.MULTIPLY - * @property {Number} blendModes.SCREEN - * @property {Number} blendModes.OVERLAY - * @property {Number} blendModes.DARKEN - * @property {Number} blendModes.LIGHTEN - * @property {Number} blendModes.COLOR_DODGE - * @property {Number} blendModes.COLOR_BURN - * @property {Number} blendModes.HARD_LIGHT - * @property {Number} blendModes.SOFT_LIGHT - * @property {Number} blendModes.DIFFERENCE - * @property {Number} blendModes.EXCLUSION - * @property {Number} blendModes.HUE - * @property {Number} blendModes.SATURATION - * @property {Number} blendModes.COLOR - * @property {Number} blendModes.LUMINOSITY - * @static - */ -PIXI.blendModes = { - NORMAL:0, - ADD:1, - MULTIPLY:2, - SCREEN:3, - OVERLAY:4, - DARKEN:5, - LIGHTEN:6, - COLOR_DODGE:7, - COLOR_BURN:8, - HARD_LIGHT:9, - SOFT_LIGHT:10, - DIFFERENCE:11, - EXCLUSION:12, - HUE:13, - SATURATION:14, - COLOR:15, - LUMINOSITY:16 -}; - -/** - * The scale modes that are supported by pixi. - * - * The DEFAULT scale mode affects the default scaling mode of future operations. - * It can be re-assigned to either LINEAR or NEAREST, depending upon suitability. - * - * @property {Object} scaleModes - * @property {Number} scaleModes.DEFAULT=LINEAR - * @property {Number} scaleModes.LINEAR Smooth scaling - * @property {Number} scaleModes.NEAREST Pixelating scaling - * @static - */ -PIXI.scaleModes = { - DEFAULT:0, - LINEAR:0, - NEAREST:1 -}; - -// used to create uids for various pixi objects.. -PIXI._UID = 0; - -if(typeof(Float32Array) != 'undefined') -{ - PIXI.Float32Array = Float32Array; - PIXI.Uint16Array = Uint16Array; - - // Uint32Array and ArrayBuffer only used by WebGL renderer - // We can suppose that if WebGL is supported then typed arrays are supported too - // as they predate WebGL support for all browsers: - // see typed arrays support: http://caniuse.com/#search=TypedArrays - // see WebGL support: http://caniuse.com/#search=WebGL - PIXI.Uint32Array = Uint32Array; - PIXI.ArrayBuffer = ArrayBuffer; -} -else -{ - PIXI.Float32Array = Array; - PIXI.Uint16Array = Array; -} - -// interaction frequency -PIXI.INTERACTION_FREQUENCY = 30; -PIXI.AUTO_PREVENT_DEFAULT = true; - -/** - * @property {Number} PI_2 - * @static - */ -PIXI.PI_2 = Math.PI * 2; - -/** - * @property {Number} RAD_TO_DEG - * @static - */ -PIXI.RAD_TO_DEG = 180 / Math.PI; - -/** - * @property {Number} DEG_TO_RAD - * @static - */ -PIXI.DEG_TO_RAD = Math.PI / 180; - -/** - * @property {String} RETINA_PREFIX - * @protected - * @static - */ -PIXI.RETINA_PREFIX = "@2x"; -//PIXI.SCALE_PREFIX "@x%%"; - -/** - * If true the default pixi startup (console) banner message will be suppressed. - * - * @property {Boolean} dontSayHello - * @default false - * @static - */ -PIXI.dontSayHello = false; - -/** - * The default render options if none are supplied to - * {{#crossLink "WebGLRenderer"}}{{/crossLink}} or {{#crossLink "CanvasRenderer"}}{{/crossLink}}. - * - * @property {Object} defaultRenderOptions - * @property {Object} defaultRenderOptions.view=null - * @property {Boolean} defaultRenderOptions.transparent=false - * @property {Boolean} defaultRenderOptions.antialias=false - * @property {Boolean} defaultRenderOptions.preserveDrawingBuffer=false - * @property {Number} defaultRenderOptions.resolution=1 - * @property {Boolean} defaultRenderOptions.clearBeforeRender=true - * @property {Boolean} defaultRenderOptions.autoResize=false - * @static - */ -PIXI.defaultRenderOptions = { - view:null, - transparent:false, - antialias:false, - preserveDrawingBuffer:false, - resolution:1, - clearBeforeRender:true, - autoResize:false -} - -PIXI.sayHello = function (type) -{ - if(PIXI.dontSayHello)return; - - if ( navigator.userAgent.toLowerCase().indexOf('chrome') > -1 ) - { - var args = [ - '%c %c %c Pixi.js ' + PIXI.VERSION + ' - ' + type + ' %c ' + ' %c ' + ' http://www.pixijs.com/ %c %c ♥%c♥%c♥ ', - 'background: #ff66a5', - 'background: #ff66a5', - 'color: #ff66a5; background: #030307;', - 'background: #ff66a5', - 'background: #ffc3dc', - 'background: #ff66a5', - 'color: #ff2424; background: #fff', - 'color: #ff2424; background: #fff', - 'color: #ff2424; background: #fff' - ]; - - console.log.apply(console, args); - } - else if (window['console']) - { - console.log('Pixi.js ' + PIXI.VERSION + ' - http://www.pixijs.com/'); - } - - PIXI.dontSayHello = true; -}; diff --git a/app/Lib/Vendor/src/pixi/display/DisplayObject.js b/app/Lib/Vendor/src/pixi/display/DisplayObject.js deleted file mode 100755 index 58b375c..0000000 --- a/app/Lib/Vendor/src/pixi/display/DisplayObject.js +++ /dev/null @@ -1,765 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The base class for all objects that are rendered on the screen. - * This is an abstract class and should not be used on its own rather it should be extended. - * - * @class DisplayObject - * @constructor - */ -PIXI.DisplayObject = function() -{ - /** - * The coordinate of the object relative to the local coordinates of the parent. - * - * @property position - * @type Point - */ - this.position = new PIXI.Point(); - - /** - * The scale factor of the object. - * - * @property scale - * @type Point - */ - this.scale = new PIXI.Point(1,1);//{x:1, y:1}; - - /** - * The pivot point of the displayObject that it rotates around - * - * @property pivot - * @type Point - */ - this.pivot = new PIXI.Point(0,0); - - /** - * The rotation of the object in radians. - * - * @property rotation - * @type Number - */ - this.rotation = 0; - - /** - * The opacity of the object. - * - * @property alpha - * @type Number - */ - this.alpha = 1; - - /** - * The visibility of the object. - * - * @property visible - * @type Boolean - */ - this.visible = true; - - /** - * This is the defined area that will pick up mouse / touch events. It is null by default. - * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) - * - * @property hitArea - * @type Rectangle|Circle|Ellipse|Polygon - */ - this.hitArea = null; - - /** - * This is used to indicate if the displayObject should display a mouse hand cursor on rollover - * - * @property buttonMode - * @type Boolean - */ - this.buttonMode = false; - - /** - * Can this object be rendered - * - * @property renderable - * @type Boolean - */ - this.renderable = false; - - /** - * [read-only] The display object container that contains this display object. - * - * @property parent - * @type DisplayObjectContainer - * @readOnly - */ - this.parent = null; - - /** - * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. - * - * @property stage - * @type Stage - * @readOnly - */ - this.stage = null; - - /** - * [read-only] The multiplied alpha of the displayObject - * - * @property worldAlpha - * @type Number - * @readOnly - */ - this.worldAlpha = 1; - - /** - * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property - * - * @property _interactive - * @type Boolean - * @readOnly - * @private - */ - this._interactive = false; - - /** - * This is the cursor that will be used when the mouse is over this object. To enable this the element must have interaction = true and buttonMode = true - * - * @property defaultCursor - * @type String - * - */ - this.defaultCursor = 'pointer'; - - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Matrix - * @readOnly - * @private - */ - this.worldTransform = new PIXI.Matrix(); - - /** - * cached sin rotation and cos rotation - * - * @property _sr - * @type Number - * @private - */ - this._sr = 0; - - /** - * cached sin rotation and cos rotation - * - * @property _cr - * @type Number - * @private - */ - this._cr = 1; - - /** - * The area the filter is applied to like the hitArea this is used as more of an optimisation - * rather than figuring out the dimensions of the displayObject each frame you can set this rectangle - * - * @property filterArea - * @type Rectangle - */ - this.filterArea = null;//new PIXI.Rectangle(0,0,1,1); - - /** - * The original, cached bounds of the object - * - * @property _bounds - * @type Rectangle - * @private - */ - this._bounds = new PIXI.Rectangle(0, 0, 1, 1); - - /** - * The most up-to-date bounds of the object - * - * @property _currentBounds - * @type Rectangle - * @private - */ - this._currentBounds = null; - - /** - * The original, cached mask of the object - * - * @property _currentBounds - * @type Rectangle - * @private - */ - this._mask = null; - - /** - * Cached internal flag. - * - * @property _cacheAsBitmap - * @type Boolean - * @private - */ - this._cacheAsBitmap = false; - - /** - * Cached internal flag. - * - * @property _cacheIsDirty - * @type Boolean - * @private - */ - this._cacheIsDirty = false; - - - /* - * MOUSE Callbacks - */ - - /** - * A callback that is used when the users mouse rolls over the displayObject - * @method mouseover - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the users mouse leaves the displayObject - * @method mouseout - * @param interactionData {InteractionData} - */ - - //Left button - /** - * A callback that is used when the users clicks on the displayObject with their mouse's left button - * @method click - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user clicks the mouse's left button down over the sprite - * @method mousedown - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's left button that was over the displayObject - * for this callback to be fired, the mouse's left button must have been pressed down over the displayObject - * @method mouseup - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's left button that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, the mouse's left button must have been pressed down over the displayObject - * @method mouseupoutside - * @param interactionData {InteractionData} - */ - - //Right button - /** - * A callback that is used when the users clicks on the displayObject with their mouse's right button - * @method rightclick - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user clicks the mouse's right button down over the sprite - * @method rightdown - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's right button that was over the displayObject - * for this callback to be fired the mouse's right button must have been pressed down over the displayObject - * @method rightup - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the mouse's right button that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, the mouse's right button must have been pressed down over the displayObject - * @method rightupoutside - * @param interactionData {InteractionData} - */ - - /* - * TOUCH Callbacks - */ - - /** - * A callback that is used when the users taps on the sprite with their finger - * basically a touch version of click - * @method tap - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user touches over the displayObject - * @method touchstart - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases a touch over the displayObject - * @method touchend - * @param interactionData {InteractionData} - */ - - /** - * A callback that is used when the user releases the touch that was over the displayObject - * for this callback to be fired, The touch must have started over the sprite - * @method touchendoutside - * @param interactionData {InteractionData} - */ -}; - -// constructor -PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; - -/** - * Indicates if the sprite will have touch and mouse interactivity. It is false by default - * - * @property interactive - * @type Boolean - * @default false - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', { - get: function() { - return this._interactive; - }, - set: function(value) { - this._interactive = value; - - // TODO more to be done here.. - // need to sort out a re-crawl! - if(this.stage)this.stage.dirty = true; - } -}); - -/** - * [read-only] Indicates if the sprite is globally visible. - * - * @property worldVisible - * @type Boolean - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'worldVisible', { - get: function() { - var item = this; - - do - { - if(!item.visible)return false; - item = item.parent; - } - while(item); - - return true; - } -}); - -/** - * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it. - * In PIXI a regular mask must be a PIXI.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping. - * To remove a mask, set this property to null. - * - * @property mask - * @type Graphics - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { - get: function() { - return this._mask; - }, - set: function(value) { - - if(this._mask)this._mask.isMask = false; - this._mask = value; - if(this._mask)this._mask.isMask = true; - } -}); - -/** - * Sets the filters for the displayObject. - * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. - * To remove filters simply set this property to 'null' - * @property filters - * @type Array(Filter) - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { - - get: function() { - return this._filters; - }, - - set: function(value) { - - if(value) - { - // now put all the passes in one place.. - var passes = []; - for (var i = 0; i < value.length; i++) - { - var filterPasses = value[i].passes; - for (var j = 0; j < filterPasses.length; j++) - { - passes.push(filterPasses[j]); - } - } - - // TODO change this as it is legacy - this._filterBlock = {target:this, filterPasses:passes}; - } - - this._filters = value; - } -}); - -/** - * Set if this display object is cached as a bitmap. - * This basically takes a snap shot of the display object as it is at that moment. It can provide a performance benefit for complex static displayObjects. - * To remove simply set this property to 'null' - * @property cacheAsBitmap - * @type Boolean - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'cacheAsBitmap', { - - get: function() { - return this._cacheAsBitmap; - }, - - set: function(value) { - - if(this._cacheAsBitmap === value)return; - - if(value) - { - this._generateCachedSprite(); - } - else - { - this._destroyCachedSprite(); - } - - this._cacheAsBitmap = value; - } -}); - -/* - * Updates the object transform for rendering - * - * @method updateTransform - * @private - */ -PIXI.DisplayObject.prototype.updateTransform = function() -{ - // create some matrix refs for easy access - var pt = this.parent.worldTransform; - var wt = this.worldTransform; - - // temporary matrix variables - var a, b, c, d, tx, ty; - - // so if rotation is between 0 then we can simplify the multiplication process.. - if(this.rotation % PIXI.PI_2) - { - // check to see if the rotation is the same as the previous render. This means we only need to use sin and cos when rotation actually changes - if(this.rotation !== this.rotationCache) - { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } - - // get the matrix values of the displayobject based on its transform properties.. - a = this._cr * this.scale.x; - b = this._sr * this.scale.x; - c = -this._sr * this.scale.y; - d = this._cr * this.scale.y; - tx = this.position.x; - ty = this.position.y; - - // check for pivot.. not often used so geared towards that fact! - if(this.pivot.x || this.pivot.y) - { - tx -= this.pivot.x * a + this.pivot.y * c; - ty -= this.pivot.x * b + this.pivot.y * d; - } - - // concat the parent matrix with the objects transform. - wt.a = a * pt.a + b * pt.c; - wt.b = a * pt.b + b * pt.d; - wt.c = c * pt.a + d * pt.c; - wt.d = c * pt.b + d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; - - - } - else - { - // lets do the fast version as we know there is no rotation.. - a = this.scale.x; - d = this.scale.y; - - tx = this.position.x - this.pivot.x * a; - ty = this.position.y - this.pivot.y * d; - - wt.a = a * pt.a; - wt.b = a * pt.b; - wt.c = d * pt.c; - wt.d = d * pt.d; - wt.tx = tx * pt.a + ty * pt.c + pt.tx; - wt.ty = tx * pt.b + ty * pt.d + pt.ty; - } - - // multiply the alphas.. - this.worldAlpha = this.alpha * this.parent.worldAlpha; -}; - -// performance increase to avoid using call.. (10x faster) -PIXI.DisplayObject.prototype.displayObjectUpdateTransform = PIXI.DisplayObject.prototype.updateTransform; - -/** - * Retrieves the bounds of the displayObject as a rectangle object - * - * @method getBounds - * @param matrix {Matrix} - * @return {Rectangle} the rectangular bounding area - */ -PIXI.DisplayObject.prototype.getBounds = function(matrix) -{ - matrix = matrix;//just to get passed js hinting (and preserve inheritance) - return PIXI.EmptyRectangle; -}; - -/** - * Retrieves the local bounds of the displayObject as a rectangle object - * - * @method getLocalBounds - * @return {Rectangle} the rectangular bounding area - */ -PIXI.DisplayObject.prototype.getLocalBounds = function() -{ - return this.getBounds(PIXI.identityMatrix);///PIXI.EmptyRectangle(); -}; - -/** - * Sets the object's stage reference, the stage this object is connected to - * - * @method setStageReference - * @param stage {Stage} the stage that the object will have as its current stage reference - */ -PIXI.DisplayObject.prototype.setStageReference = function(stage) -{ - this.stage = stage; - if(this._interactive)this.stage.dirty = true; -}; - -/** - * Useful function that returns a texture of the displayObject object that can then be used to create sprites - * This can be quite useful if your displayObject is static / complicated and needs to be reused multiple times. - * - * @method generateTexture - * @param resolution {Number} The resolution of the texture being generated - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @param renderer {CanvasRenderer|WebGLRenderer} The renderer used to generate the texture. - * @return {Texture} a texture of the graphics object - */ -PIXI.DisplayObject.prototype.generateTexture = function(resolution, scaleMode, renderer) -{ - var bounds = this.getLocalBounds(); - - var renderTexture = new PIXI.RenderTexture(bounds.width | 0, bounds.height | 0, renderer, scaleMode, resolution); - - PIXI.DisplayObject._tempMatrix.tx = -bounds.x; - PIXI.DisplayObject._tempMatrix.ty = -bounds.y; - - renderTexture.render(this, PIXI.DisplayObject._tempMatrix); - - return renderTexture; -}; - -/** - * Generates and updates the cached sprite for this object. - * - * @method updateCache - */ -PIXI.DisplayObject.prototype.updateCache = function() -{ - this._generateCachedSprite(); -}; - -/** - * Calculates the global position of the display object - * - * @method toGlobal - * @param position {Point} The world origin to calculate from - * @return {Point} A point object representing the position of this object - */ -PIXI.DisplayObject.prototype.toGlobal = function(position) -{ - // don't need to u[date the lot - this.displayObjectUpdateTransform(); - return this.worldTransform.apply(position); -}; - -/** - * Calculates the local position of the display object relative to another point - * - * @method toLocal - * @param position {Point} The world origin to calculate from - * @param [from] {DisplayObject} The DisplayObject to calculate the global position from - * @return {Point} A point object representing the position of this object - */ -PIXI.DisplayObject.prototype.toLocal = function(position, from) -{ - // - if (from) - { - position = from.toGlobal(position); - } - - // don't need to u[date the lot - this.displayObjectUpdateTransform(); - return this.worldTransform.applyInverse(position); -}; - -/** - * Internal method. - * - * @method _renderCachedSprite - * @param renderSession {Object} The render session - * @private - */ -PIXI.DisplayObject.prototype._renderCachedSprite = function(renderSession) -{ - this._cachedSprite.worldAlpha = this.worldAlpha; - - if(renderSession.gl) - { - PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession); - } - else - { - PIXI.Sprite.prototype._renderCanvas.call(this._cachedSprite, renderSession); - } -}; - -/** - * Internal method. - * - * @method _generateCachedSprite - * @private - */ -PIXI.DisplayObject.prototype._generateCachedSprite = function() -{ - this._cacheAsBitmap = false; - var bounds = this.getLocalBounds(); - - if(!this._cachedSprite) - { - var renderTexture = new PIXI.RenderTexture(bounds.width | 0, bounds.height | 0);//, renderSession.renderer); - - this._cachedSprite = new PIXI.Sprite(renderTexture); - this._cachedSprite.worldTransform = this.worldTransform; - } - else - { - this._cachedSprite.texture.resize(bounds.width | 0, bounds.height | 0); - } - - //REMOVE filter! - var tempFilters = this._filters; - this._filters = null; - - this._cachedSprite.filters = tempFilters; - - PIXI.DisplayObject._tempMatrix.tx = -bounds.x; - PIXI.DisplayObject._tempMatrix.ty = -bounds.y; - - this._cachedSprite.texture.render(this, PIXI.DisplayObject._tempMatrix, true); - - this._cachedSprite.anchor.x = -( bounds.x / bounds.width ); - this._cachedSprite.anchor.y = -( bounds.y / bounds.height ); - - this._filters = tempFilters; - - this._cacheAsBitmap = true; -}; - -/** -* Destroys the cached sprite. -* -* @method _destroyCachedSprite -* @private -*/ -PIXI.DisplayObject.prototype._destroyCachedSprite = function() -{ - if(!this._cachedSprite)return; - - this._cachedSprite.texture.destroy(true); - - // TODO could be object pooled! - this._cachedSprite = null; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.DisplayObject.prototype._renderWebGL = function(renderSession) -{ - // OVERWRITE; - // this line is just here to pass jshinting :) - renderSession = renderSession; -}; - -/** -* Renders the object using the Canvas renderer -* -* @method _renderCanvas -* @param renderSession {RenderSession} -* @private -*/ -PIXI.DisplayObject.prototype._renderCanvas = function(renderSession) -{ - // OVERWRITE; - // this line is just here to pass jshinting :) - renderSession = renderSession; -}; - - -PIXI.DisplayObject._tempMatrix = new PIXI.Matrix(); - -/** - * The position of the displayObject on the x axis relative to the local coordinates of the parent. - * - * @property x - * @type Number - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'x', { - get: function() { - return this.position.x; - }, - set: function(value) { - this.position.x = value; - } -}); - -/** - * The position of the displayObject on the y axis relative to the local coordinates of the parent. - * - * @property y - * @type Number - */ -Object.defineProperty(PIXI.DisplayObject.prototype, 'y', { - get: function() { - return this.position.y; - }, - set: function(value) { - this.position.y = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/display/DisplayObjectContainer.js b/app/Lib/Vendor/src/pixi/display/DisplayObjectContainer.js deleted file mode 100644 index e3ccc20..0000000 --- a/app/Lib/Vendor/src/pixi/display/DisplayObjectContainer.js +++ /dev/null @@ -1,515 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A DisplayObjectContainer represents a collection of display objects. - * It is the base class of all display objects that act as a container for other objects. - * - * @class DisplayObjectContainer - * @extends DisplayObject - * @constructor - */ -PIXI.DisplayObjectContainer = function() -{ - PIXI.DisplayObject.call( this ); - - /** - * [read-only] The array of children of this container. - * - * @property children - * @type Array(DisplayObject) - * @readOnly - */ - this.children = []; - - // fast access to update transform.. - -}; - -// constructor -PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); -PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; - - -/** - * The width of the displayObjectContainer, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', { - get: function() { - return this.scale.x * this.getLocalBounds().width; - }, - set: function(value) { - - var width = this.getLocalBounds().width; - - if(width !== 0) - { - this.scale.x = value / width; - } - else - { - this.scale.x = 1; - } - - - this._width = value; - } -}); - -/** - * The height of the displayObjectContainer, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'height', { - get: function() { - return this.scale.y * this.getLocalBounds().height; - }, - set: function(value) { - - var height = this.getLocalBounds().height; - - if(height !== 0) - { - this.scale.y = value / height ; - } - else - { - this.scale.y = 1; - } - - this._height = value; - } -}); - -/** - * Adds a child to the container. - * - * @method addChild - * @param child {DisplayObject} The DisplayObject to add to the container - * @return {DisplayObject} The child that was added. - */ -PIXI.DisplayObjectContainer.prototype.addChild = function(child) -{ - return this.addChildAt(child, this.children.length); -}; - -/** - * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown - * - * @method addChildAt - * @param child {DisplayObject} The child to add - * @param index {Number} The index to place the child in - * @return {DisplayObject} The child that was added. - */ -PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) -{ - if(index >= 0 && index <= this.children.length) - { - if(child.parent) - { - child.parent.removeChild(child); - } - - child.parent = this; - - this.children.splice(index, 0, child); - - if(this.stage)child.setStageReference(this.stage); - - return child; - } - else - { - throw new Error(child + 'addChildAt: The index '+ index +' supplied is out of bounds ' + this.children.length); - } -}; - -/** - * Swaps the position of 2 Display Objects within this container. - * - * @method swapChildren - * @param child {DisplayObject} - * @param child2 {DisplayObject} - */ -PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) -{ - if(child === child2) { - return; - } - - var index1 = this.getChildIndex(child); - var index2 = this.getChildIndex(child2); - - if(index1 < 0 || index2 < 0) { - throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.'); - } - - this.children[index1] = child2; - this.children[index2] = child; - -}; - -/** - * Returns the index position of a child DisplayObject instance - * - * @method getChildIndex - * @param child {DisplayObject} The DisplayObject instance to identify - * @return {Number} The index position of the child display object to identify - */ -PIXI.DisplayObjectContainer.prototype.getChildIndex = function(child) -{ - var index = this.children.indexOf(child); - if (index === -1) - { - throw new Error('The supplied DisplayObject must be a child of the caller'); - } - return index; -}; - -/** - * Changes the position of an existing child in the display object container - * - * @method setChildIndex - * @param child {DisplayObject} The child DisplayObject instance for which you want to change the index number - * @param index {Number} The resulting index number for the child display object - */ -PIXI.DisplayObjectContainer.prototype.setChildIndex = function(child, index) -{ - if (index < 0 || index >= this.children.length) - { - throw new Error('The supplied index is out of bounds'); - } - var currentIndex = this.getChildIndex(child); - this.children.splice(currentIndex, 1); //remove from old position - this.children.splice(index, 0, child); //add at new position -}; - -/** - * Returns the child at the specified index - * - * @method getChildAt - * @param index {Number} The index to get the child from - * @return {DisplayObject} The child at the given index, if any. - */ -PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) -{ - if (index < 0 || index >= this.children.length) - { - throw new Error('getChildAt: Supplied index '+ index +' does not exist in the child list, or the supplied DisplayObject must be a child of the caller'); - } - return this.children[index]; - -}; - -/** - * Removes a child from the container. - * - * @method removeChild - * @param child {DisplayObject} The DisplayObject to remove - * @return {DisplayObject} The child that was removed. - */ -PIXI.DisplayObjectContainer.prototype.removeChild = function(child) -{ - var index = this.children.indexOf( child ); - if(index === -1)return; - - return this.removeChildAt( index ); -}; - -/** - * Removes a child from the specified index position. - * - * @method removeChildAt - * @param index {Number} The index to get the child from - * @return {DisplayObject} The child that was removed. - */ -PIXI.DisplayObjectContainer.prototype.removeChildAt = function(index) -{ - var child = this.getChildAt( index ); - if(this.stage) - child.removeStageReference(); - - child.parent = undefined; - this.children.splice( index, 1 ); - return child; -}; - -/** -* Removes all children from this container that are within the begin and end indexes. -* -* @method removeChildren -* @param beginIndex {Number} The beginning position. Default value is 0. -* @param endIndex {Number} The ending position. Default value is size of the container. -*/ -PIXI.DisplayObjectContainer.prototype.removeChildren = function(beginIndex, endIndex) -{ - var begin = beginIndex || 0; - var end = typeof endIndex === 'number' ? endIndex : this.children.length; - var range = end - begin; - - if (range > 0 && range <= end) - { - var removed = this.children.splice(begin, range); - for (var i = 0; i < removed.length; i++) { - var child = removed[i]; - if(this.stage) - child.removeStageReference(); - child.parent = undefined; - } - return removed; - } - else if (range === 0 && this.children.length === 0) - { - return []; - } - else - { - throw new Error( 'removeChildren: Range Error, numeric values are outside the acceptable range' ); - } -}; - -/* - * Updates the transform on all children of this container for rendering - * - * @method updateTransform - * @private - */ -PIXI.DisplayObjectContainer.prototype.updateTransform = function() -{ - if(!this.visible)return; - - this.displayObjectUpdateTransform(); - - //PIXI.DisplayObject.prototype.updateTransform.call( this ); - - if(this._cacheAsBitmap)return; - - for(var i=0,j=this.children.length; i childMaxX ? maxX : childMaxX; - maxY = maxY > childMaxY ? maxY : childMaxY; - } - - if(!childVisible) - return PIXI.EmptyRectangle; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.y = minY; - bounds.width = maxX - minX; - bounds.height = maxY - minY; - - // TODO: store a reference so that if this function gets called again in the render cycle we do not have to recalculate - //this._currentBounds = bounds; - - return bounds; -}; - -/** - * Retrieves the non-global local bounds of the displayObjectContainer as a rectangle. The calculation takes all visible children into consideration. - * - * @method getLocalBounds - * @return {Rectangle} The rectangular bounding area - */ -PIXI.DisplayObjectContainer.prototype.getLocalBounds = function() -{ - var matrixCache = this.worldTransform; - - this.worldTransform = PIXI.identityMatrix; - - for(var i=0,j=this.children.length; i= this.textures.length) - { - this.gotoAndStop(this.textures.length - 1); - if(this.onComplete) - { - this.onComplete(); - } - } -}; - -/** - * A short hand way of creating a movieclip from an array of frame ids - * - * @static - * @method fromFrames - * @param frames {Array} the array of frames ids the movieclip will use as its texture frames - */ -PIXI.MovieClip.fromFrames = function(frames) -{ - var textures = []; - - for (var i = 0; i < frames.length; i++) - { - textures.push(new PIXI.Texture.fromFrame(frames[i])); - } - - return new PIXI.MovieClip(textures); -}; - -/** - * A short hand way of creating a movieclip from an array of image ids - * - * @static - * @method fromImages - * @param frames {Array} the array of image ids the movieclip will use as its texture frames - */ -PIXI.MovieClip.fromImages = function(images) -{ - var textures = []; - - for (var i = 0; i < images.length; i++) - { - textures.push(new PIXI.Texture.fromImage(images[i])); - } - - return new PIXI.MovieClip(textures); -}; diff --git a/app/Lib/Vendor/src/pixi/display/Sprite.js b/app/Lib/Vendor/src/pixi/display/Sprite.js deleted file mode 100644 index aab559a..0000000 --- a/app/Lib/Vendor/src/pixi/display/Sprite.js +++ /dev/null @@ -1,471 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The Sprite object is the base for all textured objects that are rendered to the screen - * - * @class Sprite - * @extends DisplayObjectContainer - * @constructor - * @param texture {Texture} The texture for this sprite - * - * A sprite can be created directly from an image like this : - * var sprite = new PIXI.Sprite.fromImage('assets/image.png'); - * yourStage.addChild(sprite); - * then obviously don't forget to add it to the stage you have already created - */ -PIXI.Sprite = function(texture) -{ - PIXI.DisplayObjectContainer.call( this ); - - /** - * The anchor sets the origin point of the texture. - * The default is 0,0 this means the texture's origin is the top left - * Setting than anchor to 0.5,0.5 means the textures origin is centered - * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right corner - * - * @property anchor - * @type Point - */ - this.anchor = new PIXI.Point(); - - /** - * The texture that the sprite is using - * - * @property texture - * @type Texture - */ - this.texture = texture || PIXI.Texture.emptyTexture; - - /** - * The width of the sprite (this is initially set by the texture) - * - * @property _width - * @type Number - * @private - */ - this._width = 0; - - /** - * The height of the sprite (this is initially set by the texture) - * - * @property _height - * @type Number - * @private - */ - this._height = 0; - - /** - * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect. - * - * @property tint - * @type Number - * @default 0xFFFFFF - */ - this.tint = 0xFFFFFF; - - /** - * The blend mode to be applied to the sprite. Set to PIXI.blendModes.NORMAL to remove any blend mode. - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; - - /** - * The shader that will be used to render the texture to the stage. Set to null to remove a current shader. - * - * @property shader - * @type AbstractFilter - * @default null - */ - this.shader = null; - - if(this.texture.baseTexture.hasLoaded) - { - this.onTextureUpdate(); - } - else - { - this.texture.on( 'update', this.onTextureUpdate.bind(this) ); - } - - this.renderable = true; - -}; - -// constructor -PIXI.Sprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); -PIXI.Sprite.prototype.constructor = PIXI.Sprite; - -/** - * The width of the sprite, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.Sprite.prototype, 'width', { - get: function() { - return this.scale.x * this.texture.frame.width; - }, - set: function(value) { - this.scale.x = value / this.texture.frame.width; - this._width = value; - } -}); - -/** - * The height of the sprite, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.Sprite.prototype, 'height', { - get: function() { - return this.scale.y * this.texture.frame.height; - }, - set: function(value) { - this.scale.y = value / this.texture.frame.height; - this._height = value; - } -}); - -/** - * Sets the texture of the sprite - * - * @method setTexture - * @param texture {Texture} The PIXI texture that is displayed by the sprite - */ -PIXI.Sprite.prototype.setTexture = function(texture) -{ - this.texture = texture; - this.cachedTint = 0xFFFFFF; -}; - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @method onTextureUpdate - * @param event - * @private - */ -PIXI.Sprite.prototype.onTextureUpdate = function() -{ - // so if _width is 0 then width was not set.. - if(this._width)this.scale.x = this._width / this.texture.frame.width; - if(this._height)this.scale.y = this._height / this.texture.frame.height; - - //this.updateFrame = true; -}; - -/** -* Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account. -* -* @method getBounds -* @param matrix {Matrix} the transformation matrix of the sprite -* @return {Rectangle} the framing rectangle -*/ -PIXI.Sprite.prototype.getBounds = function(matrix) -{ - var width = this.texture.frame.width; - var height = this.texture.frame.height; - - var w0 = width * (1-this.anchor.x); - var w1 = width * -this.anchor.x; - - var h0 = height * (1-this.anchor.y); - var h1 = height * -this.anchor.y; - - var worldTransform = matrix || this.worldTransform ; - - var a = worldTransform.a; - var b = worldTransform.b; - var c = worldTransform.c; - var d = worldTransform.d; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - if(b === 0 && c === 0) - { - // scale may be negative! - if(a < 0)a *= -1; - if(d < 0)d *= -1; - - // this means there is no rotation going on right? RIGHT? - // if thats the case then we can avoid checking the bound values! yay - minX = a * w1 + tx; - maxX = a * w0 + tx; - minY = d * h1 + ty; - maxY = d * h0 + ty; - } - else - { - var x1 = a * w1 + c * h1 + tx; - var y1 = d * h1 + b * w1 + ty; - - var x2 = a * w0 + c * h1 + tx; - var y2 = d * h1 + b * w0 + ty; - - var x3 = a * w0 + c * h0 + tx; - var y3 = d * h0 + b * w0 + ty; - - var x4 = a * w1 + c * h0 + tx; - var y4 = d * h0 + b * w1 + ty; - - minX = x1 < minX ? x1 : minX; - minX = x2 < minX ? x2 : minX; - minX = x3 < minX ? x3 : minX; - minX = x4 < minX ? x4 : minX; - - minY = y1 < minY ? y1 : minY; - minY = y2 < minY ? y2 : minY; - minY = y3 < minY ? y3 : minY; - minY = y4 < minY ? y4 : minY; - - maxX = x1 > maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - } - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Sprite.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(!this.visible || this.alpha <= 0)return; - - var i,j; - - // do a quick check to see if this element has a mask or a filter. - if(this._mask || this._filters) - { - var spriteBatch = renderSession.spriteBatch; - - // push filter first as we need to ensure the stencil buffer is correct for any masking - if(this._filters) - { - spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - - if(this._mask) - { - spriteBatch.stop(); - renderSession.maskManager.pushMask(this.mask, renderSession); - spriteBatch.start(); - } - - // add this sprite to the batch - spriteBatch.render(this); - - // now loop through the children and make sure they get rendered - for(i=0,j=this.children.length; i 1) ratio = 1; - - perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); - num = this.texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; - perp.x /= perpLength; - perp.y /= perpLength; - - perp.x *= num; - perp.y *= num; - - vertices[index] = point.x + perp.x; - vertices[index+1] = point.y + perp.y; - vertices[index+2] = point.x - perp.x; - vertices[index+3] = point.y - perp.y; - - lastPoint = point; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); -}; -/* - * Sets the texture that the Rope will use - * - * @method setTexture - * @param texture {Texture} the texture that will be used - */ -PIXI.Rope.prototype.setTexture = function(texture) -{ - // stop current texture - this.texture = texture; - //this.updateFrame = true; -}; diff --git a/app/Lib/Vendor/src/pixi/extras/SPINE-LICENSE b/app/Lib/Vendor/src/pixi/extras/SPINE-LICENSE deleted file mode 100755 index 7bb7566..0000000 --- a/app/Lib/Vendor/src/pixi/extras/SPINE-LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -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. diff --git a/app/Lib/Vendor/src/pixi/extras/Spine.js b/app/Lib/Vendor/src/pixi/extras/Spine.js deleted file mode 100644 index 06ce610..0000000 --- a/app/Lib/Vendor/src/pixi/extras/Spine.js +++ /dev/null @@ -1,2626 +0,0 @@ -/****************************************************************************** - * 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 - 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[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[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]); - - } 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]); - - } 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]); - - } 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]); - - } 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]); - } 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]); - } - - 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]); - } - } - } - - 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]); - } - - 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]); - } - - 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; - } -}; diff --git a/app/Lib/Vendor/src/pixi/extras/Strip.js b/app/Lib/Vendor/src/pixi/extras/Strip.js deleted file mode 100644 index 6cff5df..0000000 --- a/app/Lib/Vendor/src/pixi/extras/Strip.js +++ /dev/null @@ -1,469 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ - */ - - /** - * - * @class Strip - * @extends DisplayObjectContainer - * @constructor - * @param texture {Texture} The texture to use - * @param width {Number} the width - * @param height {Number} the height - * - */ -PIXI.Strip = function(texture) -{ - PIXI.DisplayObjectContainer.call( this ); - - - /** - * The texture of the strip - * - * @property texture - * @type Texture - */ - this.texture = texture; - - // set up the main bits.. - this.uvs = new PIXI.Float32Array([0, 1, - 1, 1, - 1, 0, - 0, 1]); - - this.vertices = new PIXI.Float32Array([0, 0, - 100, 0, - 100, 100, - 0, 100]); - - this.colors = new PIXI.Float32Array([1, 1, 1, 1]); - - this.indices = new PIXI.Uint16Array([0, 1, 2, 3]); - - /** - * Whether the strip is dirty or not - * - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * The blend mode to be applied to the sprite. Set to PIXI.blendModes.NORMAL to remove any blend mode. - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; - - /** - * Triangles in canvas mode are automatically antialiased, use this value to force triangles to overlap a bit with each other. - * - * @property canvasPadding - * @type Number - */ - this.canvasPadding = 0; - - this.drawMode = PIXI.Strip.DrawModes.TRIANGLE_STRIP; - -}; - -// constructor -PIXI.Strip.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); -PIXI.Strip.prototype.constructor = PIXI.Strip; - -PIXI.Strip.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(!this.visible || this.alpha <= 0)return; - // render triangle strip.. - - renderSession.spriteBatch.stop(); - - // init! init! - if(!this._vertexBuffer)this._initWebGL(renderSession); - - renderSession.shaderManager.setShader(renderSession.shaderManager.stripShader); - - this._renderStrip(renderSession); - - ///renderSession.shaderManager.activateDefaultShader(); - - renderSession.spriteBatch.start(); - - //TODO check culling -}; - -PIXI.Strip.prototype._initWebGL = function(renderSession) -{ - // build the strip! - var gl = renderSession.gl; - - this._vertexBuffer = gl.createBuffer(); - this._indexBuffer = gl.createBuffer(); - this._uvBuffer = gl.createBuffer(); - this._colorBuffer = gl.createBuffer(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); -}; - -PIXI.Strip.prototype._renderStrip = function(renderSession) -{ - var gl = renderSession.gl; - var projection = renderSession.projection, - offset = renderSession.offset, - shader = renderSession.shaderManager.stripShader; - - var drawMode = this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP ? gl.TRIANGLE_STRIP : gl.TRIANGLES; - - // gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mat4Real); - - renderSession.blendModeManager.setBlendMode(this.blendMode); - - - // set uniforms - gl.uniformMatrix3fv(shader.translationMatrix, false, this.worldTransform.toArray(true)); - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - gl.uniform1f(shader.alpha, this.worldAlpha); - - if(!this.dirty) - { - - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { - renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - - - } - else - { - - this.dirty = false; - gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - // update the uvs - gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.activeTexture(gl.TEXTURE0); - - // check if a texture is dirty.. - if(this.texture.baseTexture._dirty[gl.id]) - { - renderSession.renderer.updateTexture(this.texture.baseTexture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]); - } - - // dont need to upload! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - } - //console.log(gl.TRIANGLE_STRIP) - // - // - gl.drawElements(drawMode, this.indices.length, gl.UNSIGNED_SHORT, 0); - - -}; - - - -PIXI.Strip.prototype._renderCanvas = function(renderSession) -{ - var context = renderSession.context; - - var transform = this.worldTransform; - - if (renderSession.roundPixels) - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx | 0, transform.ty | 0); - } - else - { - context.setTransform(transform.a, transform.b, transform.c, transform.d, transform.tx, transform.ty); - } - - if (this.drawMode === PIXI.Strip.DrawModes.TRIANGLE_STRIP) - { - this._renderCanvasTriangleStrip(context); - } - else - { - this._renderCanvasTriangles(context); - } -}; - -PIXI.Strip.prototype._renderCanvasTriangleStrip = function(context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - - var length = vertices.length / 2; - this.count++; - - for (var i = 0; i < length - 2; i++) { - // draw some triangles! - var index = i * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index, (index + 2), (index + 4)); - } -}; - -PIXI.Strip.prototype._renderCanvasTriangles = function(context) -{ - // draw triangles!! - var vertices = this.vertices; - var uvs = this.uvs; - var indices = this.indices; - - var length = indices.length; - this.count++; - - for (var i = 0; i < length; i += 3) { - // draw some triangles! - var index0 = indices[i] * 2, index1 = indices[i + 1] * 2, index2 = indices[i + 2] * 2; - this._renderCanvasDrawTriangle(context, vertices, uvs, index0, index1, index2); - } -}; - -PIXI.Strip.prototype._renderCanvasDrawTriangle = function(context, vertices, uvs, index0, index1, index2) -{ - var textureSource = this.texture.baseTexture.source; - var textureWidth = this.texture.width; - var textureHeight = this.texture.height; - - var x0 = vertices[index0], x1 = vertices[index1], x2 = vertices[index2]; - var y0 = vertices[index0 + 1], y1 = vertices[index1 + 1], y2 = vertices[index2 + 1]; - - var u0 = uvs[index0] * textureWidth, u1 = uvs[index1] * textureWidth, u2 = uvs[index2] * textureWidth; - var v0 = uvs[index0 + 1] * textureHeight, v1 = uvs[index1 + 1] * textureHeight, v2 = uvs[index2 + 1] * textureHeight; - - if (this.canvasPadding > 0) { - var paddingX = this.canvasPadding / this.worldTransform.a; - var paddingY = this.canvasPadding / this.worldTransform.d; - var centerX = (x0 + x1 + x2) / 3; - var centerY = (y0 + y1 + y2) / 3; - - var normX = x0 - centerX; - var normY = y0 - centerY; - - var dist = Math.sqrt(normX * normX + normY * normY); - x0 = centerX + (normX / dist) * (dist + paddingX); - y0 = centerY + (normY / dist) * (dist + paddingY); - - // - - normX = x1 - centerX; - normY = y1 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x1 = centerX + (normX / dist) * (dist + paddingX); - y1 = centerY + (normY / dist) * (dist + paddingY); - - normX = x2 - centerX; - normY = y2 - centerY; - - dist = Math.sqrt(normX * normX + normY * normY); - x2 = centerX + (normX / dist) * (dist + paddingX); - y2 = centerY + (normY / dist) * (dist + paddingY); - } - - context.save(); - context.beginPath(); - - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - context.closePath(); - - context.clip(); - - // Compute matrix transform - var delta = (u0 * v1) + (v0 * u2) + (u1 * v2) - (v1 * u2) - (v0 * u1) - (u0 * v2); - var deltaA = (x0 * v1) + (v0 * x2) + (x1 * v2) - (v1 * x2) - (v0 * x1) - (x0 * v2); - var deltaB = (u0 * x1) + (x0 * u2) + (u1 * x2) - (x1 * u2) - (x0 * u1) - (u0 * x2); - var deltaC = (u0 * v1 * x2) + (v0 * x1 * u2) + (x0 * u1 * v2) - (x0 * v1 * u2) - (v0 * u1 * x2) - (u0 * x1 * v2); - var deltaD = (y0 * v1) + (v0 * y2) + (y1 * v2) - (v1 * y2) - (v0 * y1) - (y0 * v2); - var deltaE = (u0 * y1) + (y0 * u2) + (u1 * y2) - (y1 * u2) - (y0 * u1) - (u0 * y2); - var deltaF = (u0 * v1 * y2) + (v0 * y1 * u2) + (y0 * u1 * v2) - (y0 * v1 * u2) - (v0 * u1 * y2) - (u0 * y1 * v2); - - context.transform(deltaA / delta, deltaD / delta, - deltaB / delta, deltaE / delta, - deltaC / delta, deltaF / delta); - - context.drawImage(textureSource, 0, 0); - context.restore(); -}; - - - -/** - * Renders a flat strip - * - * @method renderStripFlat - * @param strip {Strip} The Strip to render - * @private - */ -PIXI.Strip.prototype.renderStripFlat = function(strip) -{ - var context = this.context; - var vertices = strip.vertices; - - var length = vertices.length/2; - this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - // draw some triangles! - var index = i*2; - - var x0 = vertices[index], x1 = vertices[index+2], x2 = vertices[index+4]; - var y0 = vertices[index+1], y1 = vertices[index+3], y2 = vertices[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - } - - context.fillStyle = '#FF0000'; - context.fill(); - context.closePath(); -}; - -/* -PIXI.Strip.prototype.setTexture = function(texture) -{ - //TODO SET THE TEXTURES - //TODO VISIBILITY - - // stop current texture - this.texture = texture; - this.width = texture.frame.width; - this.height = texture.frame.height; - this.updateFrame = true; -}; -*/ - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @method onTextureUpdate - * @param event - * @private - */ - -PIXI.Strip.prototype.onTextureUpdate = function() -{ - this.updateFrame = true; -}; - -/** - * Returns the bounds of the mesh as a rectangle. The bounds calculation takes the worldTransform into account. - * - * @method getBounds - * @param matrix {Matrix} the transformation matrix of the sprite - * @return {Rectangle} the framing rectangle - */ -PIXI.Strip.prototype.getBounds = function(matrix) -{ - var worldTransform = matrix || this.worldTransform; - - var a = worldTransform.a; - var b = worldTransform.b; - var c = worldTransform.c; - var d = worldTransform.d; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - var vertices = this.vertices; - for (var i = 0, n = vertices.length; i < n; i += 2) - { - var rawX = vertices[i], rawY = vertices[i + 1]; - var x = (a * rawX) + (c * rawY) + tx; - var y = (d * rawY) + (b * rawX) + ty; - - minX = x < minX ? x : minX; - minY = y < minY ? y : minY; - - maxX = x > maxX ? x : maxX; - maxY = y > maxY ? y : maxY; - } - - if (minX === -Infinity || maxY === Infinity) - { - return PIXI.EmptyRectangle; - } - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - -/** - * Different drawing buffer modes supported - * - * @property - * @type {{TRIANGLE_STRIP: number, TRIANGLES: number}} - * @static - */ -PIXI.Strip.DrawModes = { - TRIANGLE_STRIP: 0, - TRIANGLES: 1 -}; diff --git a/app/Lib/Vendor/src/pixi/extras/TilingSprite.js b/app/Lib/Vendor/src/pixi/extras/TilingSprite.js deleted file mode 100644 index 2b758e2..0000000 --- a/app/Lib/Vendor/src/pixi/extras/TilingSprite.js +++ /dev/null @@ -1,466 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * A tiling sprite is a fast way of rendering a tiling image - * - * @class TilingSprite - * @extends Sprite - * @constructor - * @param texture {Texture} the texture of the tiling sprite - * @param width {Number} the width of the tiling sprite - * @param height {Number} the height of the tiling sprite - */ -PIXI.TilingSprite = function(texture, width, height) -{ - PIXI.Sprite.call( this, texture); - - /** - * The with of the tiling sprite - * - * @property width - * @type Number - */ - this._width = width || 100; - - /** - * The height of the tiling sprite - * - * @property height - * @type Number - */ - this._height = height || 100; - - /** - * The scaling of the image that is being tiled - * - * @property tileScale - * @type Point - */ - this.tileScale = new PIXI.Point(1,1); - - /** - * A point that represents the scale of the texture object - * - * @property tileScaleOffset - * @type Point - */ - this.tileScaleOffset = new PIXI.Point(1,1); - - /** - * The offset position of the image that is being tiled - * - * @property tilePosition - * @type Point - */ - this.tilePosition = new PIXI.Point(0,0); - - /** - * Whether this sprite is renderable or not - * - * @property renderable - * @type Boolean - * @default true - */ - this.renderable = true; - - /** - * The tint applied to the sprite. This is a hex value - * - * @property tint - * @type Number - * @default 0xFFFFFF - */ - this.tint = 0xFFFFFF; - - /** - * The blend mode to be applied to the sprite - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; - - - -}; - -// constructor -PIXI.TilingSprite.prototype = Object.create(PIXI.Sprite.prototype); -PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite; - - -/** - * The width of the sprite, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.TilingSprite.prototype, 'width', { - get: function() { - return this._width; - }, - set: function(value) { - - this._width = value; - } -}); - -/** - * The height of the TilingSprite, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.TilingSprite.prototype, 'height', { - get: function() { - return this._height; - }, - set: function(value) { - this._height = value; - } -}); - -PIXI.TilingSprite.prototype.setTexture = function(texture) -{ - if (this.texture === texture) return; - - this.texture = texture; - - this.refreshTexture = true; - - this.cachedTint = 0xFFFFFF; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.TilingSprite.prototype._renderWebGL = function(renderSession) -{ - if (this.visible === false || this.alpha === 0) return; - var i,j; - - if (this._mask) - { - renderSession.spriteBatch.stop(); - renderSession.maskManager.pushMask(this.mask, renderSession); - renderSession.spriteBatch.start(); - } - - if (this._filters) - { - renderSession.spriteBatch.flush(); - renderSession.filterManager.pushFilter(this._filterBlock); - } - - - - if (!this.tilingTexture || this.refreshTexture) - { - this.generateTilingTexture(true); - - if (this.tilingTexture && this.tilingTexture.needsUpdate) - { - //TODO - tweaking - PIXI.updateWebGLTexture(this.tilingTexture.baseTexture, renderSession.gl); - this.tilingTexture.needsUpdate = false; - // this.tilingTexture._uvs = null; - } - } - else - { - renderSession.spriteBatch.renderTilingSprite(this); - } - // simple render children! - for (i=0,j=this.children.length; i maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - - var bounds = this._bounds; - - bounds.x = minX; - bounds.width = maxX - minX; - - bounds.y = minY; - bounds.height = maxY - minY; - - // store a reference so that if this function gets called again in the render cycle we do not have to recalculate - this._currentBounds = bounds; - - return bounds; -}; - - - -/** - * When the texture is updated, this event will fire to update the scale and frame - * - * @method onTextureUpdate - * @param event - * @private - */ -PIXI.TilingSprite.prototype.onTextureUpdate = function() -{ - // overriding the sprite version of this! -}; - - -/** -* -* @method generateTilingTexture -* -* @param forcePowerOfTwo {Boolean} Whether we want to force the texture to be a power of two -*/ -PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo) -{ - if (!this.texture.baseTexture.hasLoaded) return; - - var texture = this.originalTexture || this.texture; - var frame = texture.frame; - var targetWidth, targetHeight; - - // Check that the frame is the same size as the base texture. - var isFrame = frame.width !== texture.baseTexture.width || frame.height !== texture.baseTexture.height; - - var newTextureRequired = false; - - if (!forcePowerOfTwo) - { - if (isFrame) - { - targetWidth = frame.width; - targetHeight = frame.height; - - newTextureRequired = true; - } - } - else - { - targetWidth = PIXI.getNextPowerOfTwo(frame.width); - targetHeight = PIXI.getNextPowerOfTwo(frame.height); - - // If the BaseTexture dimensions don't match the texture frame then we need a new texture anyway because it's part of a texture atlas - if (frame.width !== targetWidth || frame.height !== targetHeight || texture.baseTexture.width !== targetWidth || texture.baseTexture.height || targetHeight) newTextureRequired = true; - } - - if (newTextureRequired) - { - var canvasBuffer; - - if (this.tilingTexture && this.tilingTexture.isTiling) - { - canvasBuffer = this.tilingTexture.canvasBuffer; - canvasBuffer.resize(targetWidth, targetHeight); - this.tilingTexture.baseTexture.width = targetWidth; - this.tilingTexture.baseTexture.height = targetHeight; - this.tilingTexture.needsUpdate = true; - } - else - { - canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight); - - this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); - this.tilingTexture.canvasBuffer = canvasBuffer; - this.tilingTexture.isTiling = true; - } - - canvasBuffer.context.drawImage(texture.baseTexture.source, - texture.crop.x, - texture.crop.y, - texture.crop.width, - texture.crop.height, - 0, - 0, - targetWidth, - targetHeight); - - this.tileScaleOffset.x = frame.width / targetWidth; - this.tileScaleOffset.y = frame.height / targetHeight; - } - else - { - // TODO - switching? - if (this.tilingTexture && this.tilingTexture.isTiling) - { - // destroy the tiling texture! - // TODO could store this somewhere? - this.tilingTexture.destroy(true); - } - - this.tileScaleOffset.x = 1; - this.tileScaleOffset.y = 1; - this.tilingTexture = texture; - } - - this.refreshTexture = false; - - this.originalTexture = this.texture; - this.texture = this.tilingTexture; - - this.tilingTexture.baseTexture._powerOf2 = true; -}; diff --git a/app/Lib/Vendor/src/pixi/filters/AbstractFilter.js b/app/Lib/Vendor/src/pixi/filters/AbstractFilter.js deleted file mode 100644 index 6727dc5..0000000 --- a/app/Lib/Vendor/src/pixi/filters/AbstractFilter.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This is the base class for creating a PIXI filter. Currently only webGL supports filters. - * If you want to make a custom filter this should be your base class. - * @class AbstractFilter - * @constructor - * @param fragmentSrc {Array} The fragment source in an array of strings. - * @param uniforms {Object} An object containing the uniforms for this filter. - */ -PIXI.AbstractFilter = function(fragmentSrc, uniforms) -{ - /** - * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. - * For example the blur filter has two passes blurX and blurY. - * @property passes - * @type Array(Filter) - * @private - */ - this.passes = [this]; - - /** - * @property shaders - * @type Array(Shader) - * @private - */ - this.shaders = []; - - /** - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * @property padding - * @type Number - */ - this.padding = 0; - - /** - * @property uniforms - * @type object - * @private - */ - this.uniforms = uniforms || {}; - - /** - * @property fragmentSrc - * @type Array - * @private - */ - this.fragmentSrc = fragmentSrc || []; -}; - -PIXI.AbstractFilter.prototype.constructor = PIXI.AbstractFilter; - -/** - * Syncs the uniforms between the class object and the shaders. - * - * @method syncUniforms - */ -PIXI.AbstractFilter.prototype.syncUniforms = function() -{ - for(var i=0,j=this.shaders.length; i 0.2) n = 65600.0; // :', - ' if (gray > 0.3) n = 332772.0; // *', - ' if (gray > 0.4) n = 15255086.0; // o', - ' if (gray > 0.5) n = 23385164.0; // &', - ' if (gray > 0.6) n = 15252014.0; // 8', - ' if (gray > 0.7) n = 13199452.0; // @', - ' if (gray > 0.8) n = 11512810.0; // #', - - ' vec2 p = mod( uv / ( pixelSize * 0.5 ), 2.0) - vec2(1.0);', - ' col = col * character(n, p);', - - ' gl_FragColor = vec4(col, 1.0);', - '}' - ]; -}; - -PIXI.AsciiFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.AsciiFilter.prototype.constructor = PIXI.AsciiFilter; - -/** - * The pixel size used by the filter. - * - * @property size - * @type Number - */ -Object.defineProperty(PIXI.AsciiFilter.prototype, 'size', { - get: function() { - return this.uniforms.pixelSize.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.pixelSize.value = value; - } -}); \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/filters/BlurFilter.js b/app/Lib/Vendor/src/pixi/filters/BlurFilter.js deleted file mode 100644 index d93d147..0000000 --- a/app/Lib/Vendor/src/pixi/filters/BlurFilter.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The BlurFilter applies a Gaussian blur to an object. - * The strength of the blur can be set for x- and y-axis separately (always relative to the stage). - * - * @class BlurFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.BlurFilter = function() -{ - this.blurXFilter = new PIXI.BlurXFilter(); - this.blurYFilter = new PIXI.BlurYFilter(); - - this.passes =[this.blurXFilter, this.blurYFilter]; -}; - -PIXI.BlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.BlurFilter.prototype.constructor = PIXI.BlurFilter; - -/** - * Sets the strength of both the blurX and blurY properties simultaneously - * - * @property blur - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', { - get: function() { - return this.blurXFilter.blur; - }, - set: function(value) { - this.blurXFilter.blur = this.blurYFilter.blur = value; - } -}); - -/** - * Sets the strength of the blurX property - * - * @property blurX - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', { - get: function() { - return this.blurXFilter.blur; - }, - set: function(value) { - this.blurXFilter.blur = value; - } -}); - -/** - * Sets the strength of the blurY property - * - * @property blurY - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', { - get: function() { - return this.blurYFilter.blur; - }, - set: function(value) { - this.blurYFilter.blur = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/BlurXFilter.js b/app/Lib/Vendor/src/pixi/filters/BlurXFilter.js deleted file mode 100644 index 13f67c3..0000000 --- a/app/Lib/Vendor/src/pixi/filters/BlurXFilter.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The BlurXFilter applies a horizontal Gaussian blur to an object. - * - * @class BlurXFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.BlurXFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float blur;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' vec4 sum = vec4(0.0);', - - ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;', - - ' gl_FragColor = sum;', - '}' - ]; -}; - -PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter; - -/** - * Sets the strength of both the blur. - * - * @property blur - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value / (1/7000); - }, - set: function(value) { - - this.dirty = true; - this.uniforms.blur.value = (1/7000) * value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/BlurYFilter.js b/app/Lib/Vendor/src/pixi/filters/BlurYFilter.js deleted file mode 100644 index 5aecfef..0000000 --- a/app/Lib/Vendor/src/pixi/filters/BlurYFilter.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The BlurYFilter applies a vertical Gaussian blur to an object. - * - * @class BlurYFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.BlurYFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float blur;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' vec4 sum = vec4(0.0);', - - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;', - ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;', - - ' gl_FragColor = sum;', - '}' - ]; -}; - -PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter; - -/** - * Sets the strength of both the blur. - * - * @property blur - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value / (1/7000); - }, - set: function(value) { - //this.padding = value; - this.uniforms.blur.value = (1/7000) * value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/ColorMatrixFilter.js b/app/Lib/Vendor/src/pixi/filters/ColorMatrixFilter.js deleted file mode 100644 index 8f1dcbe..0000000 --- a/app/Lib/Vendor/src/pixi/filters/ColorMatrixFilter.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA - * color and alpha values of every pixel on your displayObject to produce a result - * with a new set of RGBA color and alpha values. It's pretty powerful! - * - * @class ColorMatrixFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.ColorMatrixFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - matrix: {type: 'mat4', value: [1,0,0,0, - 0,1,0,0, - 0,0,1,0, - 0,0,0,1]} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float invert;', - 'uniform mat4 matrix;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', - // ' gl_FragColor = gl_FragColor;', - '}' - ]; -}; - -PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter; - -/** - * Sets the matrix of the color matrix filter - * - * @property matrix - * @type Array(Number) - * @default [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1] - */ -Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', { - get: function() { - return this.uniforms.matrix.value; - }, - set: function(value) { - this.uniforms.matrix.value = value; - } -}); \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/filters/ColorStepFilter.js b/app/Lib/Vendor/src/pixi/filters/ColorStepFilter.js deleted file mode 100644 index 9481acd..0000000 --- a/app/Lib/Vendor/src/pixi/filters/ColorStepFilter.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This lowers the color depth of your image by the given amount, producing an image with a smaller palette. - * - * @class ColorStepFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.ColorStepFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - step: {type: '1f', value: 5} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'uniform float step;', - - 'void main(void) {', - ' vec4 color = texture2D(uSampler, vTextureCoord);', - ' color = floor(color * step) / step;', - ' gl_FragColor = color;', - '}' - ]; -}; - -PIXI.ColorStepFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.ColorStepFilter.prototype.constructor = PIXI.ColorStepFilter; - -/** - * The number of steps to reduce the palette by. - * - * @property step - * @type Number - */ -Object.defineProperty(PIXI.ColorStepFilter.prototype, 'step', { - get: function() { - return this.uniforms.step.value; - }, - set: function(value) { - this.uniforms.step.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/ConvolutionFilter.js b/app/Lib/Vendor/src/pixi/filters/ConvolutionFilter.js deleted file mode 100644 index 1d180d7..0000000 --- a/app/Lib/Vendor/src/pixi/filters/ConvolutionFilter.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * The ConvolutionFilter class applies a matrix convolution filter effect. - * A convolution combines pixels in the input image with neighboring pixels to produce a new image. - * A wide variety of image effects can be achieved through convolutions, including blurring, edge detection, sharpening, embossing, and beveling. - * The matrix should be specified as a 9 point Array. See http://docs.gimp.org/en/plug-in-convmatrix.html for more info. - * - * @class ConvolutionFilter - * @extends AbstractFilter - * @constructor - * @param matrix {Array} An array of values used for matrix transformation. Specified as a 9 point Array. - * @param width {Number} Width of the object you are transforming - * @param height {Number} Height of the object you are transforming - */ -PIXI.ConvolutionFilter = function(matrix, width, height) -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - m : {type: '1fv', value: new PIXI.Float32Array(matrix)}, - texelSizeX: {type: '1f', value: 1 / width}, - texelSizeY: {type: '1f', value: 1 / height} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying mediump vec2 vTextureCoord;', - 'uniform sampler2D texture;', - 'uniform float texelSizeX;', - 'uniform float texelSizeY;', - 'uniform float m[9];', - - 'vec2 px = vec2(texelSizeX, texelSizeY);', - - 'void main(void) {', - 'vec4 c11 = texture2D(texture, vTextureCoord - px);', // top left - 'vec4 c12 = texture2D(texture, vec2(vTextureCoord.x, vTextureCoord.y - px.y));', // top center - 'vec4 c13 = texture2D(texture, vec2(vTextureCoord.x + px.x, vTextureCoord.y - px.y));', // top right - - 'vec4 c21 = texture2D(texture, vec2(vTextureCoord.x - px.x, vTextureCoord.y) );', // mid left - 'vec4 c22 = texture2D(texture, vTextureCoord);', // mid center - 'vec4 c23 = texture2D(texture, vec2(vTextureCoord.x + px.x, vTextureCoord.y) );', // mid right - - 'vec4 c31 = texture2D(texture, vec2(vTextureCoord.x - px.x, vTextureCoord.y + px.y) );', // bottom left - 'vec4 c32 = texture2D(texture, vec2(vTextureCoord.x, vTextureCoord.y + px.y) );', // bottom center - 'vec4 c33 = texture2D(texture, vTextureCoord + px );', // bottom right - - 'gl_FragColor = ', - 'c11 * m[0] + c12 * m[1] + c22 * m[2] +', - 'c21 * m[3] + c22 * m[4] + c23 * m[5] +', - 'c31 * m[6] + c32 * m[7] + c33 * m[8];', - 'gl_FragColor.a = c22.a;', - '}' - ]; - -}; - -PIXI.ConvolutionFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.ConvolutionFilter.prototype.constructor = PIXI.ConvolutionFilter; - -/** - * An array of values used for matrix transformation. Specified as a 9 point Array. - * - * @property matrix - * @type Array - */ -Object.defineProperty(PIXI.ConvolutionFilter.prototype, 'matrix', { - get: function() { - return this.uniforms.m.value; - }, - set: function(value) { - this.uniforms.m.value = new PIXI.Float32Array(value); - } -}); - -/** - * Width of the object you are transforming - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.ConvolutionFilter.prototype, 'width', { - get: function() { - return this.uniforms.texelSizeX.value; - }, - set: function(value) { - this.uniforms.texelSizeX.value = 1/value; - } -}); - -/** - * Height of the object you are transforming - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.ConvolutionFilter.prototype, 'height', { - get: function() { - return this.uniforms.texelSizeY.value; - }, - set: function(value) { - this.uniforms.texelSizeY.value = 1/value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/CrossHatchFilter.js b/app/Lib/Vendor/src/pixi/filters/CrossHatchFilter.js deleted file mode 100644 index 4b9f381..0000000 --- a/app/Lib/Vendor/src/pixi/filters/CrossHatchFilter.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Cross Hatch effect filter. - * - * @class CrossHatchFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.CrossHatchFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1 / 512} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float blur;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);', - - ' gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);', - - ' if (lum < 1.00) {', - ' if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {', - ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', - ' }', - ' }', - - ' if (lum < 0.75) {', - ' if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {', - ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', - ' }', - ' }', - - ' if (lum < 0.50) {', - ' if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {', - ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', - ' }', - ' }', - - ' if (lum < 0.3) {', - ' if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {', - ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', - ' }', - ' }', - '}' - ]; -}; - -PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.CrossHatchFilter.prototype.constructor = PIXI.CrossHatchFilter; - -/** - * Sets the strength of both the blur. - * - * @property blur - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value / (1/7000); - }, - set: function(value) { - //this.padding = value; - this.uniforms.blur.value = (1/7000) * value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/DisplacementFilter.js b/app/Lib/Vendor/src/pixi/filters/DisplacementFilter.js deleted file mode 100644 index 803b7b8..0000000 --- a/app/Lib/Vendor/src/pixi/filters/DisplacementFilter.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. - * You can use this filter to apply all manor of crazy warping effects - * Currently the r property of the texture is used offset the x and the g property of the texture is used to offset the y. - * - * @class DisplacementFilter - * @extends AbstractFilter - * @constructor - * @param texture {Texture} The texture used for the displacement map * must be power of 2 texture at the moment - */ -PIXI.DisplacementFilter = function(texture) -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - texture.baseTexture._powerOf2 = true; - - // set the uniforms - this.uniforms = { - displacementMap: {type: 'sampler2D', value:texture}, - scale: {type: '2f', value:{x:30, y:30}}, - offset: {type: '2f', value:{x:0, y:0}}, - mapDimensions: {type: '2f', value:{x:1, y:5112}}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; - - if(texture.baseTexture.hasLoaded) - { - this.uniforms.mapDimensions.value.x = texture.width; - this.uniforms.mapDimensions.value.y = texture.height; - } - else - { - this.boundLoadedFunction = this.onTextureLoaded.bind(this); - - texture.baseTexture.on('loaded', this.boundLoadedFunction); - } - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D displacementMap;', - 'uniform sampler2D uSampler;', - 'uniform vec2 scale;', - 'uniform vec2 offset;', - 'uniform vec4 dimensions;', - 'uniform vec2 mapDimensions;',// = vec2(256.0, 256.0);', - // 'const vec2 textureDimensions = vec2(750.0, 750.0);', - - 'void main(void) {', - ' vec2 mapCords = vTextureCoord.xy;', - //' mapCords -= ;', - ' mapCords += (dimensions.zw + offset)/ dimensions.xy ;', - ' mapCords.y *= -1.0;', - ' mapCords.y += 1.0;', - ' vec2 matSample = texture2D(displacementMap, mapCords).xy;', - ' matSample -= 0.5;', - ' matSample *= scale;', - ' matSample /= mapDimensions;', - ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));', - ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);', - ' vec2 cord = vTextureCoord;', - - //' gl_FragColor = texture2D(displacementMap, cord);', - // ' gl_FragColor = gl_FragColor;', - '}' - ]; -}; - -PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter; - -/** - * Sets the map dimensions uniforms when the texture becomes available. - * - * @method onTextureLoaded - */ -PIXI.DisplacementFilter.prototype.onTextureLoaded = function() -{ - this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; - this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; - - this.uniforms.displacementMap.value.baseTexture.off('loaded', this.boundLoadedFunction); -}; - -/** - * The texture used for the displacement map. Must be power of 2 texture. - * - * @property map - * @type Texture - */ -Object.defineProperty(PIXI.DisplacementFilter.prototype, 'map', { - get: function() { - return this.uniforms.displacementMap.value; - }, - set: function(value) { - this.uniforms.displacementMap.value = value; - } -}); - -/** - * The multiplier used to scale the displacement result from the map calculation. - * - * @property scale - * @type Point - */ -Object.defineProperty(PIXI.DisplacementFilter.prototype, 'scale', { - get: function() { - return this.uniforms.scale.value; - }, - set: function(value) { - this.uniforms.scale.value = value; - } -}); - -/** - * The offset used to move the displacement map. - * - * @property offset - * @type Point - */ -Object.defineProperty(PIXI.DisplacementFilter.prototype, 'offset', { - get: function() { - return this.uniforms.offset.value; - }, - set: function(value) { - this.uniforms.offset.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/DotScreenFilter.js b/app/Lib/Vendor/src/pixi/filters/DotScreenFilter.js deleted file mode 100644 index 5a7462f..0000000 --- a/app/Lib/Vendor/src/pixi/filters/DotScreenFilter.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js - */ - -/** - * This filter applies a dotscreen effect making display objects appear to be made out of black and white halftone dots like an old printer. - * - * @class DotScreenFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.DotScreenFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - scale: {type: '1f', value:1}, - angle: {type: '1f', value:5}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform vec4 dimensions;', - 'uniform sampler2D uSampler;', - - 'uniform float angle;', - 'uniform float scale;', - - 'float pattern() {', - ' float s = sin(angle), c = cos(angle);', - ' vec2 tex = vTextureCoord * dimensions.xy;', - ' vec2 point = vec2(', - ' c * tex.x - s * tex.y,', - ' s * tex.x + c * tex.y', - ' ) * scale;', - ' return (sin(point.x) * sin(point.y)) * 4.0;', - '}', - - 'void main() {', - ' vec4 color = texture2D(uSampler, vTextureCoord);', - ' float average = (color.r + color.g + color.b) / 3.0;', - ' gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);', - '}' - ]; -}; - -PIXI.DotScreenFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter; - -/** - * The scale of the effect. - * @property scale - * @type Number - */ -Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', { - get: function() { - return this.uniforms.scale.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.scale.value = value; - } -}); - -/** - * The radius of the effect. - * @property angle - * @type Number - */ -Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', { - get: function() { - return this.uniforms.angle.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.angle.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/FilterBlock.js b/app/Lib/Vendor/src/pixi/filters/FilterBlock.js deleted file mode 100644 index fbdacc2..0000000 --- a/app/Lib/Vendor/src/pixi/filters/FilterBlock.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A target and pass info object for filters. - * - * @class FilterBlock - * @constructor - */ -PIXI.FilterBlock = function() -{ - /** - * The visible state of this FilterBlock. - * - * @property visible - * @type Boolean - */ - this.visible = true; - - /** - * The renderable state of this FilterBlock. - * - * @property renderable - * @type Boolean - */ - this.renderable = true; -}; - -PIXI.FilterBlock.prototype.constructor = PIXI.FilterBlock; diff --git a/app/Lib/Vendor/src/pixi/filters/GrayFilter.js b/app/Lib/Vendor/src/pixi/filters/GrayFilter.js deleted file mode 100644 index 201d026..0000000 --- a/app/Lib/Vendor/src/pixi/filters/GrayFilter.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This greyscales the palette of your Display Objects. - * - * @class GrayFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.GrayFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - gray: {type: '1f', value: 1} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'uniform float gray;', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord);', - ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', - // ' gl_FragColor = gl_FragColor;', - '}' - ]; -}; - -PIXI.GrayFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.GrayFilter.prototype.constructor = PIXI.GrayFilter; - -/** - * The strength of the gray. 1 will make the object black and white, 0 will make the object its normal color. - * @property gray - * @type Number - */ -Object.defineProperty(PIXI.GrayFilter.prototype, 'gray', { - get: function() { - return this.uniforms.gray.value; - }, - set: function(value) { - this.uniforms.gray.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/InvertFilter.js b/app/Lib/Vendor/src/pixi/filters/InvertFilter.js deleted file mode 100644 index 7f5e84c..0000000 --- a/app/Lib/Vendor/src/pixi/filters/InvertFilter.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This inverts your Display Objects colors. - * - * @class InvertFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.InvertFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - invert: {type: '1f', value: 1} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float invert;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord);', - ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', - //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', - // ' gl_FragColor = gl_FragColor * vColor;', - '}' - ]; -}; - -PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter; - -/** - * The strength of the invert. 1 will fully invert the colors, 0 will make the object its normal color - * @property invert - * @type Number -*/ -Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', { - get: function() { - return this.uniforms.invert.value; - }, - set: function(value) { - this.uniforms.invert.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/NoiseFilter.js b/app/Lib/Vendor/src/pixi/filters/NoiseFilter.js deleted file mode 100644 index ff248e4..0000000 --- a/app/Lib/Vendor/src/pixi/filters/NoiseFilter.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @author Vico @vicocotea - * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/noise.js - */ - -/** - * A Noise effect filter. - * - * @class NoiseFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.NoiseFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - noise: {type: '1f', value: 0.5} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'uniform sampler2D uSampler;', - 'uniform float noise;', - 'varying vec2 vTextureCoord;', - - 'float rand(vec2 co) {', - ' return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);', - '}', - 'void main() {', - ' vec4 color = texture2D(uSampler, vTextureCoord);', - - ' float diff = (rand(vTextureCoord) - 0.5) * noise;', - ' color.r += diff;', - ' color.g += diff;', - ' color.b += diff;', - - ' gl_FragColor = color;', - '}' - ]; -}; - -PIXI.NoiseFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.NoiseFilter.prototype.constructor = PIXI.NoiseFilter; - -/** - * The amount of noise to apply. - * @property noise - * @type Number -*/ -Object.defineProperty(PIXI.NoiseFilter.prototype, 'noise', { - get: function() { - return this.uniforms.noise.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.noise.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/NormalMapFilter.js b/app/Lib/Vendor/src/pixi/filters/NormalMapFilter.js deleted file mode 100644 index e686905..0000000 --- a/app/Lib/Vendor/src/pixi/filters/NormalMapFilter.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * The NormalMapFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. - * You can use this filter to apply all manor of crazy warping effects - * Currently the r property of the texture is used offset the x and the g property of the texture is used to offset the y. - * - * @class NormalMapFilter - * @extends AbstractFilter - * @constructor - * @param texture {Texture} The texture used for the displacement map * must be power of 2 texture at the moment - */ -PIXI.NormalMapFilter = function(texture) -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - texture.baseTexture._powerOf2 = true; - - // set the uniforms - this.uniforms = { - displacementMap: {type: 'sampler2D', value:texture}, - scale: {type: '2f', value:{x:15, y:15}}, - offset: {type: '2f', value:{x:0, y:0}}, - mapDimensions: {type: '2f', value:{x:1, y:1}}, - dimensions: {type: '4f', value:[0,0,0,0]}, - // LightDir: {type: 'f3', value:[0, 1, 0]}, - LightPos: {type: '3f', value:[0, 1, 0]} - }; - - - if(texture.baseTexture.hasLoaded) - { - this.uniforms.mapDimensions.value.x = texture.width; - this.uniforms.mapDimensions.value.y = texture.height; - } - else - { - this.boundLoadedFunction = this.onTextureLoaded.bind(this); - - texture.baseTexture.on("loaded", this.boundLoadedFunction); - } - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D displacementMap;", - "uniform sampler2D uSampler;", - - "uniform vec4 dimensions;", - - "const vec2 Resolution = vec2(1.0,1.0);", //resolution of screen - "uniform vec3 LightPos;", //light position, normalized - "const vec4 LightColor = vec4(1.0, 1.0, 1.0, 1.0);", //light RGBA -- alpha is intensity - "const vec4 AmbientColor = vec4(1.0, 1.0, 1.0, 0.5);", //ambient RGBA -- alpha is intensity - "const vec3 Falloff = vec3(0.0, 1.0, 0.2);", //attenuation coefficients - - "uniform vec3 LightDir;",//" = vec3(1.0, 0.0, 1.0);", - - - "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - - - "void main(void) {", - "vec2 mapCords = vTextureCoord.xy;", - - "vec4 color = texture2D(uSampler, vTextureCoord.st);", - "vec3 nColor = texture2D(displacementMap, vTextureCoord.st).rgb;", - - - "mapCords *= vec2(dimensions.x/512.0, dimensions.y/512.0);", - - "mapCords.y *= -1.0;", - "mapCords.y += 1.0;", - - //RGBA of our diffuse color - "vec4 DiffuseColor = texture2D(uSampler, vTextureCoord);", - - //RGB of our normal map - "vec3 NormalMap = texture2D(displacementMap, mapCords).rgb;", - - //The delta position of light - //"vec3 LightDir = vec3(LightPos.xy - (gl_FragCoord.xy / Resolution.xy), LightPos.z);", - "vec3 LightDir = vec3(LightPos.xy - (mapCords.xy), LightPos.z);", - //Correct for aspect ratio - //"LightDir.x *= Resolution.x / Resolution.y;", - - //Determine distance (used for attenuation) BEFORE we normalize our LightDir - "float D = length(LightDir);", - - //normalize our vectors - "vec3 N = normalize(NormalMap * 2.0 - 1.0);", - "vec3 L = normalize(LightDir);", - - //Pre-multiply light color with intensity - //Then perform "N dot L" to determine our diffuse term - "vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0);", - - //pre-multiply ambient color with intensity - "vec3 Ambient = AmbientColor.rgb * AmbientColor.a;", - - //calculate attenuation - "float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D) );", - - //the calculation which brings it all together - "vec3 Intensity = Ambient + Diffuse * Attenuation;", - "vec3 FinalColor = DiffuseColor.rgb * Intensity;", - "gl_FragColor = vColor * vec4(FinalColor, DiffuseColor.a);", - //"gl_FragColor = vec4(1.0, 0.0, 0.0, Attenuation);",//vColor * vec4(FinalColor, DiffuseColor.a);", - /* - // normalise color - "vec3 normal = normalize(nColor * 2.0 - 1.0);", - - "vec3 deltaPos = vec3( (light.xy - gl_FragCoord.xy) / resolution.xy, light.z );", - - "float lambert = clamp(dot(normal, lightDir), 0.0, 1.0);", - - "float d = sqrt(dot(deltaPos, deltaPos));", - "float att = 1.0 / ( attenuation.x + (attenuation.y*d) + (attenuation.z*d*d) );", - - "vec3 result = (ambientColor * ambientIntensity) + (lightColor.rgb * lambert) * att;", - "result *= color.rgb;", - - "gl_FragColor = vec4(result, 1.0);",*/ - - - - "}" - ]; - -} - -PIXI.NormalMapFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.NormalMapFilter.prototype.constructor = PIXI.NormalMapFilter; - -/** - * Sets the map dimensions uniforms when the texture becomes available. - * - * @method onTextureLoaded - */ -PIXI.NormalMapFilter.prototype.onTextureLoaded = function() -{ - this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; - this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; - - this.uniforms.displacementMap.value.baseTexture.off("loaded", this.boundLoadedFunction) -}; - -/** - * The texture used for the displacement map. Must be power of 2 texture. - * - * @property map - * @type Texture - */ -Object.defineProperty(PIXI.NormalMapFilter.prototype, 'map', { - get: function() { - return this.uniforms.displacementMap.value; - }, - set: function(value) { - this.uniforms.displacementMap.value = value; - } -}); - -/** - * The multiplier used to scale the displacement result from the map calculation. - * - * @property scale - * @type Point - */ -Object.defineProperty(PIXI.NormalMapFilter.prototype, 'scale', { - get: function() { - return this.uniforms.scale.value; - }, - set: function(value) { - this.uniforms.scale.value = value; - } -}); - -/** - * The offset used to move the displacement map. - * - * @property offset - * @type Point - */ -Object.defineProperty(PIXI.NormalMapFilter.prototype, 'offset', { - get: function() { - return this.uniforms.offset.value; - }, - set: function(value) { - this.uniforms.offset.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/PixelateFilter.js b/app/Lib/Vendor/src/pixi/filters/PixelateFilter.js deleted file mode 100644 index 2a3127d..0000000 --- a/app/Lib/Vendor/src/pixi/filters/PixelateFilter.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This filter applies a pixelate effect making display objects appear 'blocky'. - * - * @class PixelateFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.PixelateFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - invert: {type: '1f', value: 0}, - dimensions: {type: '4fv', value:new PIXI.Float32Array([10000, 100, 10, 10])}, - pixelSize: {type: '2f', value:{x:10, y:10}} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform vec2 testDim;', - 'uniform vec4 dimensions;', - 'uniform vec2 pixelSize;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' vec2 coord = vTextureCoord;', - - ' vec2 size = dimensions.xy/pixelSize;', - - ' vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;', - ' gl_FragColor = texture2D(uSampler, color);', - '}' - ]; -}; - -PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter; - -/** - * This a point that describes the size of the blocks. x is the width of the block and y is the height. - * - * @property size - * @type Point - */ -Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', { - get: function() { - return this.uniforms.pixelSize.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.pixelSize.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/RGBSplitFilter.js b/app/Lib/Vendor/src/pixi/filters/RGBSplitFilter.js deleted file mode 100644 index 7169637..0000000 --- a/app/Lib/Vendor/src/pixi/filters/RGBSplitFilter.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * An RGB Split Filter. - * - * @class RGBSplitFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.RGBSplitFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - red: {type: '2f', value: {x:20, y:20}}, - green: {type: '2f', value: {x:-20, y:20}}, - blue: {type: '2f', value: {x:20, y:-20}}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform vec2 red;', - 'uniform vec2 green;', - 'uniform vec2 blue;', - 'uniform vec4 dimensions;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;', - ' gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;', - ' gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;', - ' gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;', - '}' - ]; -}; - -PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter; - -/** - * Red channel offset. - * - * @property red - * @type Point - */ -Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'red', { - get: function() { - return this.uniforms.red.value; - }, - set: function(value) { - this.uniforms.red.value = value; - } -}); - -/** - * Green channel offset. - * - * @property green - * @type Point - */ -Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'green', { - get: function() { - return this.uniforms.green.value; - }, - set: function(value) { - this.uniforms.green.value = value; - } -}); - -/** - * Blue offset. - * - * @property blue - * @type Point - */ -Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'blue', { - get: function() { - return this.uniforms.blue.value; - }, - set: function(value) { - this.uniforms.blue.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/SepiaFilter.js b/app/Lib/Vendor/src/pixi/filters/SepiaFilter.js deleted file mode 100644 index 5596e53..0000000 --- a/app/Lib/Vendor/src/pixi/filters/SepiaFilter.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This applies a sepia effect to your Display Objects. - * - * @class SepiaFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.SepiaFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - sepia: {type: '1f', value: 1} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform float sepia;', - 'uniform sampler2D uSampler;', - - 'const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord);', - ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', - // ' gl_FragColor = gl_FragColor * vColor;', - '}' - ]; -}; - -PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter; - -/** - * The strength of the sepia. 1 will apply the full sepia effect, 0 will make the object its normal color. - * @property sepia - * @type Number -*/ -Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', { - get: function() { - return this.uniforms.sepia.value; - }, - set: function(value) { - this.uniforms.sepia.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/SmartBlurFilter.js b/app/Lib/Vendor/src/pixi/filters/SmartBlurFilter.js deleted file mode 100644 index 44a47f4..0000000 --- a/app/Lib/Vendor/src/pixi/filters/SmartBlurFilter.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Smart Blur Filter. - * - * @class SmartBlurFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.SmartBlurFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'uniform sampler2D uSampler;', - //'uniform vec2 delta;', - 'const vec2 delta = vec2(1.0/10.0, 0.0);', - //'uniform float darkness;', - - 'float random(vec3 scale, float seed) {', - ' return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);', - '}', - - - 'void main(void) {', - ' vec4 color = vec4(0.0);', - ' float total = 0.0;', - - ' float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);', - - ' for (float t = -30.0; t <= 30.0; t++) {', - ' float percent = (t + offset - 0.5) / 30.0;', - ' float weight = 1.0 - abs(percent);', - ' vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);', - ' sample.rgb *= sample.a;', - ' color += sample * weight;', - ' total += weight;', - ' }', - - ' gl_FragColor = color / total;', - ' gl_FragColor.rgb /= gl_FragColor.a + 0.00001;', - //' gl_FragColor.rgb *= darkness;', - '}' - ]; -}; - -PIXI.SmartBlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.SmartBlurFilter.prototype.constructor = PIXI.SmartBlurFilter; - -/** - * The strength of the blur. - * - * @property blur - * @type Number - * @default 2 - */ -Object.defineProperty(PIXI.SmartBlurFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value; - }, - set: function(value) { - this.uniforms.blur.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/TiltShiftFilter.js b/app/Lib/Vendor/src/pixi/filters/TiltShiftFilter.js deleted file mode 100644 index 2eb3776..0000000 --- a/app/Lib/Vendor/src/pixi/filters/TiltShiftFilter.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @author Vico @vicocotea - * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/ - */ - -/** - * A TiltShift Filter. Manages the pass of both a TiltShiftXFilter and TiltShiftYFilter. - * - * @class TiltShiftFilter - * @constructor - */ -PIXI.TiltShiftFilter = function() -{ - this.tiltShiftXFilter = new PIXI.TiltShiftXFilter(); - this.tiltShiftYFilter = new PIXI.TiltShiftYFilter(); - this.tiltShiftXFilter.updateDelta(); - this.tiltShiftXFilter.updateDelta(); - - this.passes = [this.tiltShiftXFilter, this.tiltShiftYFilter]; -}; - -PIXI.TiltShiftFilter.prototype.constructor = PIXI.TiltShiftFilter; - -/** - * The strength of the blur. - * - * @property blur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftFilter.prototype, 'blur', { - get: function() { - return this.tiltShiftXFilter.blur; - }, - set: function(value) { - this.tiltShiftXFilter.blur = this.tiltShiftYFilter.blur = value; - } -}); - -/** - * The strength of the gradient blur. - * - * @property gradientBlur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftFilter.prototype, 'gradientBlur', { - get: function() { - return this.tiltShiftXFilter.gradientBlur; - }, - set: function(value) { - this.tiltShiftXFilter.gradientBlur = this.tiltShiftYFilter.gradientBlur = value; - } -}); - -/** - * The Y value to start the effect at. - * - * @property start - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftFilter.prototype, 'start', { - get: function() { - return this.tiltShiftXFilter.start; - }, - set: function(value) { - this.tiltShiftXFilter.start = this.tiltShiftYFilter.start = value; - } -}); - -/** - * The Y value to end the effect at. - * - * @property end - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftFilter.prototype, 'end', { - get: function() { - return this.tiltShiftXFilter.end; - }, - set: function(value) { - this.tiltShiftXFilter.end = this.tiltShiftYFilter.end = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/filters/TiltShiftXFilter.js b/app/Lib/Vendor/src/pixi/filters/TiltShiftXFilter.js deleted file mode 100644 index 29d8f38..0000000 --- a/app/Lib/Vendor/src/pixi/filters/TiltShiftXFilter.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @author Vico @vicocotea - * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/ - */ - -/** - * A TiltShiftXFilter. - * - * @class TiltShiftXFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.TiltShiftXFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 100.0}, - gradientBlur: {type: '1f', value: 600.0}, - start: {type: '2f', value:{x:0, y:window.screenHeight / 2}}, - end: {type: '2f', value:{x:600, y:window.screenHeight / 2}}, - delta: {type: '2f', value:{x:30, y:30}}, - texSize: {type: '2f', value:{x:window.screenWidth, y:window.screenHeight}} - }; - - this.updateDelta(); - - this.fragmentSrc = [ - 'precision mediump float;', - 'uniform sampler2D uSampler;', - 'uniform float blur;', - 'uniform float gradientBlur;', - 'uniform vec2 start;', - 'uniform vec2 end;', - 'uniform vec2 delta;', - 'uniform vec2 texSize;', - 'varying vec2 vTextureCoord;', - - 'float random(vec3 scale, float seed) {', - ' return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);', - '}', - - 'void main(void) {', - ' vec4 color = vec4(0.0);', - ' float total = 0.0;', - - ' float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);', - ' vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));', - ' float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * texSize - start, normal)) / gradientBlur) * blur;', - - ' for (float t = -30.0; t <= 30.0; t++) {', - ' float percent = (t + offset - 0.5) / 30.0;', - ' float weight = 1.0 - abs(percent);', - ' vec4 sample = texture2D(uSampler, vTextureCoord + delta / texSize * percent * radius);', - ' sample.rgb *= sample.a;', - ' color += sample * weight;', - ' total += weight;', - ' }', - - ' gl_FragColor = color / total;', - ' gl_FragColor.rgb /= gl_FragColor.a + 0.00001;', - '}' - ]; -}; - -PIXI.TiltShiftXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.TiltShiftXFilter.prototype.constructor = PIXI.TiltShiftXFilter; - -/** - * The strength of the blur. - * - * @property blur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftXFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.blur.value = value; - } -}); - -/** - * The strength of the gradient blur. - * - * @property gradientBlur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftXFilter.prototype, 'gradientBlur', { - get: function() { - return this.uniforms.gradientBlur.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.gradientBlur.value = value; - } -}); - -/** - * The X value to start the effect at. - * - * @property start - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftXFilter.prototype, 'start', { - get: function() { - return this.uniforms.start.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.start.value = value; - this.updateDelta(); - } -}); - -/** - * The X value to end the effect at. - * - * @property end - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftXFilter.prototype, 'end', { - get: function() { - return this.uniforms.end.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.end.value = value; - this.updateDelta(); - } -}); - -/** - * Updates the filter delta values. - * - * @method updateDelta - */ -PIXI.TiltShiftXFilter.prototype.updateDelta = function(){ - var dx = this.uniforms.end.value.x - this.uniforms.start.value.x; - var dy = this.uniforms.end.value.y - this.uniforms.start.value.y; - var d = Math.sqrt(dx * dx + dy * dy); - this.uniforms.delta.value.x = dx / d; - this.uniforms.delta.value.y = dy / d; -}; diff --git a/app/Lib/Vendor/src/pixi/filters/TiltShiftYFilter.js b/app/Lib/Vendor/src/pixi/filters/TiltShiftYFilter.js deleted file mode 100644 index 3a92851..0000000 --- a/app/Lib/Vendor/src/pixi/filters/TiltShiftYFilter.js +++ /dev/null @@ -1,149 +0,0 @@ -/** - * @author Vico @vicocotea - * original filter https://github.com/evanw/glfx.js/blob/master/src/filters/blur/tiltshift.js by Evan Wallace : http://madebyevan.com/ - */ - -/** - * A TiltShiftYFilter. - * - * @class TiltShiftYFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.TiltShiftYFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 100.0}, - gradientBlur: {type: '1f', value: 600.0}, - start: {type: '2f', value:{x:0, y:window.screenHeight / 2}}, - end: {type: '2f', value:{x:600, y:window.screenHeight / 2}}, - delta: {type: '2f', value:{x:30, y:30}}, - texSize: {type: '2f', value:{x:window.screenWidth, y:window.screenHeight}} - }; - - this.updateDelta(); - - this.fragmentSrc = [ - 'precision mediump float;', - 'uniform sampler2D uSampler;', - 'uniform float blur;', - 'uniform float gradientBlur;', - 'uniform vec2 start;', - 'uniform vec2 end;', - 'uniform vec2 delta;', - 'uniform vec2 texSize;', - 'varying vec2 vTextureCoord;', - - 'float random(vec3 scale, float seed) {', - ' return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);', - '}', - - 'void main(void) {', - ' vec4 color = vec4(0.0);', - ' float total = 0.0;', - - ' float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);', - ' vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));', - ' float radius = smoothstep(0.0, 1.0, abs(dot(vTextureCoord * texSize - start, normal)) / gradientBlur) * blur;', - - ' for (float t = -30.0; t <= 30.0; t++) {', - ' float percent = (t + offset - 0.5) / 30.0;', - ' float weight = 1.0 - abs(percent);', - ' vec4 sample = texture2D(uSampler, vTextureCoord + delta / texSize * percent * radius);', - ' sample.rgb *= sample.a;', - ' color += sample * weight;', - ' total += weight;', - ' }', - - ' gl_FragColor = color / total;', - ' gl_FragColor.rgb /= gl_FragColor.a + 0.00001;', - '}' - ]; -}; - -PIXI.TiltShiftYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.TiltShiftYFilter.prototype.constructor = PIXI.TiltShiftYFilter; - -/** - * The strength of the blur. - * - * @property blur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftYFilter.prototype, 'blur', { - get: function() { - return this.uniforms.blur.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.blur.value = value; - } -}); - -/** - * The strength of the gradient blur. - * - * @property gradientBlur - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftYFilter.prototype, 'gradientBlur', { - get: function() { - return this.uniforms.gradientBlur.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.gradientBlur.value = value; - } -}); - -/** - * The Y value to start the effect at. - * - * @property start - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftYFilter.prototype, 'start', { - get: function() { - return this.uniforms.start.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.start.value = value; - this.updateDelta(); - } -}); - -/** - * The Y value to end the effect at. - * - * @property end - * @type Number - */ -Object.defineProperty(PIXI.TiltShiftYFilter.prototype, 'end', { - get: function() { - return this.uniforms.end.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.end.value = value; - this.updateDelta(); - } -}); - -/** - * Updates the filter delta values. - * - * @method updateDelta - */ -PIXI.TiltShiftYFilter.prototype.updateDelta = function(){ - var dx = this.uniforms.end.value.x - this.uniforms.start.value.x; - var dy = this.uniforms.end.value.y - this.uniforms.start.value.y; - var d = Math.sqrt(dx * dx + dy * dy); - this.uniforms.delta.value.x = -dy / d; - this.uniforms.delta.value.y = dx / d; -}; diff --git a/app/Lib/Vendor/src/pixi/filters/TwistFilter.js b/app/Lib/Vendor/src/pixi/filters/TwistFilter.js deleted file mode 100644 index 08a3122..0000000 --- a/app/Lib/Vendor/src/pixi/filters/TwistFilter.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This filter applies a twist effect making display objects appear twisted in the given direction. - * - * @class TwistFilter - * @extends AbstractFilter - * @constructor - */ -PIXI.TwistFilter = function() -{ - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - radius: {type: '1f', value:0.5}, - angle: {type: '1f', value:5}, - offset: {type: '2f', value:{x:0.5, y:0.5}} - }; - - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform vec4 dimensions;', - 'uniform sampler2D uSampler;', - - 'uniform float radius;', - 'uniform float angle;', - 'uniform vec2 offset;', - - 'void main(void) {', - ' vec2 coord = vTextureCoord - offset;', - ' float distance = length(coord);', - - ' if (distance < radius) {', - ' float ratio = (radius - distance) / radius;', - ' float angleMod = ratio * ratio * angle;', - ' float s = sin(angleMod);', - ' float c = cos(angleMod);', - ' coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);', - ' }', - - ' gl_FragColor = texture2D(uSampler, coord+offset);', - '}' - ]; -}; - -PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); -PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter; - -/** - * This point describes the the offset of the twist. - * - * @property offset - * @type Point - */ -Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', { - get: function() { - return this.uniforms.offset.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.offset.value = value; - } -}); - -/** - * This radius of the twist. - * - * @property radius - * @type Number - */ -Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', { - get: function() { - return this.uniforms.radius.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.radius.value = value; - } -}); - -/** - * This angle of the twist. - * - * @property angle - * @type Number - */ -Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', { - get: function() { - return this.uniforms.angle.value; - }, - set: function(value) { - this.dirty = true; - this.uniforms.angle.value = value; - } -}); diff --git a/app/Lib/Vendor/src/pixi/geom/Circle.js b/app/Lib/Vendor/src/pixi/geom/Circle.js deleted file mode 100644 index 541e0fe..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Circle.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @author Chad Engler - */ - -/** - * The Circle object can be used to specify a hit area for displayObjects - * - * @class Circle - * @constructor - * @param x {Number} The X coordinate of the center of this circle - * @param y {Number} The Y coordinate of the center of this circle - * @param radius {Number} The radius of the circle - */ -PIXI.Circle = function(x, y, radius) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property radius - * @type Number - * @default 0 - */ - this.radius = radius || 0; -}; - -/** - * Creates a clone of this Circle instance - * - * @method clone - * @return {Circle} a copy of the Circle - */ -PIXI.Circle.prototype.clone = function() -{ - return new PIXI.Circle(this.x, this.y, this.radius); -}; - -/** - * Checks whether the x and y coordinates given are contained within this circle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Circle - */ -PIXI.Circle.prototype.contains = function(x, y) -{ - if(this.radius <= 0) - return false; - - var dx = (this.x - x), - dy = (this.y - y), - r2 = this.radius * this.radius; - - dx *= dx; - dy *= dy; - - return (dx + dy <= r2); -}; - -/** -* Returns the framing rectangle of the circle as a PIXI.Rectangle object -* -* @method getBounds -* @return {Rectangle} the framing rectangle -*/ -PIXI.Circle.prototype.getBounds = function() -{ - return new PIXI.Rectangle(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2); -}; - -// constructor -PIXI.Circle.prototype.constructor = PIXI.Circle; diff --git a/app/Lib/Vendor/src/pixi/geom/Ellipse.js b/app/Lib/Vendor/src/pixi/geom/Ellipse.js deleted file mode 100644 index 0dd71f3..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Ellipse.js +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @author Chad Engler - */ - -/** - * The Ellipse object can be used to specify a hit area for displayObjects - * - * @class Ellipse - * @constructor - * @param x {Number} The X coordinate of the center of the ellipse - * @param y {Number} The Y coordinate of the center of the ellipse - * @param width {Number} The half width of this ellipse - * @param height {Number} The half height of this ellipse - */ -PIXI.Ellipse = function(x, y, width, height) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -}; - -/** - * Creates a clone of this Ellipse instance - * - * @method clone - * @return {Ellipse} a copy of the ellipse - */ -PIXI.Ellipse.prototype.clone = function() -{ - return new PIXI.Ellipse(this.x, this.y, this.width, this.height); -}; - -/** - * Checks whether the x and y coordinates given are contained within this ellipse - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coords are within this ellipse - */ -PIXI.Ellipse.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - //normalize the coords to an ellipse with center 0,0 - var normx = ((x - this.x) / this.width), - normy = ((y - this.y) / this.height); - - normx *= normx; - normy *= normy; - - return (normx + normy <= 1); -}; - -/** -* Returns the framing rectangle of the ellipse as a PIXI.Rectangle object -* -* @method getBounds -* @return {Rectangle} the framing rectangle -*/ -PIXI.Ellipse.prototype.getBounds = function() -{ - return new PIXI.Rectangle(this.x - this.width, this.y - this.height, this.width, this.height); -}; - -// constructor -PIXI.Ellipse.prototype.constructor = PIXI.Ellipse; diff --git a/app/Lib/Vendor/src/pixi/geom/Matrix.js b/app/Lib/Vendor/src/pixi/geom/Matrix.js deleted file mode 100644 index b0f043f..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Matrix.js +++ /dev/null @@ -1,268 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The Matrix class is now an object, which makes it a lot faster, - * here is a representation of it : - * | a | b | tx| - * | c | d | ty| - * | 0 | 0 | 1 | - * - * @class Matrix - * @constructor - */ -PIXI.Matrix = function() -{ - /** - * @property a - * @type Number - * @default 1 - */ - this.a = 1; - - /** - * @property b - * @type Number - * @default 0 - */ - this.b = 0; - - /** - * @property c - * @type Number - * @default 0 - */ - this.c = 0; - - /** - * @property d - * @type Number - * @default 1 - */ - this.d = 1; - - /** - * @property tx - * @type Number - * @default 0 - */ - this.tx = 0; - - /** - * @property ty - * @type Number - * @default 0 - */ - this.ty = 0; -}; - -/** - * Creates a Matrix object based on the given array. The Element to Matrix mapping order is as follows: - * - * a = array[0] - * b = array[1] - * c = array[3] - * d = array[4] - * tx = array[2] - * ty = array[5] - * - * @method fromArray - * @param array {Array} The array that the matrix will be populated from. - */ -PIXI.Matrix.prototype.fromArray = function(array) -{ - this.a = array[0]; - this.b = array[1]; - this.c = array[3]; - this.d = array[4]; - this.tx = array[2]; - this.ty = array[5]; -}; - -/** - * Creates an array from the current Matrix object. - * - * @method toArray - * @param transpose {Boolean} Whether we need to transpose the matrix or not - * @return {Array} the newly created array which contains the matrix - */ -PIXI.Matrix.prototype.toArray = function(transpose) -{ - if(!this.array) this.array = new PIXI.Float32Array(9); - var array = this.array; - - if(transpose) - { - array[0] = this.a; - array[1] = this.b; - array[2] = 0; - array[3] = this.c; - array[4] = this.d; - array[5] = 0; - array[6] = this.tx; - array[7] = this.ty; - array[8] = 1; - } - else - { - array[0] = this.a; - array[1] = this.c; - array[2] = this.tx; - array[3] = this.b; - array[4] = this.d; - array[5] = this.ty; - array[6] = 0; - array[7] = 0; - array[8] = 1; - } - - return array; -}; - -/** - * Get a new position with the current transformation applied. - * Can be used to go from a child's coordinate space to the world coordinate space. (e.g. rendering) - * - * @method apply - * @param pos {Point} The origin - * @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input) - * @return {Point} The new point, transformed through this matrix - */ -PIXI.Matrix.prototype.apply = function(pos, newPos) -{ - newPos = newPos || new PIXI.Point(); - - newPos.x = this.a * pos.x + this.c * pos.y + this.tx; - newPos.y = this.b * pos.x + this.d * pos.y + this.ty; - - return newPos; -}; - -/** - * Get a new position with the inverse of the current transformation applied. - * Can be used to go from the world coordinate space to a child's coordinate space. (e.g. input) - * - * @method applyInverse - * @param pos {Point} The origin - * @param [newPos] {Point} The point that the new position is assigned to (allowed to be same as input) - * @return {Point} The new point, inverse-transformed through this matrix - */ -PIXI.Matrix.prototype.applyInverse = function(pos, newPos) -{ - newPos = newPos || new PIXI.Point(); - - var id = 1 / (this.a * this.d + this.c * -this.b); - - newPos.x = this.d * id * pos.x + -this.c * id * pos.y + (this.ty * this.c - this.tx * this.d) * id; - newPos.y = this.a * id * pos.y + -this.b * id * pos.x + (-this.ty * this.a + this.tx * this.b) * id; - - return newPos; -}; - -/** - * Translates the matrix on the x and y. - * - * @method translate - * @param {Number} x - * @param {Number} y - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.translate = function(x, y) -{ - this.tx += x; - this.ty += y; - - return this; -}; - -/** - * Applies a scale transformation to the matrix. - * - * @method scale - * @param {Number} x The amount to scale horizontally - * @param {Number} y The amount to scale vertically - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.scale = function(x, y) -{ - this.a *= x; - this.d *= y; - this.c *= x; - this.b *= y; - this.tx *= x; - this.ty *= y; - - return this; -}; - - -/** - * Applies a rotation transformation to the matrix. - * @method rotate - * @param {Number} angle The angle in radians. - * @return {Matrix} This matrix. Good for chaining method calls. - **/ -PIXI.Matrix.prototype.rotate = function(angle) -{ - var cos = Math.cos( angle ); - var sin = Math.sin( angle ); - - var a1 = this.a; - var c1 = this.c; - var tx1 = this.tx; - - this.a = a1 * cos-this.b * sin; - this.b = a1 * sin+this.b * cos; - this.c = c1 * cos-this.d * sin; - this.d = c1 * sin+this.d * cos; - this.tx = tx1 * cos - this.ty * sin; - this.ty = tx1 * sin + this.ty * cos; - - return this; -}; - -/** - * Appends the given Matrix to this Matrix. - * - * @method append - * @param {Matrix} matrix - * @return {Matrix} This matrix. Good for chaining method calls. - */ -PIXI.Matrix.prototype.append = function(matrix) -{ - var a1 = this.a; - var b1 = this.b; - var c1 = this.c; - var d1 = this.d; - - this.a = matrix.a * a1 + matrix.b * c1; - this.b = matrix.a * b1 + matrix.b * d1; - this.c = matrix.c * a1 + matrix.d * c1; - this.d = matrix.c * b1 + matrix.d * d1; - - this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx; - this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty; - - return this; -}; - -/** - * Resets this Matix to an identity (default) matrix. - * - * @method identity - * @return {Matrix} This matrix. Good for chaining method calls. - */ -PIXI.Matrix.prototype.identity = function() -{ - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.tx = 0; - this.ty = 0; - - return this; -}; - -PIXI.identityMatrix = new PIXI.Matrix(); diff --git a/app/Lib/Vendor/src/pixi/geom/Point.js b/app/Lib/Vendor/src/pixi/geom/Point.js deleted file mode 100644 index 2adcb13..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Point.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis. - * - * @class Point - * @constructor - * @param x {Number} position of the point on the x axis - * @param y {Number} position of the point on the y axis - */ -PIXI.Point = function(x, y) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; -}; - -/** - * Creates a clone of this point - * - * @method clone - * @return {Point} a copy of the point - */ -PIXI.Point.prototype.clone = function() -{ - return new PIXI.Point(this.x, this.y); -}; - -/** - * Sets the point to a new x and y position. - * If y is omitted, both x and y will be set to x. - * - * @method set - * @param [x=0] {Number} position of the point on the x axis - * @param [y=0] {Number} position of the point on the y axis - */ -PIXI.Point.prototype.set = function(x, y) -{ - this.x = x || 0; - this.y = y || ( (y !== 0) ? this.x : 0 ) ; -}; - -// constructor -PIXI.Point.prototype.constructor = PIXI.Point; \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/geom/Polygon.js b/app/Lib/Vendor/src/pixi/geom/Polygon.js deleted file mode 100644 index d615a89..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Polygon.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @author Adrien Brault - */ - -/** - * @class Polygon - * @constructor - * @param points* {Array(Point)|Array(Number)|Point...|Number...} This can be an array of Points that form the polygon, - * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be - * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the - * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are - * Numbers. - */ -PIXI.Polygon = function(points) -{ - //if points isn't an array, use arguments as the array - if(!(points instanceof Array))points = Array.prototype.slice.call(arguments); - - //if this is a flat array of numbers, convert it to points - if(points[0] instanceof PIXI.Point) - { - var p = []; - for(var i = 0, il = points.length; i < il; i++) - { - p.push(points[i].x, points[i].y); - } - - points = p; - } - - this.closed = true; - this.points = points; -}; - -/** - * Creates a clone of this polygon - * - * @method clone - * @return {Polygon} a copy of the polygon - */ -PIXI.Polygon.prototype.clone = function() -{ - var points = this.points.slice(); - return new PIXI.Polygon(points); -}; - -/** - * Checks whether the x and y coordinates passed to this function are contained within this polygon - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this polygon - */ -PIXI.Polygon.prototype.contains = function(x, y) -{ - var inside = false; - - // use some raycasting to test hits - // https://github.com/substack/point-in-polygon/blob/master/index.js - var length = this.points.length / 2; - - for(var i = 0, j = length - 1; i < length; j = i++) - { - var xi = this.points[i * 2], yi = this.points[i * 2 + 1], - xj = this.points[j * 2], yj = this.points[j * 2 + 1], - intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); - - if(intersect) inside = !inside; - } - - return inside; -}; - -// constructor -PIXI.Polygon.prototype.constructor = PIXI.Polygon; diff --git a/app/Lib/Vendor/src/pixi/geom/Rectangle.js b/app/Lib/Vendor/src/pixi/geom/Rectangle.js deleted file mode 100644 index 2ccd1d1..0000000 --- a/app/Lib/Vendor/src/pixi/geom/Rectangle.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height. - * - * @class Rectangle - * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the rectangle - * @param y {Number} The Y coordinate of the upper-left corner of the rectangle - * @param width {Number} The overall width of this rectangle - * @param height {Number} The overall height of this rectangle - */ -PIXI.Rectangle = function(x, y, width, height) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -}; - -/** - * Creates a clone of this Rectangle - * - * @method clone - * @return {Rectangle} a copy of the rectangle - */ -PIXI.Rectangle.prototype.clone = function() -{ - return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -}; - -/** - * Checks whether the x and y coordinates given are contained within this Rectangle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Rectangle - */ -PIXI.Rectangle.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; - - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } - - return false; -}; - -// constructor -PIXI.Rectangle.prototype.constructor = PIXI.Rectangle; - -PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0); \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/geom/RoundedRectangle.js b/app/Lib/Vendor/src/pixi/geom/RoundedRectangle.js deleted file mode 100644 index dae668d..0000000 --- a/app/Lib/Vendor/src/pixi/geom/RoundedRectangle.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ - */ - -/** - * The Rounded Rectangle object is an area defined by its position and has nice rounded corners, as indicated by its top-left corner point (x, y) and by its width and its height. - * - * @class RoundedRectangle - * @constructor - * @param x {Number} The X coordinate of the upper-left corner of the rounded rectangle - * @param y {Number} The Y coordinate of the upper-left corner of the rounded rectangle - * @param width {Number} The overall width of this rounded rectangle - * @param height {Number} The overall height of this rounded rectangle - * @param radius {Number} The overall radius of this corners of this rounded rectangle - */ -PIXI.RoundedRectangle = function(x, y, width, height, radius) -{ - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; - - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; - - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; - - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; - - /** - * @property radius - * @type Number - * @default 20 - */ - this.radius = radius || 20; -}; - -/** - * Creates a clone of this Rounded Rectangle - * - * @method clone - * @return {RoundedRectangle} a copy of the rounded rectangle - */ -PIXI.RoundedRectangle.prototype.clone = function() -{ - return new PIXI.RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); -}; - -/** - * Checks whether the x and y coordinates given are contained within this Rounded Rectangle - * - * @method contains - * @param x {Number} The X coordinate of the point to test - * @param y {Number} The Y coordinate of the point to test - * @return {Boolean} Whether the x/y coordinates are within this Rounded Rectangle - */ -PIXI.RoundedRectangle.prototype.contains = function(x, y) -{ - if(this.width <= 0 || this.height <= 0) - return false; - - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; - - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } - - return false; -}; - -// constructor -PIXI.RoundedRectangle.prototype.constructor = PIXI.RoundedRectangle; - diff --git a/app/Lib/Vendor/src/pixi/loaders/AssetLoader.js b/app/Lib/Vendor/src/pixi/loaders/AssetLoader.js deleted file mode 100644 index 25adce2..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/AssetLoader.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A Class that loads a bunch of images / sprite sheet / bitmap font files. Once the - * assets have been loaded they are added to the PIXI Texture cache and can be accessed - * easily through PIXI.Texture.fromImage() and PIXI.Sprite.fromImage() - * When all items have been loaded this class will dispatch a 'onLoaded' event - * As each individual item is loaded this class will dispatch a 'onProgress' event - * - * @class AssetLoader - * @constructor - * @uses EventTarget - * @param assetURLs {Array(String)} An array of image/sprite sheet urls that you would like loaded - * supported. Supported image formats include 'jpeg', 'jpg', 'png', 'gif'. Supported - * sprite sheet data formats only include 'JSON' at this time. Supported bitmap font - * data formats include 'xml' and 'fnt'. - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.AssetLoader = function(assetURLs, crossorigin) -{ - /** - * The array of asset URLs that are going to be loaded - * - * @property assetURLs - * @type Array(String) - */ - this.assetURLs = assetURLs; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * Maps file extension to loader types - * - * @property loadersByType - * @type Object - */ - this.loadersByType = { - 'jpg': PIXI.ImageLoader, - 'jpeg': PIXI.ImageLoader, - 'png': PIXI.ImageLoader, - 'gif': PIXI.ImageLoader, - 'webp': PIXI.ImageLoader, - 'json': PIXI.JsonLoader, - 'atlas': PIXI.AtlasLoader, - 'anim': PIXI.SpineLoader, - 'xml': PIXI.BitmapFontLoader, - 'fnt': PIXI.BitmapFontLoader - }; -}; - -PIXI.EventTarget.mixin(PIXI.AssetLoader.prototype); - -/** - * Fired when an item has loaded - * @event onProgress - */ - -/** - * Fired when all the assets have loaded - * @event onComplete - */ - -// constructor -PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader; - -/** - * Given a filename, returns its extension. - * - * @method _getDataType - * @param str {String} the name of the asset - */ -PIXI.AssetLoader.prototype._getDataType = function(str) -{ - var test = 'data:'; - //starts with 'data:' - var start = str.slice(0, test.length).toLowerCase(); - if (start === test) { - var data = str.slice(test.length); - - var sepIdx = data.indexOf(','); - if (sepIdx === -1) //malformed data URI scheme - return null; - - //e.g. 'image/gif;base64' => 'image/gif' - var info = data.slice(0, sepIdx).split(';')[0]; - - //We might need to handle some special cases here... - //standardize text/plain to 'txt' file extension - if (!info || info.toLowerCase() === 'text/plain') - return 'txt'; - - //User specified mime type, try splitting it by '/' - return info.split('/').pop().toLowerCase(); - } - - return null; -}; - -/** - * Starts loading the assets sequentially - * - * @method load - */ -PIXI.AssetLoader.prototype.load = function() -{ - var scope = this; - - function onLoad(evt) { - scope.onAssetLoaded(evt.data.content); - } - - this.loadCount = this.assetURLs.length; - - for (var i=0; i < this.assetURLs.length; i++) - { - var fileName = this.assetURLs[i]; - //first see if we have a data URI scheme.. - var fileType = this._getDataType(fileName); - - //if not, assume it's a file URI - if (!fileType) - fileType = fileName.split('?').shift().split('.').pop().toLowerCase(); - - var Constructor = this.loadersByType[fileType]; - if(!Constructor) - throw new Error(fileType + ' is an unsupported file type'); - - var loader = new Constructor(fileName, this.crossorigin); - - loader.on('loaded', onLoad); - loader.load(); - } -}; - -/** - * Invoked after each file is loaded - * - * @method onAssetLoaded - * @private - */ -PIXI.AssetLoader.prototype.onAssetLoaded = function(loader) -{ - this.loadCount--; - this.emit('onProgress', { content: this, loader: loader }); - if (this.onProgress) this.onProgress(loader); - - if (!this.loadCount) - { - this.emit('onComplete', { content: this }); - if(this.onComplete) this.onComplete(); - } -}; diff --git a/app/Lib/Vendor/src/pixi/loaders/AtlasLoader.js b/app/Lib/Vendor/src/pixi/loaders/AtlasLoader.js deleted file mode 100644 index 5368b6b..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/AtlasLoader.js +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @author Martin Kelm http://mkelm.github.com - */ - -/** - * The atlas file loader is used to load in Texture Atlas data and parse it. When loaded this class will dispatch a 'loaded' event. If loading fails this class will dispatch an 'error' event. - * - * To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format. - * - * It is highly recommended to use texture atlases (also know as 'sprite sheets') as it allowed sprites to be batched and drawn together for highly increased rendering speed. - * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() - * - * @class AtlasLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.AtlasLoader = function (url, crossorigin) { - this.url = url; - this.baseUrl = url.replace(/[^\/]*$/, ''); - this.crossorigin = crossorigin; - this.loaded = false; - -}; - -// constructor -PIXI.AtlasLoader.constructor = PIXI.AtlasLoader; - -PIXI.EventTarget.mixin(PIXI.AtlasLoader.prototype); - - /** - * Starts loading the JSON file - * - * @method load - */ -PIXI.AtlasLoader.prototype.load = function () { - this.ajaxRequest = new PIXI.AjaxRequest(); - this.ajaxRequest.onreadystatechange = this.onAtlasLoaded.bind(this); - - this.ajaxRequest.open('GET', this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); - this.ajaxRequest.send(null); -}; - -/** - * Invoked when the Atlas has fully loaded. Parses the JSON and builds the texture frames. - * - * @method onAtlasLoaded - * @private - */ -PIXI.AtlasLoader.prototype.onAtlasLoaded = function () { - if (this.ajaxRequest.readyState === 4) { - if (this.ajaxRequest.status === 200 || window.location.href.indexOf('http') === -1) { - this.atlas = { - meta : { - image : [] - }, - frames : [] - }; - var result = this.ajaxRequest.responseText.split(/\r?\n/); - var lineCount = -3; - - var currentImageId = 0; - var currentFrame = null; - var nameInNextLine = false; - - var i = 0, - j = 0, - selfOnLoaded = this.onLoaded.bind(this); - - // parser without rotation support yet! - for (i = 0; i < result.length; i++) { - result[i] = result[i].replace(/^\s+|\s+$/g, ''); - if (result[i] === '') { - nameInNextLine = i+1; - } - if (result[i].length > 0) { - if (nameInNextLine === i) { - this.atlas.meta.image.push(result[i]); - currentImageId = this.atlas.meta.image.length - 1; - this.atlas.frames.push({}); - lineCount = -3; - } else if (lineCount > 0) { - if (lineCount % 7 === 1) { // frame name - if (currentFrame != null) { //jshint ignore:line - this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; - } - currentFrame = { name: result[i], frame : {} }; - } else { - var text = result[i].split(' '); - if (lineCount % 7 === 3) { // position - currentFrame.frame.x = Number(text[1].replace(',', '')); - currentFrame.frame.y = Number(text[2]); - } else if (lineCount % 7 === 4) { // size - currentFrame.frame.w = Number(text[1].replace(',', '')); - currentFrame.frame.h = Number(text[2]); - } else if (lineCount % 7 === 5) { // real size - var realSize = { - x : 0, - y : 0, - w : Number(text[1].replace(',', '')), - h : Number(text[2]) - }; - - if (realSize.w > currentFrame.frame.w || realSize.h > currentFrame.frame.h) { - currentFrame.trimmed = true; - currentFrame.realSize = realSize; - } else { - currentFrame.trimmed = false; - } - } - } - } - lineCount++; - } - } - - if (currentFrame != null) { //jshint ignore:line - this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; - } - - if (this.atlas.meta.image.length > 0) { - this.images = []; - for (j = 0; j < this.atlas.meta.image.length; j++) { - // sprite sheet - var textureUrl = this.baseUrl + this.atlas.meta.image[j]; - var frameData = this.atlas.frames[j]; - this.images.push(new PIXI.ImageLoader(textureUrl, this.crossorigin)); - - for (i in frameData) { - var rect = frameData[i].frame; - if (rect) { - PIXI.TextureCache[i] = new PIXI.Texture(this.images[j].texture.baseTexture, { - x: rect.x, - y: rect.y, - width: rect.w, - height: rect.h - }); - if (frameData[i].trimmed) { - PIXI.TextureCache[i].realSize = frameData[i].realSize; - // trim in pixi not supported yet, todo update trim properties if it is done ... - PIXI.TextureCache[i].trim.x = 0; - PIXI.TextureCache[i].trim.y = 0; - } - } - } - } - - this.currentImageId = 0; - for (j = 0; j < this.images.length; j++) { - this.images[j].on('loaded', selfOnLoaded); - } - this.images[this.currentImageId].load(); - - } else { - this.onLoaded(); - } - - } else { - this.onError(); - } - } -}; - -/** - * Invoked when json file has loaded. - * - * @method onLoaded - * @private - */ -PIXI.AtlasLoader.prototype.onLoaded = function () { - if (this.images.length - 1 > this.currentImageId) { - this.currentImageId++; - this.images[this.currentImageId].load(); - } else { - this.loaded = true; - this.emit('loaded', { content: this }); - } -}; - -/** - * Invoked when an error occurs. - * - * @method onError - * @private - */ -PIXI.AtlasLoader.prototype.onError = function () { - this.emit('error', { content: this }); -}; diff --git a/app/Lib/Vendor/src/pixi/loaders/BitmapFontLoader.js b/app/Lib/Vendor/src/pixi/loaders/BitmapFontLoader.js deleted file mode 100644 index 3eb54c4..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/BitmapFontLoader.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The xml loader is used to load in XML bitmap font data ('xml' or 'fnt') - * To generate the data you can use http://www.angelcode.com/products/bmfont/ - * This loader will also load the image file as the data. - * When loaded this class will dispatch a 'loaded' event - * - * @class BitmapFontLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the sprite sheet JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.BitmapFontLoader = function(url, crossorigin) -{ - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ''); - - /** - * [read-only] The texture of the bitmap font - * - * @property texture - * @type Texture - */ - this.texture = null; -}; - -// constructor -PIXI.BitmapFontLoader.prototype.constructor = PIXI.BitmapFontLoader; -PIXI.EventTarget.mixin(PIXI.BitmapFontLoader.prototype); - -/** - * Loads the XML font data - * - * @method load - */ -PIXI.BitmapFontLoader.prototype.load = function() -{ - this.ajaxRequest = new PIXI.AjaxRequest(); - this.ajaxRequest.onreadystatechange = this.onXMLLoaded.bind(this); - - this.ajaxRequest.open('GET', this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/xml'); - this.ajaxRequest.send(null); -}; - -/** - * Invoked when the XML file is loaded, parses the data. - * - * @method onXMLLoaded - * @private - */ -PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() -{ - if (this.ajaxRequest.readyState === 4) - { - if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1) - { - var responseXML = this.ajaxRequest.responseXML; - if(!responseXML || /MSIE 9/i.test(navigator.userAgent) || navigator.isCocoonJS) { - if(typeof(window.DOMParser) === 'function') { - var domparser = new DOMParser(); - responseXML = domparser.parseFromString(this.ajaxRequest.responseText, 'text/xml'); - } else { - var div = document.createElement('div'); - div.innerHTML = this.ajaxRequest.responseText; - responseXML = div; - } - } - - var textureUrl = this.baseUrl + responseXML.getElementsByTagName('page')[0].getAttribute('file'); - var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); - this.texture = image.texture.baseTexture; - - var data = {}; - var info = responseXML.getElementsByTagName('info')[0]; - var common = responseXML.getElementsByTagName('common')[0]; - data.font = info.getAttribute('face'); - data.size = parseInt(info.getAttribute('size'), 10); - data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10); - data.chars = {}; - - //parse letters - var letters = responseXML.getElementsByTagName('char'); - - for (var i = 0; i < letters.length; i++) - { - var charCode = parseInt(letters[i].getAttribute('id'), 10); - - var textureRect = new PIXI.Rectangle( - parseInt(letters[i].getAttribute('x'), 10), - parseInt(letters[i].getAttribute('y'), 10), - parseInt(letters[i].getAttribute('width'), 10), - parseInt(letters[i].getAttribute('height'), 10) - ); - - data.chars[charCode] = { - xOffset: parseInt(letters[i].getAttribute('xoffset'), 10), - yOffset: parseInt(letters[i].getAttribute('yoffset'), 10), - xAdvance: parseInt(letters[i].getAttribute('xadvance'), 10), - kerning: {}, - texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect) - - }; - } - - //parse kernings - var kernings = responseXML.getElementsByTagName('kerning'); - for (i = 0; i < kernings.length; i++) - { - var first = parseInt(kernings[i].getAttribute('first'), 10); - var second = parseInt(kernings[i].getAttribute('second'), 10); - var amount = parseInt(kernings[i].getAttribute('amount'), 10); - - data.chars[second].kerning[first] = amount; - - } - - PIXI.BitmapText.fonts[data.font] = data; - - image.addEventListener('loaded', this.onLoaded.bind(this)); - image.load(); - } - } -}; - -/** - * Invoked when all files are loaded (xml/fnt and texture) - * - * @method onLoaded - * @private - */ -PIXI.BitmapFontLoader.prototype.onLoaded = function() -{ - this.emit('loaded', { content: this }); -}; diff --git a/app/Lib/Vendor/src/pixi/loaders/ImageLoader.js b/app/Lib/Vendor/src/pixi/loaders/ImageLoader.js deleted file mode 100644 index 1567f29..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/ImageLoader.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif') - * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrame() and PIXI.Sprite.fromFrame() - * When loaded this class will dispatch a 'loaded' event - * - * @class ImageLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the image - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.ImageLoader = function(url, crossorigin) -{ - /** - * The texture being loaded - * - * @property texture - * @type Texture - */ - this.texture = PIXI.Texture.fromImage(url, crossorigin); - - /** - * if the image is loaded with loadFramedSpriteSheet - * frames will contain the sprite sheet frames - * - * @property frames - * @type Array - * @readOnly - */ - this.frames = []; -}; - -// constructor -PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader; - -PIXI.EventTarget.mixin(PIXI.ImageLoader.prototype); - -/** - * Loads image or takes it from cache - * - * @method load - */ -PIXI.ImageLoader.prototype.load = function() -{ - if(!this.texture.baseTexture.hasLoaded) - { - this.texture.baseTexture.on('loaded', this.onLoaded.bind(this)); - } - else - { - this.onLoaded(); - } -}; - -/** - * Invoked when image file is loaded or it is already cached and ready to use - * - * @method onLoaded - * @private - */ -PIXI.ImageLoader.prototype.onLoaded = function() -{ - this.emit('loaded', { content: this }); -}; - -/** - * Loads image and split it to uniform sized frames - * - * @method loadFramedSpriteSheet - * @param frameWidth {Number} width of each frame - * @param frameHeight {Number} height of each frame - * @param textureName {String} if given, the frames will be cached in - format - */ -PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName) -{ - this.frames = []; - var cols = Math.floor(this.texture.width / frameWidth); - var rows = Math.floor(this.texture.height / frameHeight); - - var i=0; - for (var y=0; y 0) - { - textureLoader.addEventListener('loadedBaseTexture', function(evt){ - if (evt.content.content.loadingCount <= 0) - { - originalLoader.onLoaded(); - } - }); - } - else - { - originalLoader.onLoaded(); - } - }; - // start the loading // - atlasLoader.load(); - } - } - else - { - this.onLoaded(); - } -}; - -/** - * Invoke when json file loaded - * - * @method onLoaded - * @private - */ -PIXI.JsonLoader.prototype.onLoaded = function () { - this.loaded = true; - this.dispatchEvent({ - type: 'loaded', - content: this - }); -}; - -/** - * Invoke when error occured - * - * @method onError - * @private - */ -PIXI.JsonLoader.prototype.onError = function () { - - this.dispatchEvent({ - type: 'error', - content: this - }); -}; diff --git a/app/Lib/Vendor/src/pixi/loaders/SpineLoader.js b/app/Lib/Vendor/src/pixi/loaders/SpineLoader.js deleted file mode 100644 index c736c50..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/SpineLoader.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi - * - * Awesome JS run time provided by EsotericSoftware - * https://github.com/EsotericSoftware/spine-runtimes - * - */ - -/** - * The Spine loader is used to load in JSON spine data - * To generate the data you need to use http://esotericsoftware.com/ and export in the "JSON" format - * Due to a clash of names You will need to change the extension of the spine file from *.json to *.anim for it to load - * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source - * You will need to generate a sprite sheet to accompany the spine data - * When loaded this class will dispatch a "loaded" event - * - * @class SpineLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.SpineLoader = function(url, crossorigin) -{ - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * [read-only] Whether the data has loaded yet - * - * @property loaded - * @type Boolean - * @readOnly - */ - this.loaded = false; -}; - -PIXI.SpineLoader.prototype.constructor = PIXI.SpineLoader; - -PIXI.EventTarget.mixin(PIXI.SpineLoader.prototype); - -/** - * Loads the JSON data - * - * @method load - */ -PIXI.SpineLoader.prototype.load = function () { - - var scope = this; - var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.on('loaded', function (event) { - scope.json = event.data.content.json; - scope.onLoaded(); - }); - jsonLoader.load(); -}; - -/** - * Invoked when JSON file is loaded. - * - * @method onLoaded - * @private - */ -PIXI.SpineLoader.prototype.onLoaded = function () { - this.loaded = true; - this.emit('loaded', { content: this }); -}; diff --git a/app/Lib/Vendor/src/pixi/loaders/SpriteSheetLoader.js b/app/Lib/Vendor/src/pixi/loaders/SpriteSheetLoader.js deleted file mode 100644 index 4d50430..0000000 --- a/app/Lib/Vendor/src/pixi/loaders/SpriteSheetLoader.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The sprite sheet loader is used to load in JSON sprite sheet data - * To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format - * There is a free version so thats nice, although the paid version is great value for money. - * It is highly recommended to use Sprite sheets (also know as a 'texture atlas') as it means sprites can be batched and drawn together for highly increased rendering speed. - * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId() - * This loader will load the image file that the Spritesheet points to as well as the data. - * When loaded this class will dispatch a 'loaded' event - * - * @class SpriteSheetLoader - * @uses EventTarget - * @constructor - * @param url {String} The url of the sprite sheet JSON file - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - */ -PIXI.SpriteSheetLoader = function (url, crossorigin) { - - /** - * The url of the atlas data - * - * @property url - * @type String - */ - this.url = url; - - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; - - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ''); - - /** - * The texture being loaded - * - * @property texture - * @type Texture - */ - this.texture = null; - - /** - * The frames of the sprite sheet - * - * @property frames - * @type Object - */ - this.frames = {}; -}; - -// constructor -PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader; - -PIXI.EventTarget.mixin(PIXI.SpriteSheetLoader.prototype); - -/** - * This will begin loading the JSON file - * - * @method load - */ -PIXI.SpriteSheetLoader.prototype.load = function () { - var scope = this; - var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.on('loaded', function (event) { - scope.json = event.data.content.json; - scope.onLoaded(); - }); - jsonLoader.load(); -}; - -/** - * Invoke when all files are loaded (json and texture) - * - * @method onLoaded - * @private - */ -PIXI.SpriteSheetLoader.prototype.onLoaded = function () { - this.emit('loaded', { - content: this - }); -}; diff --git a/app/Lib/Vendor/src/pixi/primitives/Graphics.js b/app/Lib/Vendor/src/pixi/primitives/Graphics.js deleted file mode 100644 index 91a44ea..0000000 --- a/app/Lib/Vendor/src/pixi/primitives/Graphics.js +++ /dev/null @@ -1,1135 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The Graphics class contains methods used to draw primitive shapes such as lines, circles and rectangles to the display, and color and fill them. - * - * @class Graphics - * @extends DisplayObjectContainer - * @constructor - */ -PIXI.Graphics = function() -{ - PIXI.DisplayObjectContainer.call( this ); - - this.renderable = true; - - /** - * The alpha value used when filling the Graphics object. - * - * @property fillAlpha - * @type Number - */ - this.fillAlpha = 1; - - /** - * The width (thickness) of any lines drawn. - * - * @property lineWidth - * @type Number - */ - this.lineWidth = 0; - - /** - * The color of any lines drawn. - * - * @property lineColor - * @type String - * @default 0 - */ - this.lineColor = 0; - - /** - * Graphics data - * - * @property graphicsData - * @type Array - * @private - */ - this.graphicsData = []; - - /** - * The tint applied to the graphic shape. This is a hex value. Apply a value of 0xFFFFFF to reset the tint. - * - * @property tint - * @type Number - * @default 0xFFFFFF - */ - this.tint = 0xFFFFFF; - - /** - * The blend mode to be applied to the graphic shape. Apply a value of PIXI.blendModes.NORMAL to reset the blend mode. - * - * @property blendMode - * @type Number - * @default PIXI.blendModes.NORMAL; - */ - this.blendMode = PIXI.blendModes.NORMAL; - - /** - * Current path - * - * @property currentPath - * @type Object - * @private - */ - this.currentPath = null; - - /** - * Array containing some WebGL-related properties used by the WebGL renderer. - * - * @property _webGL - * @type Array - * @private - */ - this._webGL = []; - - /** - * Whether this shape is being used as a mask. - * - * @property isMask - * @type Boolean - */ - this.isMask = false; - - /** - * The bounds' padding used for bounds calculation. - * - * @property boundsPadding - * @type Number - */ - this.boundsPadding = 0; - - this._localBounds = new PIXI.Rectangle(0,0,1,1); - - /** - * Used to detect if the graphics object has changed. If this is set to true then the graphics object will be recalculated. - * - * @property dirty - * @type Boolean - * @private - */ - this.dirty = true; - - /** - * Used to detect if the webgl graphics object has changed. If this is set to true then the graphics object will be recalculated. - * - * @property webGLDirty - * @type Boolean - * @private - */ - this.webGLDirty = false; - - /** - * Used to detect if the cached sprite object needs to be updated. - * - * @property cachedSpriteDirty - * @type Boolean - * @private - */ - this.cachedSpriteDirty = false; - -}; - -// constructor -PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); -PIXI.Graphics.prototype.constructor = PIXI.Graphics; - -/** - * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite. - * This is useful if your graphics element does not change often, as it will speed up the rendering of the object in exchange for taking up texture memory. - * It is also useful if you need the graphics object to be anti-aliased, because it will be rendered using canvas. - * This is not recommended if you are constantly redrawing the graphics element. - * - * @property cacheAsBitmap - * @type Boolean - * @default false - * @private - */ -Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", { - get: function() { - return this._cacheAsBitmap; - }, - set: function(value) { - this._cacheAsBitmap = value; - - if(this._cacheAsBitmap) - { - - this._generateCachedSprite(); - } - else - { - this.destroyCachedSprite(); - this.dirty = true; - } - - } -}); - -/** - * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method. - * - * @method lineStyle - * @param lineWidth {Number} width of the line to draw, will update the objects stored style - * @param color {Number} color of the line to draw, will update the objects stored style - * @param alpha {Number} alpha of the line to draw, will update the objects stored style - * @return {Graphics} - */ -PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) -{ - this.lineWidth = lineWidth || 0; - this.lineColor = color || 0; - this.lineAlpha = (arguments.length < 3) ? 1 : alpha; - - if(this.currentPath) - { - if(this.currentPath.shape.points.length) - { - // halfway through a line? start a new one! - this.drawShape( new PIXI.Polygon( this.currentPath.shape.points.slice(-2) )); - return this; - } - - // otherwise its empty so lets just set the line properties - this.currentPath.lineWidth = this.lineWidth; - this.currentPath.lineColor = this.lineColor; - this.currentPath.lineAlpha = this.lineAlpha; - - } - - return this; -}; - -/** - * Moves the current drawing position to x, y. - * - * @method moveTo - * @param x {Number} the X coordinate to move to - * @param y {Number} the Y coordinate to move to - * @return {Graphics} - */ -PIXI.Graphics.prototype.moveTo = function(x, y) -{ - this.drawShape(new PIXI.Polygon([x,y])); - - return this; -}; - -/** - * Draws a line using the current line style from the current drawing position to (x, y); - * The current drawing position is then set to (x, y). - * - * @method lineTo - * @param x {Number} the X coordinate to draw to - * @param y {Number} the Y coordinate to draw to - * @return {Graphics} - */ -PIXI.Graphics.prototype.lineTo = function(x, y) -{ - this.currentPath.shape.points.push(x, y); - this.dirty = true; - - return this; -}; - -/** - * Calculate the points for a quadratic bezier curve and then draws it. - * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c - * - * @method quadraticCurveTo - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Graphics} - */ -PIXI.Graphics.prototype.quadraticCurveTo = function(cpX, cpY, toX, toY) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0)this.currentPath.shape.points = [0,0]; - } - else - { - this.moveTo(0,0); - } - - var xa, - ya, - n = 20, - points = this.currentPath.shape.points; - if(points.length === 0)this.moveTo(0, 0); - - - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - - var j = 0; - for (var i = 1; i <= n; i++ ) - { - j = i / n; - - xa = fromX + ( (cpX - fromX) * j ); - ya = fromY + ( (cpY - fromY) * j ); - - points.push( xa + ( ((cpX + ( (toX - cpX) * j )) - xa) * j ), - ya + ( ((cpY + ( (toY - cpY) * j )) - ya) * j ) ); - } - - - this.dirty = true; - - return this; -}; - -/** - * Calculate the points for a bezier curve and then draws it. - * - * @method bezierCurveTo - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param cpX2 {Number} Second Control point x - * @param cpY2 {Number} Second Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Graphics} - */ -PIXI.Graphics.prototype.bezierCurveTo = function(cpX, cpY, cpX2, cpY2, toX, toY) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0)this.currentPath.shape.points = [0,0]; - } - else - { - this.moveTo(0,0); - } - - var n = 20, - dt, - dt2, - dt3, - t2, - t3, - points = this.currentPath.shape.points; - - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - - var j = 0; - - for (var i=1; i<=n; i++) - { - j = i / n; - - dt = (1 - j); - dt2 = dt * dt; - dt3 = dt2 * dt; - - t2 = j * j; - t3 = t2 * j; - - points.push( dt3 * fromX + 3 * dt2 * j * cpX + 3 * dt * t2 * cpX2 + t3 * toX, - dt3 * fromY + 3 * dt2 * j * cpY + 3 * dt * t2 * cpY2 + t3 * toY); - } - - this.dirty = true; - - return this; -}; - -/* - * The arcTo() method creates an arc/curve between two tangents on the canvas. - * - * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google! - * - * @method arcTo - * @param x1 {Number} The x-coordinate of the beginning of the arc - * @param y1 {Number} The y-coordinate of the beginning of the arc - * @param x2 {Number} The x-coordinate of the end of the arc - * @param y2 {Number} The y-coordinate of the end of the arc - * @param radius {Number} The radius of the arc - * @return {Graphics} - */ -PIXI.Graphics.prototype.arcTo = function(x1, y1, x2, y2, radius) -{ - if( this.currentPath ) - { - if(this.currentPath.shape.points.length === 0) - { - this.currentPath.shape.points.push(x1, y1); - } - } - else - { - this.moveTo(x1, y1); - } - - var points = this.currentPath.shape.points; - var fromX = points[points.length-2]; - var fromY = points[points.length-1]; - var a1 = fromY - y1; - var b1 = fromX - x1; - var a2 = y2 - y1; - var b2 = x2 - x1; - var mm = Math.abs(a1 * b2 - b1 * a2); - - - if (mm < 1.0e-8 || radius === 0) - { - if( points[points.length-2] !== x1 || points[points.length-1] !== y1) - { - //console.log(">>") - points.push(x1, y1); - } - } - else - { - var dd = a1 * a1 + b1 * b1; - var cc = a2 * a2 + b2 * b2; - var tt = a1 * a2 + b1 * b2; - var k1 = radius * Math.sqrt(dd) / mm; - var k2 = radius * Math.sqrt(cc) / mm; - var j1 = k1 * tt / dd; - var j2 = k2 * tt / cc; - var cx = k1 * b2 + k2 * b1; - var cy = k1 * a2 + k2 * a1; - var px = b1 * (k2 + j1); - var py = a1 * (k2 + j1); - var qx = b2 * (k1 + j2); - var qy = a2 * (k1 + j2); - var startAngle = Math.atan2(py - cy, px - cx); - var endAngle = Math.atan2(qy - cy, qx - cx); - - this.arc(cx + x1, cy + y1, radius, startAngle, endAngle, b1 * a2 > b2 * a1); - } - - this.dirty = true; - - return this; -}; - -/** - * The arc method creates an arc/curve (used to create circles, or parts of circles). - * - * @method arc - * @param cx {Number} The x-coordinate of the center of the circle - * @param cy {Number} The y-coordinate of the center of the circle - * @param radius {Number} The radius of the circle - * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle) - * @param endAngle {Number} The ending angle, in radians - * @param anticlockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise. - * @return {Graphics} - */ -PIXI.Graphics.prototype.arc = function(cx, cy, radius, startAngle, endAngle, anticlockwise) -{ - var startX = cx + Math.cos(startAngle) * radius; - var startY = cy + Math.sin(startAngle) * radius; - var points; - - if( this.currentPath ) - { - points = this.currentPath.shape.points; - - if(points.length === 0) - { - points.push(startX, startY); - } - else if( points[points.length-2] !== startX || points[points.length-1] !== startY) - { - points.push(startX, startY); - } - } - else - { - this.moveTo(startX, startY); - points = this.currentPath.shape.points; - } - - if (startAngle === endAngle)return this; - - if( !anticlockwise && endAngle <= startAngle ) - { - endAngle += Math.PI * 2; - } - else if( anticlockwise && startAngle <= endAngle ) - { - startAngle += Math.PI * 2; - } - - var sweep = anticlockwise ? (startAngle - endAngle) *-1 : (endAngle - startAngle); - var segs = ( Math.abs(sweep)/ (Math.PI * 2) ) * 40; - - if( sweep === 0 ) return this; - - var theta = sweep/(segs*2); - var theta2 = theta*2; - - var cTheta = Math.cos(theta); - var sTheta = Math.sin(theta); - - var segMinus = segs - 1; - - var remainder = ( segMinus % 1 ) / segMinus; - - for(var i=0; i<=segMinus; i++) - { - var real = i + remainder * i; - - - var angle = ((theta) + startAngle + (theta2 * real)); - - var c = Math.cos(angle); - var s = -Math.sin(angle); - - points.push(( (cTheta * c) + (sTheta * s) ) * radius + cx, - ( (cTheta * -s) + (sTheta * c) ) * radius + cy); - } - - this.dirty = true; - - return this; -}; - -/** - * Specifies a simple one-color fill that subsequent calls to other Graphics methods - * (such as lineTo() or drawCircle()) use when drawing. - * - * @method beginFill - * @param color {Number} the color of the fill - * @param alpha {Number} the alpha of the fill - * @return {Graphics} - */ -PIXI.Graphics.prototype.beginFill = function(color, alpha) -{ - this.filling = true; - this.fillColor = color || 0; - this.fillAlpha = (alpha === undefined) ? 1 : alpha; - - if(this.currentPath) - { - if(this.currentPath.shape.points.length <= 2) - { - this.currentPath.fill = this.filling; - this.currentPath.fillColor = this.fillColor; - this.currentPath.fillAlpha = this.fillAlpha; - } - } - return this; -}; - -/** - * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. - * - * @method endFill - * @return {Graphics} - */ -PIXI.Graphics.prototype.endFill = function() -{ - this.filling = false; - this.fillColor = null; - this.fillAlpha = 1; - - return this; -}; - -/** - * @method drawRect - * - * @param x {Number} The X coord of the top-left of the rectangle - * @param y {Number} The Y coord of the top-left of the rectangle - * @param width {Number} The width of the rectangle - * @param height {Number} The height of the rectangle - * @return {Graphics} - */ -PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) -{ - this.drawShape(new PIXI.Rectangle(x,y, width, height)); - - return this; -}; - -/** - * @method drawRoundedRect - * - * @param x {Number} The X coord of the top-left of the rectangle - * @param y {Number} The Y coord of the top-left of the rectangle - * @param width {Number} The width of the rectangle - * @param height {Number} The height of the rectangle - * @param radius {Number} Radius of the rectangle corners - */ -PIXI.Graphics.prototype.drawRoundedRect = function( x, y, width, height, radius ) -{ - this.drawShape(new PIXI.RoundedRectangle(x, y, width, height, radius)); - - return this; -}; - -/** - * Draws a circle. - * - * @method drawCircle - * @param x {Number} The X coordinate of the center of the circle - * @param y {Number} The Y coordinate of the center of the circle - * @param radius {Number} The radius of the circle - * @return {Graphics} - */ -PIXI.Graphics.prototype.drawCircle = function(x, y, radius) -{ - this.drawShape(new PIXI.Circle(x,y, radius)); - - return this; -}; - -/** - * Draws an ellipse. - * - * @method drawEllipse - * @param x {Number} The X coordinate of the center of the ellipse - * @param y {Number} The Y coordinate of the center of the ellipse - * @param width {Number} The half width of the ellipse - * @param height {Number} The half height of the ellipse - * @return {Graphics} - */ -PIXI.Graphics.prototype.drawEllipse = function(x, y, width, height) -{ - this.drawShape(new PIXI.Ellipse(x, y, width, height)); - - return this; -}; - -/** - * Draws a polygon using the given path. - * - * @method drawPolygon - * @param path {Array} The path data used to construct the polygon. - * @return {Graphics} - */ -PIXI.Graphics.prototype.drawPolygon = function(path) -{ - if(!(path instanceof Array))path = Array.prototype.slice.call(arguments); - this.drawShape(new PIXI.Polygon(path)); - return this; -}; - -/** - * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. - * - * @method clear - * @return {Graphics} - */ -PIXI.Graphics.prototype.clear = function() -{ - this.lineWidth = 0; - this.filling = false; - - this.dirty = true; - this.clearDirty = true; - this.graphicsData = []; - - return this; -}; - -/** - * Useful function that returns a texture of the graphics object that can then be used to create sprites - * This can be quite useful if your geometry is complicated and needs to be reused multiple times. - * - * @method generateTexture - * @param resolution {Number} The resolution of the texture being generated - * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts - * @return {Texture} a texture of the graphics object - */ -PIXI.Graphics.prototype.generateTexture = function(resolution, scaleMode) -{ - resolution = resolution || 1; - - var bounds = this.getBounds(); - - var canvasBuffer = new PIXI.CanvasBuffer(bounds.width * resolution, bounds.height * resolution); - - var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas, scaleMode); - texture.baseTexture.resolution = resolution; - - canvasBuffer.context.scale(resolution, resolution); - - canvasBuffer.context.translate(-bounds.x,-bounds.y); - - PIXI.CanvasGraphics.renderGraphics(this, canvasBuffer.context); - - return texture; -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Graphics.prototype._renderWebGL = function(renderSession) -{ - // if the sprite is not visible or the alpha is 0 then no need to render this element - if(this.visible === false || this.alpha === 0 || this.isMask === true)return; - - if(this._cacheAsBitmap) - { - - if(this.dirty || this.cachedSpriteDirty) - { - - this._generateCachedSprite(); - - // we will also need to update the texture on the gpu too! - this.updateCachedSpriteTexture(); - - this.cachedSpriteDirty = false; - this.dirty = false; - } - - this._cachedSprite.worldAlpha = this.worldAlpha; - PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession); - - return; - } - else - { - renderSession.spriteBatch.stop(); - renderSession.blendModeManager.setBlendMode(this.blendMode); - - if(this._mask)renderSession.maskManager.pushMask(this._mask, renderSession); - if(this._filters)renderSession.filterManager.pushFilter(this._filterBlock); - - // check blend mode - if(this.blendMode !== renderSession.spriteBatch.currentBlendMode) - { - renderSession.spriteBatch.currentBlendMode = this.blendMode; - var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode]; - renderSession.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); - } - - // check if the webgl graphic needs to be updated - if(this.webGLDirty) - { - this.dirty = true; - this.webGLDirty = false; - } - - PIXI.WebGLGraphics.renderGraphics(this, renderSession); - - // only render if it has children! - if(this.children.length) - { - renderSession.spriteBatch.start(); - - // simple render children! - for(var i=0, j=this.children.length; i maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - - this._bounds.x = minX; - this._bounds.width = maxX - minX; - - this._bounds.y = minY; - this._bounds.height = maxY - minY; - - return this._bounds; -}; - -/** - * Update the bounds of the object - * - * @method updateLocalBounds - */ -PIXI.Graphics.prototype.updateLocalBounds = function() -{ - var minX = Infinity; - var maxX = -Infinity; - - var minY = Infinity; - var maxY = -Infinity; - - if(this.graphicsData.length) - { - var shape, points, x, y, w, h; - - for (var i = 0; i < this.graphicsData.length; i++) { - var data = this.graphicsData[i]; - var type = data.type; - var lineWidth = data.lineWidth; - shape = data.shape; - - - if(type === PIXI.Graphics.RECT || type === PIXI.Graphics.RREC) - { - x = shape.x - lineWidth/2; - y = shape.y - lineWidth/2; - w = shape.width + lineWidth; - h = shape.height + lineWidth; - - minX = x < minX ? x : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y < minY ? y : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else if(type === PIXI.Graphics.CIRC) - { - x = shape.x; - y = shape.y; - w = shape.radius + lineWidth/2; - h = shape.radius + lineWidth/2; - - minX = x - w < minX ? x - w : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y - h < minY ? y - h : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else if(type === PIXI.Graphics.ELIP) - { - x = shape.x; - y = shape.y; - w = shape.width + lineWidth/2; - h = shape.height + lineWidth/2; - - minX = x - w < minX ? x - w : minX; - maxX = x + w > maxX ? x + w : maxX; - - minY = y - h < minY ? y - h : minY; - maxY = y + h > maxY ? y + h : maxY; - } - else - { - // POLY - points = shape.points; - - for (var j = 0; j < points.length; j+=2) - { - - x = points[j]; - y = points[j+1]; - minX = x-lineWidth < minX ? x-lineWidth : minX; - maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - - minY = y-lineWidth < minY ? y-lineWidth : minY; - maxY = y+lineWidth > maxY ? y+lineWidth : maxY; - } - } - } - } - else - { - minX = 0; - maxX = 0; - minY = 0; - maxY = 0; - } - - var padding = this.boundsPadding; - - this._localBounds.x = minX - padding; - this._localBounds.width = (maxX - minX) + padding * 2; - - this._localBounds.y = minY - padding; - this._localBounds.height = (maxY - minY) + padding * 2; -}; - -/** - * Generates the cached sprite when the sprite has cacheAsBitmap = true - * - * @method _generateCachedSprite - * @private - */ -PIXI.Graphics.prototype._generateCachedSprite = function() -{ - var bounds = this.getLocalBounds(); - - if(!this._cachedSprite) - { - var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height); - var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas); - - this._cachedSprite = new PIXI.Sprite(texture); - this._cachedSprite.buffer = canvasBuffer; - - this._cachedSprite.worldTransform = this.worldTransform; - } - else - { - this._cachedSprite.buffer.resize(bounds.width, bounds.height); - } - - // leverage the anchor to account for the offset of the element - this._cachedSprite.anchor.x = -( bounds.x / bounds.width ); - this._cachedSprite.anchor.y = -( bounds.y / bounds.height ); - - // this._cachedSprite.buffer.context.save(); - this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y); - - // make sure we set the alpha of the graphics to 1 for the render.. - this.worldAlpha = 1; - - // now render the graphic.. - PIXI.CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context); - this._cachedSprite.alpha = this.alpha; -}; - -/** - * Updates texture size based on canvas size - * - * @method updateCachedSpriteTexture - * @private - */ -PIXI.Graphics.prototype.updateCachedSpriteTexture = function() -{ - var cachedSprite = this._cachedSprite; - var texture = cachedSprite.texture; - var canvas = cachedSprite.buffer.canvas; - - texture.baseTexture.width = canvas.width; - texture.baseTexture.height = canvas.height; - texture.crop.width = texture.frame.width = canvas.width; - texture.crop.height = texture.frame.height = canvas.height; - - cachedSprite._width = canvas.width; - cachedSprite._height = canvas.height; - - // update the dirty base textures - texture.baseTexture.dirty(); -}; - -/** - * Destroys a previous cached sprite. - * - * @method destroyCachedSprite - */ -PIXI.Graphics.prototype.destroyCachedSprite = function() -{ - this._cachedSprite.texture.destroy(true); - - // let the gc collect the unused sprite - // TODO could be object pooled! - this._cachedSprite = null; -}; - -/** - * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon. - * - * @method drawShape - * @param {Circle|Rectangle|Ellipse|Line|Polygon} shape The Shape object to draw. - * @return {GraphicsData} The generated GraphicsData object. - */ -PIXI.Graphics.prototype.drawShape = function(shape) -{ - if(this.currentPath) - { - // check current path! - if(this.currentPath.shape.points.length <= 2)this.graphicsData.pop(); - } - - this.currentPath = null; - - var data = new PIXI.GraphicsData(this.lineWidth, this.lineColor, this.lineAlpha, this.fillColor, this.fillAlpha, this.filling, shape); - - this.graphicsData.push(data); - - if(data.type === PIXI.Graphics.POLY) - { - data.shape.closed = this.filling; - this.currentPath = data; - } - - this.dirty = true; - - return data; -}; - -/** - * A GraphicsData object. - * - * @class GraphicsData - * @constructor - */ -PIXI.GraphicsData = function(lineWidth, lineColor, lineAlpha, fillColor, fillAlpha, fill, shape) -{ - this.lineWidth = lineWidth; - this.lineColor = lineColor; - this.lineAlpha = lineAlpha; - this._lineTint = lineColor; - - this.fillColor = fillColor; - this.fillAlpha = fillAlpha; - this._fillTint = fillColor; - this.fill = fill; - - this.shape = shape; - this.type = shape.type; -}; - -// SOME TYPES: -PIXI.Graphics.POLY = 0; -PIXI.Graphics.RECT = 1; -PIXI.Graphics.CIRC = 2; -PIXI.Graphics.ELIP = 3; -PIXI.Graphics.RREC = 4; - -PIXI.Polygon.prototype.type = PIXI.Graphics.POLY; -PIXI.Rectangle.prototype.type = PIXI.Graphics.RECT; -PIXI.Circle.prototype.type = PIXI.Graphics.CIRC; -PIXI.Ellipse.prototype.type = PIXI.Graphics.ELIP; -PIXI.RoundedRectangle.prototype.type = PIXI.Graphics.RREC; - diff --git a/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasGraphics.js b/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasGraphics.js deleted file mode 100644 index 1fb5372..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasGraphics.js +++ /dev/null @@ -1,358 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - - -/** - * A set of functions used by the canvas renderer to draw the primitive graphics data. - * - * @class CanvasGraphics - * @static - */ -PIXI.CanvasGraphics = function() -{ -}; - -/* - * Renders a PIXI.Graphics object to a canvas. - * - * @method renderGraphics - * @static - * @param graphics {Graphics} the actual graphics object to render - * @param context {CanvasRenderingContext2D} the 2d drawing method of the canvas - */ -PIXI.CanvasGraphics.renderGraphics = function(graphics, context) -{ - var worldAlpha = graphics.worldAlpha; - - if(graphics.dirty) - { - this.updateGraphicsTint(graphics); - graphics.dirty = false; - } - - - for (var i = 0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - var shape = data.shape; - - var fillColor = data._fillTint; - var lineColor = data._lineTint; - - context.lineWidth = data.lineWidth; - - if(data.type === PIXI.Graphics.POLY) - { - context.beginPath(); - - var points = shape.points; - - context.moveTo(points[0], points[1]); - - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } - - if(shape.closed) - { - context.lineTo(points[0], points[1]); - } - - // if the first and last point are the same close the path - much neater :) - if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) - { - context.closePath(); - } - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.stroke(); - } - } - else if(data.type === PIXI.Graphics.RECT) - { - - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fillRect(shape.x, shape.y, shape.width, shape.height); - - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.strokeRect(shape.x, shape.y, shape.width, shape.height); - } - } - else if(data.type === PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI); - context.closePath(); - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.stroke(); - } - } - else if(data.type === PIXI.Graphics.ELIP) - { - // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - - var w = shape.width * 2; - var h = shape.height * 2; - - var x = shape.x - w/2; - var y = shape.y - h/2; - - context.beginPath(); - - var kappa = 0.5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle - - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - - context.closePath(); - - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.stroke(); - } - } - else if (data.type === PIXI.Graphics.RREC) - { - var rx = shape.x; - var ry = shape.y; - var width = shape.width; - var height = shape.height; - var radius = shape.radius; - - var maxRadius = Math.min(width, height) / 2 | 0; - radius = radius > maxRadius ? maxRadius : radius; - - context.beginPath(); - context.moveTo(rx, ry + radius); - context.lineTo(rx, ry + height - radius); - context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height); - context.lineTo(rx + width - radius, ry + height); - context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); - context.lineTo(rx + width, ry + radius); - context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); - context.lineTo(rx + radius, ry); - context.quadraticCurveTo(rx, ry, rx, ry + radius); - context.closePath(); - - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = '#' + ('00000' + ( fillColor | 0).toString(16)).substr(-6); - context.fill(); - - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeStyle = '#' + ('00000' + ( lineColor | 0).toString(16)).substr(-6); - context.stroke(); - } - } - } -}; - -/* - * Renders a graphics mask - * - * @static - * @private - * @method renderGraphicsMask - * @param graphics {Graphics} the graphics which will be used as a mask - * @param context {CanvasRenderingContext2D} the context 2d method of the canvas - */ -PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) -{ - var len = graphics.graphicsData.length; - - if(len === 0) return; - - if(len > 1) - { - len = 1; - window.console.log('Pixi.js warning: masks in canvas can only mask using the first path in the graphics object'); - } - - for (var i = 0; i < 1; i++) - { - var data = graphics.graphicsData[i]; - var shape = data.shape; - - if(data.type === PIXI.Graphics.POLY) - { - context.beginPath(); - - var points = shape.points; - - context.moveTo(points[0], points[1]); - - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } - - // if the first and last point are the same close the path - much neater :) - if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) - { - context.closePath(); - } - - } - else if(data.type === PIXI.Graphics.RECT) - { - context.beginPath(); - context.rect(shape.x, shape.y, shape.width, shape.height); - context.closePath(); - } - else if(data.type === PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(shape.x, shape.y, shape.radius,0,2*Math.PI); - context.closePath(); - } - else if(data.type === PIXI.Graphics.ELIP) - { - - // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - - var w = shape.width * 2; - var h = shape.height * 2; - - var x = shape.x - w/2; - var y = shape.y - h/2; - - context.beginPath(); - - var kappa = 0.5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle - - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); - } - else if (data.type === PIXI.Graphics.RREC) - { - - var pts = shape.points; - var rx = pts[0]; - var ry = pts[1]; - var width = pts[2]; - var height = pts[3]; - var radius = pts[4]; - - var maxRadius = Math.min(width, height) / 2 | 0; - radius = radius > maxRadius ? maxRadius : radius; - - context.beginPath(); - context.moveTo(rx, ry + radius); - context.lineTo(rx, ry + height - radius); - context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height); - context.lineTo(rx + width - radius, ry + height); - context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius); - context.lineTo(rx + width, ry + radius); - context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry); - context.lineTo(rx + radius, ry); - context.quadraticCurveTo(rx, ry, rx, ry + radius); - context.closePath(); - } - } -}; - -PIXI.CanvasGraphics.updateGraphicsTint = function(graphics) -{ - if(graphics.tint === 0xFFFFFF)return; - - var tintR = (graphics.tint >> 16 & 0xFF) / 255; - var tintG = (graphics.tint >> 8 & 0xFF) / 255; - var tintB = (graphics.tint & 0xFF)/ 255; - - for (var i = 0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - var fillColor = data.fillColor | 0; - var lineColor = data.lineColor | 0; - - /* - var colorR = (fillColor >> 16 & 0xFF) / 255; - var colorG = (fillColor >> 8 & 0xFF) / 255; - var colorB = (fillColor & 0xFF) / 255; - - colorR *= tintR; - colorG *= tintG; - colorB *= tintB; - - fillColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255); - - colorR = (lineColor >> 16 & 0xFF) / 255; - colorG = (lineColor >> 8 & 0xFF) / 255; - colorB = (lineColor & 0xFF) / 255; - - colorR *= tintR; - colorG *= tintG; - colorB *= tintB; - - lineColor = ((colorR*255 << 16) + (colorG*255 << 8) + colorB*255); - */ - - // super inline cos im an optimization NAZI :) - data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG*255 << 8) + (fillColor & 0xFF) / 255 * tintB*255); - data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR*255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG*255 << 8) + (lineColor & 0xFF) / 255 * tintB*255); - - } -}; - diff --git a/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasRenderer.js b/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasRenderer.js deleted file mode 100644 index 02f1170..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/canvas/CanvasRenderer.js +++ /dev/null @@ -1,345 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * The CanvasRenderer draws the Stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. - * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :) - * - * @class CanvasRenderer - * @constructor - * @param [width=800] {Number} the width of the canvas view - * @param [height=600] {Number} the height of the canvas view - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.autoResize=false] {Boolean} If the render view is automatically resized, default false - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * @param [options.clearBeforeRender=true] {Boolean} This sets if the CanvasRenderer will clear the canvas or not before the new render pass. - */ -PIXI.CanvasRenderer = function(width, height, options) -{ - if(options) - { - for (var i in PIXI.defaultRenderOptions) - { - if (typeof options[i] === "undefined") options[i] = PIXI.defaultRenderOptions[i]; - } - } - else - { - options = PIXI.defaultRenderOptions; - } - - if(!PIXI.defaultRenderer) - { - PIXI.sayHello("Canvas"); - PIXI.defaultRenderer = this; - } - - /** - * The renderer type. - * - * @property type - * @type Number - */ - this.type = PIXI.CANVAS_RENDERER; - - /** - * The resolution of the canvas. - * - * @property resolution - * @type Number - */ - this.resolution = options.resolution; - - /** - * This sets if the CanvasRenderer will clear the canvas or not before the new render pass. - * If the Stage is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color. - * If the Stage is transparent Pixi will use clearRect to clear the canvas every frame. - * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set. - * - * @property clearBeforeRender - * @type Boolean - * @default - */ - this.clearBeforeRender = options.clearBeforeRender; - - /** - * Whether the render view is transparent - * - * @property transparent - * @type Boolean - */ - this.transparent = options.transparent; - - /** - * Whether the render view should be resized automatically - * - * @property autoResize - * @type Boolean - */ - this.autoResize = options.autoResize || false; - - - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; - - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; - - this.width *= this.resolution; - this.height *= this.resolution; - - /** - * The canvas element that everything is drawn to. - * - * @property view - * @type HTMLCanvasElement - */ - this.view = options.view || document.createElement( "canvas" ); - - /** - * The canvas 2d context that everything is drawn with - * @property context - * @type CanvasRenderingContext2D - */ - this.context = this.view.getContext( "2d", { alpha: this.transparent } ); - - /** - * Boolean flag controlling canvas refresh. - * - * @property refresh - * @type Boolean - */ - this.refresh = true; - - this.view.width = this.width * this.resolution; - this.view.height = this.height * this.resolution; - - /** - * Internal var. - * - * @property count - * @type Number - */ - this.count = 0; - - /** - * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer - * @property CanvasMaskManager - * @type CanvasMaskManager - */ - this.maskManager = new PIXI.CanvasMaskManager(); - - /** - * The render session is just a bunch of parameter used for rendering - * @property renderSession - * @type Object - */ - this.renderSession = { - context: this.context, - maskManager: this.maskManager, - scaleMode: null, - smoothProperty: null, - /** - * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. - * Handy for crisp pixel art and speed on legacy devices. - * - */ - roundPixels: false - }; - - this.mapBlendModes(); - - this.resize(width, height); - - if("imageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "imageSmoothingEnabled"; - else if("webkitImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "webkitImageSmoothingEnabled"; - else if("mozImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "mozImageSmoothingEnabled"; - else if("oImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "oImageSmoothingEnabled"; - else if ("msImageSmoothingEnabled" in this.context) - this.renderSession.smoothProperty = "msImageSmoothingEnabled"; -}; - -// constructor -PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; - -/** - * Renders the Stage to this canvas view - * - * @method render - * @param stage {Stage} the Stage element to be rendered - */ -PIXI.CanvasRenderer.prototype.render = function(stage) -{ - stage.updateTransform(); - - this.context.setTransform(1,0,0,1,0,0); - - this.context.globalAlpha = 1; - - this.renderSession.currentBlendMode = PIXI.blendModes.NORMAL; - this.context.globalCompositeOperation = PIXI.blendModesCanvas[PIXI.blendModes.NORMAL]; - - if (navigator.isCocoonJS && this.view.screencanvas) { - this.context.fillStyle = "black"; - this.context.clear(); - } - - if (this.clearBeforeRender) - { - if (this.transparent) - { - this.context.clearRect(0, 0, this.width, this.height); - } - else - { - this.context.fillStyle = stage.backgroundColorString; - this.context.fillRect(0, 0, this.width , this.height); - } - } - - this.renderDisplayObject(stage); - - // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } -}; - -/** - * Removes everything from the renderer and optionally removes the Canvas DOM element. - * - * @method destroy - * @param [removeView=true] {boolean} Removes the Canvas element from the DOM. - */ -PIXI.CanvasRenderer.prototype.destroy = function(removeView) -{ - if (typeof removeView === "undefined") { removeView = true; } - - if (removeView && this.view.parent) - { - this.view.parent.removeChild(this.view); - } - - this.view = null; - this.context = null; - this.maskManager = null; - this.renderSession = null; - -}; - -/** - * Resizes the canvas view to the specified width and height - * - * @method resize - * @param width {Number} the new width of the canvas view - * @param height {Number} the new height of the canvas view - */ -PIXI.CanvasRenderer.prototype.resize = function(width, height) -{ - this.width = width * this.resolution; - this.height = height * this.resolution; - - this.view.width = this.width; - this.view.height = this.height; - - if (this.autoResize) { - this.view.style.width = this.width / this.resolution + "px"; - this.view.style.height = this.height / this.resolution + "px"; - } -}; - -/** - * Renders a display object - * - * @method renderDisplayObject - * @param displayObject {DisplayObject} The displayObject to render - * @param context {CanvasRenderingContext2D} the context 2d method of the canvas - * @private - */ -PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context) -{ - this.renderSession.context = context || this.context; - this.renderSession.resolution = this.resolution; - displayObject._renderCanvas(this.renderSession); -}; - -/** - * Maps Pixi blend modes to canvas blend modes. - * - * @method mapBlendModes - * @private - */ -PIXI.CanvasRenderer.prototype.mapBlendModes = function() -{ - if(!PIXI.blendModesCanvas) - { - PIXI.blendModesCanvas = []; - - if(PIXI.canUseNewCanvasBlendModes()) - { - PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? - PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply"; - PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen"; - PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "overlay"; - PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "darken"; - PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "lighten"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn"; - PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light"; - PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light"; - PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference"; - PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion"; - PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "hue"; - PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "color"; - PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity"; - } - else - { - // this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough" - PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK??? - PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "source-over"; - PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over"; - } - } -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasBuffer.js b/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasBuffer.js deleted file mode 100644 index b53d851..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasBuffer.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * Creates a Canvas element of the given size. - * - * @class CanvasBuffer - * @constructor - * @param width {Number} the width for the newly created canvas - * @param height {Number} the height for the newly created canvas - */ -PIXI.CanvasBuffer = function(width, height) -{ - /** - * The width of the Canvas in pixels. - * - * @property width - * @type Number - */ - this.width = width; - - /** - * The height of the Canvas in pixels. - * - * @property height - * @type Number - */ - this.height = height; - - /** - * The Canvas object that belongs to this CanvasBuffer. - * - * @property canvas - * @type HTMLCanvasElement - */ - this.canvas = document.createElement("canvas"); - - /** - * A CanvasRenderingContext2D object representing a two-dimensional rendering context. - * - * @property context - * @type CanvasRenderingContext2D - */ - this.context = this.canvas.getContext("2d"); - - this.canvas.width = width; - this.canvas.height = height; -}; - -PIXI.CanvasBuffer.prototype.constructor = PIXI.CanvasBuffer; - -/** - * Clears the canvas that was created by the CanvasBuffer class. - * - * @method clear - * @private - */ -PIXI.CanvasBuffer.prototype.clear = function() -{ - this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.clearRect(0,0, this.width, this.height); -}; - -/** - * Resizes the canvas to the specified width and height. - * - * @method resize - * @param width {Number} the new width of the canvas - * @param height {Number} the new height of the canvas - */ -PIXI.CanvasBuffer.prototype.resize = function(width, height) -{ - this.width = this.canvas.width = width; - this.height = this.canvas.height = height; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasMaskManager.js b/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasMaskManager.js deleted file mode 100644 index 748adda..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasMaskManager.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A set of functions used to handle masking. - * - * @class CanvasMaskManager - * @constructor - */ -PIXI.CanvasMaskManager = function() -{ -}; - -PIXI.CanvasMaskManager.prototype.constructor = PIXI.CanvasMaskManager; - -/** - * This method adds it to the current stack of masks. - * - * @method pushMask - * @param maskData {Object} the maskData that will be pushed - * @param renderSession {Object} The renderSession whose context will be used for this mask manager. - */ -PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, renderSession) -{ - var context = renderSession.context; - - context.save(); - - var cacheAlpha = maskData.alpha; - var transform = maskData.worldTransform; - - var resolution = renderSession.resolution; - - context.setTransform(transform.a * resolution, - transform.b * resolution, - transform.c * resolution, - transform.d * resolution, - transform.tx * resolution, - transform.ty * resolution); - - PIXI.CanvasGraphics.renderGraphicsMask(maskData, context); - - context.clip(); - - maskData.worldAlpha = cacheAlpha; -}; - -/** - * Restores the current drawing context to the state it was before the mask was applied. - * - * @method popMask - * @param renderSession {Object} The renderSession whose context will be used for this mask manager. - */ -PIXI.CanvasMaskManager.prototype.popMask = function(renderSession) -{ - renderSession.context.restore(); -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasTinter.js b/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasTinter.js deleted file mode 100644 index dd50b06..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/canvas/utils/CanvasTinter.js +++ /dev/null @@ -1,242 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * Utility methods for Sprite/Texture tinting. - * - * @class CanvasTinter - * @static - */ -PIXI.CanvasTinter = function() -{ -}; - -/** - * Basically this method just needs a sprite and a color and tints the sprite with the given color. - * - * @method getTintedTexture - * @static - * @param sprite {Sprite} the sprite to tint - * @param color {Number} the color to use to tint the sprite with - * @return {HTMLCanvasElement} The tinted canvas - */ -PIXI.CanvasTinter.getTintedTexture = function(sprite, color) -{ - var texture = sprite.texture; - - color = PIXI.CanvasTinter.roundColor(color); - - var stringColor = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - - texture.tintCache = texture.tintCache || {}; - - if(texture.tintCache[stringColor]) return texture.tintCache[stringColor]; - - // clone texture.. - var canvas = PIXI.CanvasTinter.canvas || document.createElement("canvas"); - - //PIXI.CanvasTinter.tintWithPerPixel(texture, stringColor, canvas); - PIXI.CanvasTinter.tintMethod(texture, color, canvas); - - if(PIXI.CanvasTinter.convertTintToImage) - { - // is this better? - var tintImage = new Image(); - tintImage.src = canvas.toDataURL(); - - texture.tintCache[stringColor] = tintImage; - } - else - { - texture.tintCache[stringColor] = canvas; - // if we are not converting the texture to an image then we need to lose the reference to the canvas - PIXI.CanvasTinter.canvas = null; - } - - return canvas; -}; - -/** - * Tint a texture using the "multiply" operation. - * - * @method tintWithMultiply - * @static - * @param texture {Texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithMultiply = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var crop = texture.crop; - - canvas.width = crop.width; - canvas.height = crop.height; - - context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - - context.fillRect(0, 0, crop.width, crop.height); - - context.globalCompositeOperation = "multiply"; - - context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, - 0, - 0, - crop.width, - crop.height); - - context.globalCompositeOperation = "destination-atop"; - - context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, - 0, - 0, - crop.width, - crop.height); -}; - -/** - * Tint a texture using the "overlay" operation. - * - * @method tintWithOverlay - * @static - * @param texture {Texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithOverlay = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var crop = texture.crop; - - canvas.width = crop.width; - canvas.height = crop.height; - - context.globalCompositeOperation = "copy"; - context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6); - context.fillRect(0, 0, crop.width, crop.height); - - context.globalCompositeOperation = "destination-atop"; - context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, - 0, - 0, - crop.width, - crop.height); - - //context.globalCompositeOperation = "copy"; -}; - -/** - * Tint a texture pixel per pixel. - * - * @method tintPerPixel - * @static - * @param texture {Texture} the texture to tint - * @param color {Number} the color to use to tint the sprite with - * @param canvas {HTMLCanvasElement} the current canvas - */ -PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas) -{ - var context = canvas.getContext( "2d" ); - - var crop = texture.crop; - - canvas.width = crop.width; - canvas.height = crop.height; - - context.globalCompositeOperation = "copy"; - context.drawImage(texture.baseTexture.source, - crop.x, - crop.y, - crop.width, - crop.height, - 0, - 0, - crop.width, - crop.height); - - var rgbValues = PIXI.hex2rgb(color); - var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2]; - - var pixelData = context.getImageData(0, 0, crop.width, crop.height); - - var pixels = pixelData.data; - - for (var i = 0; i < pixels.length; i += 4) - { - pixels[i+0] *= r; - pixels[i+1] *= g; - pixels[i+2] *= b; - } - - context.putImageData(pixelData, 0, 0); -}; - -/** - * Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel. - * - * @method roundColor - * @static - * @param color {number} the color to round, should be a hex color - */ -PIXI.CanvasTinter.roundColor = function(color) -{ - var step = PIXI.CanvasTinter.cacheStepsPerColorChannel; - - var rgbValues = PIXI.hex2rgb(color); - - rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step); - rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step); - rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step); - - return PIXI.rgb2hex(rgbValues); -}; - -/** - * Number of steps which will be used as a cap when rounding colors. - * - * @property cacheStepsPerColorChannel - * @type Number - * @static - */ -PIXI.CanvasTinter.cacheStepsPerColorChannel = 8; - -/** - * Tint cache boolean flag. - * - * @property convertTintToImage - * @type Boolean - * @static - */ -PIXI.CanvasTinter.convertTintToImage = false; - -/** - * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method. - * - * @property canUseMultiply - * @type Boolean - * @static - */ -PIXI.CanvasTinter.canUseMultiply = PIXI.canUseNewCanvasBlendModes(); - -/** - * The tinting method that will be used. - * - * @method tintMethod - * @static - */ -PIXI.CanvasTinter.tintMethod = PIXI.CanvasTinter.canUseMultiply ? PIXI.CanvasTinter.tintWithMultiply : PIXI.CanvasTinter.tintWithPerPixel; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/WebGLRenderer.js b/app/Lib/Vendor/src/pixi/renderers/webgl/WebGLRenderer.js deleted file mode 100644 index 02b30e4..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/WebGLRenderer.js +++ /dev/null @@ -1,554 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.glContexts = []; // this is where we store the webGL contexts for easy access. -PIXI.instances = []; - -/** - * The WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer - * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs. - * So no need for Sprite Batches or Sprite Clouds. - * Don't forget to add the view to your DOM or you will not see anything :) - * - * @class WebGLRenderer - * @constructor - * @param [width=0] {Number} the width of the canvas view - * @param [height=0] {Number} the height of the canvas view - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.autoResize=false] {Boolean} If the render view is automatically resized, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - */ -PIXI.WebGLRenderer = function(width, height, options) -{ - if(options) - { - for (var i in PIXI.defaultRenderOptions) - { - if (typeof options[i] === 'undefined') options[i] = PIXI.defaultRenderOptions[i]; - } - } - else - { - options = PIXI.defaultRenderOptions; - } - - if(!PIXI.defaultRenderer) - { - PIXI.sayHello('webGL'); - PIXI.defaultRenderer = this; - } - - /** - * @property type - * @type Number - */ - this.type = PIXI.WEBGL_RENDERER; - - /** - * The resolution of the renderer - * - * @property resolution - * @type Number - * @default 1 - */ - this.resolution = options.resolution; - - // do a catch.. only 1 webGL renderer.. - - /** - * Whether the render view is transparent - * - * @property transparent - * @type Boolean - */ - this.transparent = options.transparent; - - /** - * Whether the render view should be resized automatically - * - * @property autoResize - * @type Boolean - */ - this.autoResize = options.autoResize || false; - - /** - * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering. - * - * @property preserveDrawingBuffer - * @type Boolean - */ - this.preserveDrawingBuffer = options.preserveDrawingBuffer; - - /** - * This sets if the WebGLRenderer will clear the context texture or not before the new render pass. If true: - * If the Stage is NOT transparent, Pixi will clear to alpha (0, 0, 0, 0). - * If the Stage is transparent, Pixi will clear to the target Stage's background color. - * Disable this by setting this to false. For example: if your game has a canvas filling background image, you often don't need this set. - * - * @property clearBeforeRender - * @type Boolean - * @default - */ - this.clearBeforeRender = options.clearBeforeRender; - - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; - - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; - - /** - * The canvas element that everything is drawn to - * - * @property view - * @type HTMLCanvasElement - */ - this.view = options.view || document.createElement( 'canvas' ); - - // deal with losing context.. - - /** - * @property contextLostBound - * @type Function - */ - this.contextLostBound = this.handleContextLost.bind(this); - - /** - * @property contextRestoredBound - * @type Function - */ - this.contextRestoredBound = this.handleContextRestored.bind(this); - - this.view.addEventListener('webglcontextlost', this.contextLostBound, false); - this.view.addEventListener('webglcontextrestored', this.contextRestoredBound, false); - - /** - * @property _contextOptions - * @type Object - * @private - */ - this._contextOptions = { - alpha: this.transparent, - antialias: options.antialias, // SPEED UP?? - premultipliedAlpha:this.transparent && this.transparent !== 'notMultiplied', - stencil:true, - preserveDrawingBuffer: options.preserveDrawingBuffer - }; - - /** - * @property projection - * @type Point - */ - this.projection = new PIXI.Point(); - - /** - * @property offset - * @type Point - */ - this.offset = new PIXI.Point(0, 0); - - // time to create the render managers! each one focuses on managing a state in webGL - - /** - * Deals with managing the shader programs and their attribs - * @property shaderManager - * @type WebGLShaderManager - */ - this.shaderManager = new PIXI.WebGLShaderManager(); - - /** - * Manages the rendering of sprites - * @property spriteBatch - * @type WebGLSpriteBatch - */ - this.spriteBatch = new PIXI.WebGLSpriteBatch(); - - /** - * Manages the masks using the stencil buffer - * @property maskManager - * @type WebGLMaskManager - */ - this.maskManager = new PIXI.WebGLMaskManager(); - - /** - * Manages the filters - * @property filterManager - * @type WebGLFilterManager - */ - this.filterManager = new PIXI.WebGLFilterManager(); - - /** - * Manages the stencil buffer - * @property stencilManager - * @type WebGLStencilManager - */ - this.stencilManager = new PIXI.WebGLStencilManager(); - - /** - * Manages the blendModes - * @property blendModeManager - * @type WebGLBlendModeManager - */ - this.blendModeManager = new PIXI.WebGLBlendModeManager(); - - /** - * TODO remove - * @property renderSession - * @type Object - */ - this.renderSession = {}; - this.renderSession.gl = this.gl; - this.renderSession.drawCount = 0; - this.renderSession.shaderManager = this.shaderManager; - this.renderSession.maskManager = this.maskManager; - this.renderSession.filterManager = this.filterManager; - this.renderSession.blendModeManager = this.blendModeManager; - this.renderSession.spriteBatch = this.spriteBatch; - this.renderSession.stencilManager = this.stencilManager; - this.renderSession.renderer = this; - this.renderSession.resolution = this.resolution; - - // time init the context.. - this.initContext(); - - // map some webGL blend modes.. - this.mapBlendModes(); -}; - -// constructor -PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; - -/** -* @method initContext -*/ -PIXI.WebGLRenderer.prototype.initContext = function() -{ - var gl = this.view.getContext('webgl', this._contextOptions) || this.view.getContext('experimental-webgl', this._contextOptions); - this.gl = gl; - - if (!gl) { - // fail, not able to get a context - throw new Error('This browser does not support webGL. Try using the canvas renderer'); - } - - this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++; - - PIXI.glContexts[this.glContextId] = gl; - - PIXI.instances[this.glContextId] = this; - - // set up the default pixi settings.. - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); - gl.enable(gl.BLEND); - - // need to set the context for all the managers... - this.shaderManager.setContext(gl); - this.spriteBatch.setContext(gl); - this.maskManager.setContext(gl); - this.filterManager.setContext(gl); - this.blendModeManager.setContext(gl); - this.stencilManager.setContext(gl); - - this.renderSession.gl = this.gl; - - // now resize and we are good to go! - this.resize(this.width, this.height); -}; - -/** - * Renders the stage to its webGL view - * - * @method render - * @param stage {Stage} the Stage element to be rendered - */ -PIXI.WebGLRenderer.prototype.render = function(stage) -{ - // no point rendering if our context has been blown up! - if(this.contextLost)return; - - // if rendering a new stage clear the batches.. - if(this.__stage !== stage) - { - if(stage.interactive)stage.interactionManager.removeEvents(); - - // TODO make this work - // dont think this is needed any more? - this.__stage = stage; - } - - // update the scene graph - stage.updateTransform(); - - var gl = this.gl; - - // interaction - if(stage._interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - else - { - if(stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = false; - stage.interactionManager.setTarget(this); - } - } - - // -- Does this need to be set every frame? -- // - gl.viewport(0, 0, this.width, this.height); - - // make sure we are bound to the main frame buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - if (this.clearBeforeRender) - { - if(this.transparent) - { - gl.clearColor(0, 0, 0, 0); - } - else - { - gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1); - } - - gl.clear (gl.COLOR_BUFFER_BIT); - } - - this.renderDisplayObject( stage, this.projection ); -}; - -/** - * Renders a Display Object. - * - * @method renderDisplayObject - * @param displayObject {DisplayObject} The DisplayObject to render - * @param projection {Point} The projection - * @param buffer {Array} a standard WebGL buffer - */ -PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, projection, buffer) -{ - this.renderSession.blendModeManager.setBlendMode(PIXI.blendModes.NORMAL); - - // reset the render session data.. - this.renderSession.drawCount = 0; - - // make sure to flip the Y if using a render texture.. - this.renderSession.flipY = buffer ? -1 : 1; - - // set the default projection - this.renderSession.projection = projection; - - //set the default offset - this.renderSession.offset = this.offset; - - // start the sprite batch - this.spriteBatch.begin(this.renderSession); - - // start the filter manager - this.filterManager.begin(this.renderSession, buffer); - - // render the scene! - displayObject._renderWebGL(this.renderSession); - - // finish the sprite batch - this.spriteBatch.end(); -}; - -/** - * Resizes the webGL view to the specified width and height. - * - * @method resize - * @param width {Number} the new width of the webGL view - * @param height {Number} the new height of the webGL view - */ -PIXI.WebGLRenderer.prototype.resize = function(width, height) -{ - this.width = width * this.resolution; - this.height = height * this.resolution; - - this.view.width = this.width; - this.view.height = this.height; - - if (this.autoResize) { - this.view.style.width = this.width / this.resolution + 'px'; - this.view.style.height = this.height / this.resolution + 'px'; - } - - this.gl.viewport(0, 0, this.width, this.height); - - this.projection.x = this.width / 2 / this.resolution; - this.projection.y = -this.height / 2 / this.resolution; -}; - -/** - * Updates and Creates a WebGL texture for the renderers context. - * - * @method updateTexture - * @param texture {Texture} the texture to update - */ -PIXI.WebGLRenderer.prototype.updateTexture = function(texture) -{ - if(!texture.hasLoaded )return; - - var gl = this.gl; - - if(!texture._glTextures[gl.id])texture._glTextures[gl.id] = gl.createTexture(); - - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - - - if(texture.mipmap && PIXI.isPowerOfTwo(texture.width, texture.height)) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); - gl.generateMipmap(gl.TEXTURE_2D); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - } - - // reguler... - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } - - texture._dirty[gl.id] = false; - - return texture._glTextures[gl.id]; -}; - -/** - * Handles a lost webgl context - * - * @method handleContextLost - * @param event {Event} - * @private - */ -PIXI.WebGLRenderer.prototype.handleContextLost = function(event) -{ - event.preventDefault(); - this.contextLost = true; -}; - -/** - * Handles a restored webgl context - * - * @method handleContextRestored - * @param event {Event} - * @private - */ -PIXI.WebGLRenderer.prototype.handleContextRestored = function() -{ - this.initContext(); - - // empty all the ol gl textures as they are useless now - for(var key in PIXI.TextureCache) - { - var texture = PIXI.TextureCache[key].baseTexture; - texture._glTextures = []; - } - - this.contextLost = false; -}; - -/** - * Removes everything from the renderer (event listeners, spritebatch, etc...) - * - * @method destroy - */ -PIXI.WebGLRenderer.prototype.destroy = function() -{ - // remove listeners - this.view.removeEventListener('webglcontextlost', this.contextLostBound); - this.view.removeEventListener('webglcontextrestored', this.contextRestoredBound); - - PIXI.glContexts[this.glContextId] = null; - - this.projection = null; - this.offset = null; - - // time to create the render managers! each one focuses on managine a state in webGL - this.shaderManager.destroy(); - this.spriteBatch.destroy(); - this.maskManager.destroy(); - this.filterManager.destroy(); - - this.shaderManager = null; - this.spriteBatch = null; - this.maskManager = null; - this.filterManager = null; - - this.gl = null; - this.renderSession = null; -}; - -/** - * Maps Pixi blend modes to WebGL blend modes. - * - * @method mapBlendModes - */ -PIXI.WebGLRenderer.prototype.mapBlendModes = function() -{ - var gl = this.gl; - - if(!PIXI.blendModesWebGL) - { - PIXI.blendModesWebGL = []; - - PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE]; - PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]; - } -}; - -PIXI.WebGLRenderer.glContextId = 0; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/ComplexPrimitiveShader.js b/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/ComplexPrimitiveShader.js deleted file mode 100644 index bbd3259..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/ComplexPrimitiveShader.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class ComplexPrimitiveShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.ComplexPrimitiveShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - - 'precision mediump float;', - - 'varying vec4 vColor;', - - 'void main(void) {', - ' gl_FragColor = vColor;', - '}' - ]; - - /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - //'attribute vec4 aColor;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - - 'uniform vec3 tint;', - 'uniform float alpha;', - 'uniform vec3 color;', - 'uniform float flipY;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, (v.y / projectionVector.y * -flipY) + flipY , 0.0, 1.0);', - ' vColor = vec4(color * alpha * tint, alpha);',//" * vec4(tint * alpha, alpha);', - '}' - ]; - - this.init(); -}; - -PIXI.ComplexPrimitiveShader.prototype.constructor = PIXI.ComplexPrimitiveShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.ComplexPrimitiveShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.tintColor = gl.getUniformLocation(program, 'tint'); - this.color = gl.getUniformLocation(program, 'color'); - this.flipY = gl.getUniformLocation(program, 'flipY'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - // this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - this.attributes = [this.aVertexPosition, this.colorAttribute]; - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.ComplexPrimitiveShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attribute = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiFastShader.js b/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiFastShader.js deleted file mode 100644 index 8e685e7..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiFastShader.js +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class PixiFastShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PixiFastShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying float vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]; - - /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aPositionCoord;', - 'attribute vec2 aScale;', - 'attribute float aRotation;', - 'attribute vec2 aTextureCoord;', - 'attribute float aColor;', - - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - 'uniform mat3 uMatrix;', - - 'varying vec2 vTextureCoord;', - 'varying float vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void) {', - ' vec2 v;', - ' vec2 sv = aVertexPosition * aScale;', - ' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);', - ' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);', - ' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;', - ' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - // ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;', - ' vColor = aColor;', - '}' - ]; - - /** - * A local texture counter for multi-texture shaders. - * @property textureCount - * @type Number - */ - this.textureCount = 0; - - this.init(); -}; - -PIXI.PixiFastShader.prototype.constructor = PIXI.PixiFastShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.PixiFastShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.dimensions = gl.getUniformLocation(program, 'dimensions'); - this.uMatrix = gl.getUniformLocation(program, 'uMatrix'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord'); - - this.aScale = gl.getAttribLocation(program, 'aScale'); - this.aRotation = gl.getAttribLocation(program, 'aRotation'); - - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - // Begin worst hack eva // - - // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? - // maybe its somthing to do with the current state of the gl context. - // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel - // If theres any webGL people that know why could happen please help :) - if(this.colorAttribute === -1) - { - this.colorAttribute = 2; - } - - this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute]; - - // End worst hack eva // - - this.program = program; -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.PixiFastShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attributes = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiShader.js b/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiShader.js deleted file mode 100644 index e70be7f..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PixiShader.js +++ /dev/null @@ -1,389 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * @author Richard Davey http://www.photonstorm.com @photonstorm - */ - -/** -* @class PixiShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PixiShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]; - - /** - * A local texture counter for multi-texture shaders. - * @property textureCount - * @type Number - */ - this.textureCount = 0; - - /** - * A local flag - * @property firstRun - * @type Boolean - * @private - */ - this.firstRun = true; - - /** - * A dirty flag - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * Uniform attributes cache. - * @property attributes - * @type Array - * @private - */ - this.attributes = []; - - this.init(); -}; - -PIXI.PixiShader.prototype.constructor = PIXI.PixiShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.PixiShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc); - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.dimensions = gl.getUniformLocation(program, 'dimensions'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - // Begin worst hack eva // - - // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters? - // maybe its something to do with the current state of the gl context. - // I'm convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel - // If theres any webGL people that know why could happen please help :) - if(this.colorAttribute === -1) - { - this.colorAttribute = 2; - } - - this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute]; - - // End worst hack eva // - - // add those custom shaders! - for (var key in this.uniforms) - { - // get the uniform locations.. - this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key); - } - - this.initUniforms(); - - this.program = program; -}; - -/** -* Initialises the shader uniform values. -* -* Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/ -* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf -* -* @method initUniforms -*/ -PIXI.PixiShader.prototype.initUniforms = function() -{ - this.textureCount = 1; - var gl = this.gl; - var uniform; - - for (var key in this.uniforms) - { - uniform = this.uniforms[key]; - - var type = uniform.type; - - if (type === 'sampler2D') - { - uniform._init = false; - - if (uniform.value !== null) - { - this.initSampler2D(uniform); - } - } - else if (type === 'mat2' || type === 'mat3' || type === 'mat4') - { - // These require special handling - uniform.glMatrix = true; - uniform.glValueLength = 1; - - if (type === 'mat2') - { - uniform.glFunc = gl.uniformMatrix2fv; - } - else if (type === 'mat3') - { - uniform.glFunc = gl.uniformMatrix3fv; - } - else if (type === 'mat4') - { - uniform.glFunc = gl.uniformMatrix4fv; - } - } - else - { - // GL function reference - uniform.glFunc = gl['uniform' + type]; - - if (type === '2f' || type === '2i') - { - uniform.glValueLength = 2; - } - else if (type === '3f' || type === '3i') - { - uniform.glValueLength = 3; - } - else if (type === '4f' || type === '4i') - { - uniform.glValueLength = 4; - } - else - { - uniform.glValueLength = 1; - } - } - } - -}; - -/** -* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded) -* -* @method initSampler2D -*/ -PIXI.PixiShader.prototype.initSampler2D = function(uniform) -{ - if (!uniform.value || !uniform.value.baseTexture || !uniform.value.baseTexture.hasLoaded) - { - return; - } - - var gl = this.gl; - - gl.activeTexture(gl['TEXTURE' + this.textureCount]); - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id]); - - // Extended texture data - if (uniform.textureData) - { - var data = uniform.textureData; - - // GLTexture = mag linear, min linear_mipmap_linear, wrap repeat + gl.generateMipmap(gl.TEXTURE_2D); - // GLTextureLinear = mag/min linear, wrap clamp - // GLTextureNearestRepeat = mag/min NEAREST, wrap repeat - // GLTextureNearest = mag/min nearest, wrap clamp - // AudioTexture = whatever + luminance + width 512, height 2, border 0 - // KeyTexture = whatever + luminance + width 256, height 2, border 0 - - // magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST - // wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT - - var magFilter = (data.magFilter) ? data.magFilter : gl.LINEAR; - var minFilter = (data.minFilter) ? data.minFilter : gl.LINEAR; - var wrapS = (data.wrapS) ? data.wrapS : gl.CLAMP_TO_EDGE; - var wrapT = (data.wrapT) ? data.wrapT : gl.CLAMP_TO_EDGE; - var format = (data.luminance) ? gl.LUMINANCE : gl.RGBA; - - if (data.repeat) - { - wrapS = gl.REPEAT; - wrapT = gl.REPEAT; - } - - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY); - - if (data.width) - { - var width = (data.width) ? data.width : 512; - var height = (data.height) ? data.height : 2; - var border = (data.border) ? data.border : 0; - - // void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels); - gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null); - } - else - { - // void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels); - gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.value.baseTexture.source); - } - - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT); - } - - gl.uniform1i(uniform.uniformLocation, this.textureCount); - - uniform._init = true; - - this.textureCount++; - -}; - -/** -* Updates the shader uniform values. -* -* @method syncUniforms -*/ -PIXI.PixiShader.prototype.syncUniforms = function() -{ - this.textureCount = 1; - var uniform; - var gl = this.gl; - - // This would probably be faster in an array and it would guarantee key order - for (var key in this.uniforms) - { - uniform = this.uniforms[key]; - - if (uniform.glValueLength === 1) - { - if (uniform.glMatrix === true) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.transpose, uniform.value); - } - else - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value); - } - } - else if (uniform.glValueLength === 2) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y); - } - else if (uniform.glValueLength === 3) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z); - } - else if (uniform.glValueLength === 4) - { - uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w); - } - else if (uniform.type === 'sampler2D') - { - if (uniform._init) - { - gl.activeTexture(gl['TEXTURE' + this.textureCount]); - - if(uniform.value.baseTexture._dirty[gl.id]) - { - PIXI.instances[gl.id].updateTexture(uniform.value.baseTexture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id]); - } - - // gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl)); - gl.uniform1i(uniform.uniformLocation, this.textureCount); - this.textureCount++; - } - else - { - this.initSampler2D(uniform); - } - } - } - -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.PixiShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attributes = null; -}; - -/** -* The Default Vertex shader source. -* -* @property defaultVertexSrc -* @type String -*/ -PIXI.PixiShader.defaultVertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'attribute vec4 aColor;', - - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - - 'const vec2 center = vec2(-1.0, 1.0);', - - 'void main(void) {', - ' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', - '}' -]; \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PrimitiveShader.js b/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PrimitiveShader.js deleted file mode 100644 index bdaab89..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/PrimitiveShader.js +++ /dev/null @@ -1,117 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class PrimitiveShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.PrimitiveShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' gl_FragColor = vColor;', - '}' - ]; - - /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec4 aColor;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - 'uniform float alpha;', - 'uniform float flipY;', - 'uniform vec3 tint;', - 'varying vec4 vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, (v.y / projectionVector.y * -flipY) + flipY , 0.0, 1.0);', - ' vColor = aColor * vec4(tint * alpha, alpha);', - '}' - ]; - - this.init(); -}; - -PIXI.PrimitiveShader.prototype.constructor = PIXI.PrimitiveShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.PrimitiveShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.tintColor = gl.getUniformLocation(program, 'tint'); - this.flipY = gl.getUniformLocation(program, 'flipY'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - - this.attributes = [this.aVertexPosition, this.colorAttribute]; - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.PrimitiveShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attributes = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/StripShader.js b/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/StripShader.js deleted file mode 100644 index 6b47244..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/shaders/StripShader.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class StripShader -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.StripShader = function(gl) -{ - /** - * @property _UID - * @type Number - * @private - */ - this._UID = PIXI._UID++; - - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - /** - * The WebGL program. - * @property program - * @type Any - */ - this.program = null; - - /** - * The fragment shader. - * @property fragmentSrc - * @type Array - */ - this.fragmentSrc = [ - 'precision mediump float;', - 'varying vec2 vTextureCoord;', - // 'varying float vColor;', - 'uniform float alpha;', - 'uniform sampler2D uSampler;', - - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * alpha;', - // ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);',//gl_FragColor * alpha;', - '}' - ]; - - /** - * The vertex shader. - * @property vertexSrc - * @type Array - */ - this.vertexSrc = [ - 'attribute vec2 aVertexPosition;', - 'attribute vec2 aTextureCoord;', - 'uniform mat3 translationMatrix;', - 'uniform vec2 projectionVector;', - 'uniform vec2 offsetVector;', - // 'uniform float alpha;', - // 'uniform vec3 tint;', - 'varying vec2 vTextureCoord;', - // 'varying vec4 vColor;', - - 'void main(void) {', - ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', - ' v -= offsetVector.xyx;', - ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', - ' vTextureCoord = aTextureCoord;', - // ' vColor = aColor * vec4(tint * alpha, alpha);', - '}' - ]; - - this.init(); -}; - -PIXI.StripShader.prototype.constructor = PIXI.StripShader; - -/** -* Initialises the shader. -* -* @method init -*/ -PIXI.StripShader.prototype.init = function() -{ - var gl = this.gl; - - var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc); - gl.useProgram(program); - - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, 'uSampler'); - this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); - this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); - this.colorAttribute = gl.getAttribLocation(program, 'aColor'); - //this.dimensions = gl.getUniformLocation(this.program, 'dimensions'); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); - this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); - - this.attributes = [this.aVertexPosition, this.aTextureCoord]; - - this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); - this.alpha = gl.getUniformLocation(program, 'alpha'); - - this.program = program; -}; - -/** -* Destroys the shader. -* -* @method destroy -*/ -PIXI.StripShader.prototype.destroy = function() -{ - this.gl.deleteProgram( this.program ); - this.uniforms = null; - this.gl = null; - - this.attribute = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/FilterTexture.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/FilterTexture.js deleted file mode 100644 index 0340289..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/FilterTexture.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class FilterTexture -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -* @param width {Number} the horizontal range of the filter -* @param height {Number} the vertical range of the filter -* @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values -*/ -PIXI.FilterTexture = function(gl, width, height, scaleMode) -{ - /** - * @property gl - * @type WebGLContext - */ - this.gl = gl; - - // next time to create a frame buffer and texture - - /** - * @property frameBuffer - * @type Any - */ - this.frameBuffer = gl.createFramebuffer(); - - /** - * @property texture - * @type Any - */ - this.texture = gl.createTexture(); - - /** - * @property scaleMode - * @type Number - */ - scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; - - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); - - // required for masking a mask?? - this.renderBuffer = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); - gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer); - - this.resize(width, height); -}; - -PIXI.FilterTexture.prototype.constructor = PIXI.FilterTexture; - -/** -* Clears the filter texture. -* -* @method clear -*/ -PIXI.FilterTexture.prototype.clear = function() -{ - var gl = this.gl; - - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); -}; - -/** - * Resizes the texture to the specified width and height - * - * @method resize - * @param width {Number} the new width of the texture - * @param height {Number} the new height of the texture - */ -PIXI.FilterTexture.prototype.resize = function(width, height) -{ - if(this.width === width && this.height === height) return; - - this.width = width; - this.height = height; - - var gl = this.gl; - - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width , height , 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - // update the stencil buffer width and height - gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width , height ); -}; - -/** -* Destroys the filter texture. -* -* @method destroy -*/ -PIXI.FilterTexture.prototype.destroy = function() -{ - var gl = this.gl; - gl.deleteFramebuffer( this.frameBuffer ); - gl.deleteTexture( this.texture ); - - this.frameBuffer = null; - this.texture = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLBlendModeManager.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLBlendModeManager.js deleted file mode 100644 index 3de0ec9..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLBlendModeManager.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLBlendModeManager -* @constructor -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLBlendModeManager = function() -{ - /** - * @property currentBlendMode - * @type Number - */ - this.currentBlendMode = 99999; -}; - -PIXI.WebGLBlendModeManager.prototype.constructor = PIXI.WebGLBlendModeManager; - -/** - * Sets the WebGL Context. - * - * @method setContext - * @param gl {WebGLContext} the current WebGL drawing context - */ -PIXI.WebGLBlendModeManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Sets-up the given blendMode from WebGL's point of view. -* -* @method setBlendMode -* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD -*/ -PIXI.WebGLBlendModeManager.prototype.setBlendMode = function(blendMode) -{ - if(this.currentBlendMode === blendMode)return false; - - this.currentBlendMode = blendMode; - - var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode]; - this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]); - - return true; -}; - -/** -* Destroys this object. -* -* @method destroy -*/ -PIXI.WebGLBlendModeManager.prototype.destroy = function() -{ - this.gl = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js deleted file mode 100644 index 15ed7ae..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js +++ /dev/null @@ -1,428 +0,0 @@ -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * - * Heavily inspired by LibGDX's WebGLSpriteBatch: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java - */ - -/** -* @class WebGLFastSpriteBatch -* @constructor -*/ -PIXI.WebGLFastSpriteBatch = function(gl) -{ - /** - * @property vertSize - * @type Number - */ - this.vertSize = 10; - - /** - * @property maxSize - * @type Number - */ - this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize; - - /** - * @property size - * @type Number - */ - this.size = this.maxSize; - - //the total number of floats in our batch - var numVerts = this.size * 4 * this.vertSize; - - //the total number of indices in our batch - var numIndices = this.maxSize * 6; - - /** - * Vertex data - * @property vertices - * @type Float32Array - */ - this.vertices = new PIXI.Float32Array(numVerts); - - /** - * Index data - * @property indices - * @type Uint16Array - */ - this.indices = new PIXI.Uint16Array(numIndices); - - /** - * @property vertexBuffer - * @type Object - */ - this.vertexBuffer = null; - - /** - * @property indexBuffer - * @type Object - */ - this.indexBuffer = null; - - /** - * @property lastIndexCount - * @type Number - */ - this.lastIndexCount = 0; - - for (var i=0, j=0; i < numIndices; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - /** - * @property drawing - * @type Boolean - */ - this.drawing = false; - - /** - * @property currentBatchSize - * @type Number - */ - this.currentBatchSize = 0; - - /** - * @property currentBaseTexture - * @type BaseTexture - */ - this.currentBaseTexture = null; - - /** - * @property currentBlendMode - * @type Number - */ - this.currentBlendMode = 0; - - /** - * @property renderSession - * @type Object - */ - this.renderSession = null; - - /** - * @property shader - * @type Object - */ - this.shader = null; - - /** - * @property matrix - * @type Matrix - */ - this.matrix = null; - - this.setContext(gl); -}; - -PIXI.WebGLFastSpriteBatch.prototype.constructor = PIXI.WebGLFastSpriteBatch; - -/** - * Sets the WebGL Context. - * - * @method setContext - * @param gl {WebGLContext} the current WebGL drawing context - */ -PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl) -{ - this.gl = gl; - - // create a couple of buffers - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // 65535 is max index, so 65535 / 6 = 10922. - - //upload the index data - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); -}; - -/** - * @method begin - * @param spriteBatch {WebGLSpriteBatch} - * @param renderSession {Object} - */ -PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession) -{ - this.renderSession = renderSession; - this.shader = this.renderSession.shaderManager.fastShader; - - this.matrix = spriteBatch.worldTransform.toArray(true); - - this.start(); -}; - -/** - * @method end - */ -PIXI.WebGLFastSpriteBatch.prototype.end = function() -{ - this.flush(); -}; - -/** - * @method render - * @param spriteBatch {WebGLSpriteBatch} - */ -PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch) -{ - var children = spriteBatch.children; - var sprite = children[0]; - - // if the uvs have not updated then no point rendering just yet! - - // check texture. - if(!sprite.texture._uvs)return; - - this.currentBaseTexture = sprite.texture.baseTexture; - - // check blend mode - if(sprite.blendMode !== this.renderSession.blendModeManager.currentBlendMode) - { - this.flush(); - this.renderSession.blendModeManager.setBlendMode(sprite.blendMode); - } - - for(var i=0,j= children.length; i= this.size) - { - this.flush(); - } -}; - -/** - * @method flush - */ -PIXI.WebGLFastSpriteBatch.prototype.flush = function() -{ - // If the batch is length 0 then return as there is nothing to draw - if (this.currentBatchSize===0)return; - - var gl = this.gl; - - // bind the current texture - - if(!this.currentBaseTexture._glTextures[gl.id])this.renderSession.renderer.updateTexture(this.currentBaseTexture, gl); - - gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]); - - // upload the verts to the buffer - - if(this.currentBatchSize > ( this.size * 0.5 ) ) - { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - } - else - { - var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize); - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); - } - - // now draw those suckas! - gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0); - - // then reset the batch! - this.currentBatchSize = 0; - - // increment the draw count - this.renderSession.drawCount++; -}; - - -/** - * @method stop - */ -PIXI.WebGLFastSpriteBatch.prototype.stop = function() -{ - this.flush(); -}; - -/** - * @method start - */ -PIXI.WebGLFastSpriteBatch.prototype.start = function() -{ - var gl = this.gl; - - // bind the main texture - gl.activeTexture(gl.TEXTURE0); - - // bind the buffers - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // set the projection - var projection = this.renderSession.projection; - gl.uniform2f(this.shader.projectionVector, projection.x, projection.y); - - // set the matrix - gl.uniformMatrix3fv(this.shader.uMatrix, false, this.matrix); - - // set the pointers - var stride = this.vertSize * 4; - - gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); - gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4); - gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4); - gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4); - gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4); - gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4); - -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFilterManager.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFilterManager.js deleted file mode 100644 index ddc4691..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLFilterManager.js +++ /dev/null @@ -1,450 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLFilterManager -* @constructor -*/ -PIXI.WebGLFilterManager = function() -{ - /** - * @property filterStack - * @type Array - */ - this.filterStack = []; - - /** - * @property offsetX - * @type Number - */ - this.offsetX = 0; - - /** - * @property offsetY - * @type Number - */ - this.offsetY = 0; -}; - -PIXI.WebGLFilterManager.prototype.constructor = PIXI.WebGLFilterManager; - -/** -* Initialises the context and the properties. -* -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLFilterManager.prototype.setContext = function(gl) -{ - this.gl = gl; - this.texturePool = []; - - this.initShaderBuffers(); -}; - -/** -* @method begin -* @param renderSession {RenderSession} -* @param buffer {ArrayBuffer} -*/ -PIXI.WebGLFilterManager.prototype.begin = function(renderSession, buffer) -{ - this.renderSession = renderSession; - this.defaultShader = renderSession.shaderManager.defaultShader; - - var projection = this.renderSession.projection; - this.width = projection.x * 2; - this.height = -projection.y * 2; - this.buffer = buffer; -}; - -/** -* Applies the filter and adds it to the current filter stack. -* -* @method pushFilter -* @param filterBlock {Object} the filter that will be pushed to the current filter stack -*/ -PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) -{ - var gl = this.gl; - - var projection = this.renderSession.projection; - var offset = this.renderSession.offset; - - filterBlock._filterArea = filterBlock.target.filterArea || filterBlock.target.getBounds(); - - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); - - var filter = filterBlock.filterPasses[0]; - - this.offsetX += filterBlock._filterArea.x; - this.offsetY += filterBlock._filterArea.y; - - var texture = this.texturePool.pop(); - if(!texture) - { - texture = new PIXI.FilterTexture(this.gl, this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - var filterArea = filterBlock._filterArea;// filterBlock.target.getBounds();///filterBlock.target.filterArea; - - var padding = filter.padding; - filterArea.x -= padding; - filterArea.y -= padding; - filterArea.width += padding * 2; - filterArea.height += padding * 2; - - // cap filter to screen size.. - if(filterArea.x < 0)filterArea.x = 0; - if(filterArea.width > this.width)filterArea.width = this.width; - if(filterArea.y < 0)filterArea.y = 0; - if(filterArea.height > this.height)filterArea.height = this.height; - - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - projection.x = filterArea.width/2; - projection.y = -filterArea.height/2; - - offset.x = -filterArea.x; - offset.y = -filterArea.y; - - // update projection - // now restore the regular shader.. - // this.renderSession.shaderManager.setShader(this.defaultShader); - //gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - //gl.uniform2f(this.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - filterBlock._glFilterTexture = texture; - -}; - -/** -* Removes the last filter from the filter stack and doesn't return it. -* -* @method popFilter -*/ -PIXI.WebGLFilterManager.prototype.popFilter = function() -{ - var gl = this.gl; - var filterBlock = this.filterStack.pop(); - var filterArea = filterBlock._filterArea; - var texture = filterBlock._glFilterTexture; - var projection = this.renderSession.projection; - var offset = this.renderSession.offset; - - if(filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // now set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height); - outputTexture.resize(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a previous filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); - - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - } - - gl.enable(gl.BLEND); - - texture = inputTexture; - this.texturePool.push(outputTexture); - } - - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if(this.filterStack.length === 0) - { - gl.colorMask(true, true, true, true);//this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - filterArea = currentFilter._filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - // TODO need to remove these global elements.. - projection.x = sizeX/2; - projection.y = -sizeY/2; - - offset.x = offsetX; - offset.y = offsetY; - - filterArea = filterBlock._filterArea; - - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set the blend mode! - //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - this.applyFilterPass(filter, filterArea, sizeX, sizeY); - - // now restore the regular shader.. should happen automatically now.. - // this.renderSession.shaderManager.setShader(this.defaultShader); - // gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2); - // gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY); - - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -}; - - -/** -* Applies the filter to the specified area. -* -* @method applyFilterPass -* @param filter {AbstractFilter} the filter that needs to be applied -* @param filterArea {Texture} TODO - might need an update -* @param width {Number} the horizontal range of the filter -* @param height {Number} the vertical range of the filter -*/ -PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height) -{ - // use program - var gl = this.gl; - var shader = filter.shaders[gl.id]; - - if(!shader) - { - shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shaders[gl.id] = shader; - } - - // set the shader - this.renderSession.shaderManager.setShader(shader); - -// gl.useProgram(shader.program); - - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0); - - if(filter.uniforms.dimensions) - { - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - } - - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.vertexAttribPointer(shader.colorAttribute, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... - gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); - - this.renderSession.drawCount++; -}; - -/** -* Initialises the shader buffers. -* -* @method initShaderBuffers -*/ -PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() -{ - var gl = this.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a reference to the vertexFloatData.. - this.vertexArray = new PIXI.Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW); - - // bind and upload the uv buffer - this.uvArray = new PIXI.Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvArray, gl.STATIC_DRAW); - - this.colorArray = new PIXI.Float32Array([1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF, - 1.0, 0xFFFFFF]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colorArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); - -}; - -/** -* Destroys the filter and removes it from the filter stack. -* -* @method destroy -*/ -PIXI.WebGLFilterManager.prototype.destroy = function() -{ - var gl = this.gl; - - this.filterStack = null; - - this.offsetX = 0; - this.offsetY = 0; - - // destroy textures - for (var i = 0; i < this.texturePool.length; i++) { - this.texturePool[i].destroy(); - } - - this.texturePool = null; - - //destroy buffers.. - gl.deleteBuffer(this.vertexBuffer); - gl.deleteBuffer(this.uvBuffer); - gl.deleteBuffer(this.colorBuffer); - gl.deleteBuffer(this.indexBuffer); -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLGraphics.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLGraphics.js deleted file mode 100644 index 710383c..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLGraphics.js +++ /dev/null @@ -1,896 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A set of functions used by the webGL renderer to draw the primitive graphics data - * - * @class WebGLGraphics - * @private - * @static - */ -PIXI.WebGLGraphics = function() -{ -}; - -/** - * Renders the graphics object - * - * @static - * @private - * @method renderGraphics - * @param graphics {Graphics} - * @param renderSession {Object} - */ -PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projection, offset) -{ - var gl = renderSession.gl; - var projection = renderSession.projection, - offset = renderSession.offset, - shader = renderSession.shaderManager.primitiveShader, - webGLData; - - if(graphics.dirty) - { - PIXI.WebGLGraphics.updateGraphics(graphics, gl); - } - - var webGL = graphics._webGL[gl.id]; - - // This could be speeded up for sure! - - for (var i = 0; i < webGL.data.length; i++) - { - if(webGL.data[i].mode === 1) - { - webGLData = webGL.data[i]; - - renderSession.stencilManager.pushStencil(graphics, webGLData, renderSession); - - // render quad.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - renderSession.stencilManager.popStencil(graphics, webGLData, renderSession); - } - else - { - webGLData = webGL.data[i]; - - - renderSession.shaderManager.setShader( shader );//activatePrimitiveShader(); - shader = renderSession.shaderManager.primitiveShader; - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform1f(shader.flipY, 1); - - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - - gl.uniform1f(shader.alpha, graphics.worldAlpha); - - - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - } - } -}; - -/** - * Updates the graphics object - * - * @static - * @private - * @method updateGraphics - * @param graphicsData {Graphics} The graphics object to update - * @param gl {WebGLContext} the current WebGL drawing context - */ -PIXI.WebGLGraphics.updateGraphics = function(graphics, gl) -{ - // get the contexts graphics object - var webGL = graphics._webGL[gl.id]; - // if the graphics object does not exist in the webGL context time to create it! - if(!webGL)webGL = graphics._webGL[gl.id] = {lastIndex:0, data:[], gl:gl}; - - // flag the graphics as not dirty as we are about to update it... - graphics.dirty = false; - - var i; - - // if the user cleared the graphics object we will need to clear every object - if(graphics.clearDirty) - { - graphics.clearDirty = false; - - // lop through and return all the webGLDatas to the object pool so than can be reused later on - for (i = 0; i < webGL.data.length; i++) - { - var graphicsData = webGL.data[i]; - graphicsData.reset(); - PIXI.WebGLGraphics.graphicsDataPool.push( graphicsData ); - } - - // clear the array and reset the index.. - webGL.data = []; - webGL.lastIndex = 0; - } - - var webGLData; - - // loop through the graphics datas and construct each one.. - // if the object is a complex fill then the new stencil buffer technique will be used - // other wise graphics objects will be pushed into a batch.. - for (i = webGL.lastIndex; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - if(data.type === PIXI.Graphics.POLY) - { - // need to add the points the the graphics object.. - data.points = data.shape.points.slice(); - if(data.shape.closed) - { - // close the poly if the value is true! - if(data.points[0] !== data.points[data.points.length-2] || data.points[1] !== data.points[data.points.length-1]) - { - data.points.push(data.points[0], data.points[1]); - } - } - - // MAKE SURE WE HAVE THE CORRECT TYPE.. - if(data.fill) - { - if(data.points.length >= 6) - { - if(data.points.length < 6 * 2) - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - - var canDrawUsingSimple = PIXI.WebGLGraphics.buildPoly(data, webGLData); - // console.log(canDrawUsingSimple); - - if(!canDrawUsingSimple) - { - // console.log("<>>>") - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 1); - PIXI.WebGLGraphics.buildComplexPoly(data, webGLData); - } - - } - else - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 1); - PIXI.WebGLGraphics.buildComplexPoly(data, webGLData); - } - } - } - - if(data.lineWidth > 0) - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - PIXI.WebGLGraphics.buildLine(data, webGLData); - - } - } - else - { - webGLData = PIXI.WebGLGraphics.switchMode(webGL, 0); - - if(data.type === PIXI.Graphics.RECT) - { - PIXI.WebGLGraphics.buildRectangle(data, webGLData); - } - else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP) - { - PIXI.WebGLGraphics.buildCircle(data, webGLData); - } - else if(data.type === PIXI.Graphics.RREC) - { - PIXI.WebGLGraphics.buildRoundedRectangle(data, webGLData); - } - } - - webGL.lastIndex++; - } - - // upload all the dirty data... - for (i = 0; i < webGL.data.length; i++) - { - webGLData = webGL.data[i]; - if(webGLData.dirty)webGLData.upload(); - } -}; - -/** - * @static - * @private - * @method switchMode - * @param webGL {WebGLContext} - * @param type {Number} - */ -PIXI.WebGLGraphics.switchMode = function(webGL, type) -{ - var webGLData; - - if(!webGL.data.length) - { - webGLData = PIXI.WebGLGraphics.graphicsDataPool.pop() || new PIXI.WebGLGraphicsData(webGL.gl); - webGLData.mode = type; - webGL.data.push(webGLData); - } - else - { - webGLData = webGL.data[webGL.data.length-1]; - - if(webGLData.mode !== type || type === 1) - { - webGLData = PIXI.WebGLGraphics.graphicsDataPool.pop() || new PIXI.WebGLGraphicsData(webGL.gl); - webGLData.mode = type; - webGL.data.push(webGLData); - } - } - - webGLData.dirty = true; - - return webGLData; -}; - -/** - * Builds a rectangle to draw - * - * @static - * @private - * @method buildRectangle - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) -{ - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.shape; - var x = rectData.x; - var y = rectData.y; - var width = rectData.width; - var height = rectData.height; - - if(graphicsData.fill) - { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vertPos = verts.length/6; - - // start - verts.push(x, y); - verts.push(r, g, b, alpha); - - verts.push(x + width, y); - verts.push(r, g, b, alpha); - - verts.push(x , y + height); - verts.push(r, g, b, alpha); - - verts.push(x + width, y + height); - verts.push(r, g, b, alpha); - - // insert 2 dead triangles.. - indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3); - } - - if(graphicsData.lineWidth) - { - var tempPoints = graphicsData.points; - - graphicsData.points = [x, y, - x + width, y, - x + width, y + height, - x, y + height, - x, y]; - - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Builds a rounded rectangle to draw - * - * @static - * @private - * @method buildRoundedRectangle - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildRoundedRectangle = function(graphicsData, webGLData) -{ - var rrectData = graphicsData.shape; - var x = rrectData.x; - var y = rrectData.y; - var width = rrectData.width; - var height = rrectData.height; - - var radius = rrectData.radius; - - var recPoints = []; - recPoints.push(x, y + radius); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x, y + height - radius, x, y + height, x + radius, y + height)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + width - radius, y + height, x + width, y + height, x + width, y + height - radius)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + width, y + radius, x + width, y, x + width - radius, y)); - recPoints = recPoints.concat(PIXI.WebGLGraphics.quadraticBezierCurve(x + radius, y, x, y, x, y + radius)); - - if (graphicsData.fill) { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - var triangles = PIXI.PolyK.Triangulate(recPoints); - - // - - var i = 0; - for (i = 0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vecPos); - indices.push(triangles[i] + vecPos); - indices.push(triangles[i+1] + vecPos); - indices.push(triangles[i+2] + vecPos); - indices.push(triangles[i+2] + vecPos); - } - - - for (i = 0; i < recPoints.length; i++) - { - verts.push(recPoints[i], recPoints[++i], r, g, b, alpha); - } - } - - if (graphicsData.lineWidth) { - var tempPoints = graphicsData.points; - - graphicsData.points = recPoints; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Calculate the points for a quadratic bezier curve. (helper function..) - * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c - * - * @static - * @private - * @method quadraticBezierCurve - * @param fromX {Number} Origin point x - * @param fromY {Number} Origin point x - * @param cpX {Number} Control point x - * @param cpY {Number} Control point y - * @param toX {Number} Destination point x - * @param toY {Number} Destination point y - * @return {Array(Number)} - */ -PIXI.WebGLGraphics.quadraticBezierCurve = function(fromX, fromY, cpX, cpY, toX, toY) { - - var xa, - ya, - xb, - yb, - x, - y, - n = 20, - points = []; - - function getPt(n1 , n2, perc) { - var diff = n2 - n1; - - return n1 + ( diff * perc ); - } - - var j = 0; - for (var i = 0; i <= n; i++ ) - { - j = i / n; - - // The Green Line - xa = getPt( fromX , cpX , j ); - ya = getPt( fromY , cpY , j ); - xb = getPt( cpX , toX , j ); - yb = getPt( cpY , toY , j ); - - // The Black Dot - x = getPt( xa , xb , j ); - y = getPt( ya , yb , j ); - - points.push(x, y); - } - return points; -}; - -/** - * Builds a circle to draw - * - * @static - * @private - * @method buildCircle - * @param graphicsData {Graphics} The graphics object to draw - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) -{ - // need to convert points to a nice regular data - var circleData = graphicsData.shape; - var x = circleData.x; - var y = circleData.y; - var width; - var height; - - // TODO - bit hacky?? - if(graphicsData.type === PIXI.Graphics.CIRC) - { - width = circleData.radius; - height = circleData.radius; - } - else - { - width = circleData.width; - height = circleData.height; - } - - var totalSegs = 40; - var seg = (Math.PI * 2) / totalSegs ; - - var i = 0; - - if(graphicsData.fill) - { - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - indices.push(vecPos); - - for (i = 0; i < totalSegs + 1 ; i++) - { - verts.push(x,y, r, g, b, alpha); - - verts.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height, - r, g, b, alpha); - - indices.push(vecPos++, vecPos++); - } - - indices.push(vecPos-1); - } - - if(graphicsData.lineWidth) - { - var tempPoints = graphicsData.points; - - graphicsData.points = []; - - for (i = 0; i < totalSegs + 1; i++) - { - graphicsData.points.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height); - } - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - - graphicsData.points = tempPoints; - } -}; - -/** - * Builds a line to draw - * - * @static - * @private - * @method buildLine - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) -{ - // TODO OPTIMISE! - var i = 0; - var points = graphicsData.points; - if(points.length === 0)return; - - // if the line width is an odd number add 0.5 to align to a whole pixel - if(graphicsData.lineWidth%2) - { - for (i = 0; i < points.length; i++) { - points[i] += 0.5; - } - } - - // get first and last point.. figure out the middle! - var firstPoint = new PIXI.Point( points[0], points[1] ); - var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - // if the first point is the last point - gonna have issues :) - if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) - { - // need to clone as we are going to slightly modify the shape.. - points = points.slice(); - - points.pop(); - points.pop(); - - lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; - var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; - - points.unshift(midPointX, midPointY); - points.push(midPointX, midPointY); - } - - var verts = webGLData.points; - var indices = webGLData.indices; - var length = points.length / 2; - var indexCount = points.length; - var indexStart = verts.length/6; - - // DRAW the Line - var width = graphicsData.lineWidth / 2; - - // sort color - var color = PIXI.hex2rgb(graphicsData.lineColor); - var alpha = graphicsData.lineAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var px, py, p1x, p1y, p2x, p2y, p3x, p3y; - var perpx, perpy, perp2x, perp2y, perp3x, perp3y; - var a1, b1, c1, a2, b2, c2; - var denom, pdist, dist; - - p1x = points[0]; - p1y = points[1]; - - p2x = points[2]; - p2y = points[3]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - // start - verts.push(p1x - perpx , p1y - perpy, - r, g, b, alpha); - - verts.push(p1x + perpx , p1y + perpy, - r, g, b, alpha); - - for (i = 1; i < length-1; i++) - { - p1x = points[(i-1)*2]; - p1y = points[(i-1)*2 + 1]; - - p2x = points[(i)*2]; - p2y = points[(i)*2 + 1]; - - p3x = points[(i+1)*2]; - p3y = points[(i+1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - perp2x = -(p2y - p3y); - perp2y = p2x - p3x; - - dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); - perp2x /= dist; - perp2y /= dist; - perp2x *= width; - perp2y *= width; - - a1 = (-perpy + p1y) - (-perpy + p2y); - b1 = (-perpx + p2x) - (-perpx + p1x); - c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); - a2 = (-perp2y + p3y) - (-perp2y + p2y); - b2 = (-perp2x + p2x) - (-perp2x + p3x); - c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); - - denom = a1*b2 - a2*b1; - - if(Math.abs(denom) < 0.1 ) - { - - denom+=10.1; - verts.push(p2x - perpx , p2y - perpy, - r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy, - r, g, b, alpha); - - continue; - } - - px = (b1*c2 - b2*c1)/denom; - py = (a2*c1 - a1*c2)/denom; - - - pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); - - - if(pdist > 140 * 140) - { - perp3x = perpx - perp2x; - perp3y = perpy - perp2y; - - dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); - perp3x /= dist; - perp3y /= dist; - perp3x *= width; - perp3y *= width; - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x + perp3x, p2y +perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - indexCount++; - } - else - { - - verts.push(px , py); - verts.push(r, g, b, alpha); - - verts.push(p2x - (px-p2x), p2y - (py - p2y)); - verts.push(r, g, b, alpha); - } - } - - p1x = points[(length-2)*2]; - p1y = points[(length-2)*2 + 1]; - - p2x = points[(length-1)*2]; - p2y = points[(length-1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - verts.push(p2x - perpx , p2y - perpy); - verts.push(r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy); - verts.push(r, g, b, alpha); - - indices.push(indexStart); - - for (i = 0; i < indexCount; i++) - { - indices.push(indexStart++); - } - - indices.push(indexStart-1); -}; - -/** - * Builds a complex polygon to draw - * - * @static - * @private - * @method buildComplexPoly - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildComplexPoly = function(graphicsData, webGLData) -{ - //TODO - no need to copy this as it gets turned into a FLoat32Array anyways.. - var points = graphicsData.points.slice(); - if(points.length < 6)return; - - // get first and last point.. figure out the middle! - var indices = webGLData.indices; - webGLData.points = points; - webGLData.alpha = graphicsData.fillAlpha; - webGLData.color = PIXI.hex2rgb(graphicsData.fillColor); - - /* - calclate the bounds.. - */ - var minX = Infinity; - var maxX = -Infinity; - - var minY = Infinity; - var maxY = -Infinity; - - var x,y; - - // get size.. - for (var i = 0; i < points.length; i+=2) - { - x = points[i]; - y = points[i+1]; - - minX = x < minX ? x : minX; - maxX = x > maxX ? x : maxX; - - minY = y < minY ? y : minY; - maxY = y > maxY ? y : maxY; - } - - // add a quad to the end cos there is no point making another buffer! - points.push(minX, minY, - maxX, minY, - maxX, maxY, - minX, maxY); - - // push a quad onto the end.. - - //TODO - this aint needed! - var length = points.length / 2; - for (i = 0; i < length; i++) - { - indices.push( i ); - } - -}; - -/** - * Builds a polygon to draw - * - * @static - * @private - * @method buildPoly - * @param graphicsData {Graphics} The graphics object containing all the necessary properties - * @param webGLData {Object} - */ -PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) -{ - var points = graphicsData.points; - - if(points.length < 6)return; - // get first and last point.. figure out the middle! - var verts = webGLData.points; - var indices = webGLData.indices; - - var length = points.length / 2; - - // sort color - var color = PIXI.hex2rgb(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var triangles = PIXI.PolyK.Triangulate(points); - - if(!triangles)return false; - - var vertPos = verts.length / 6; - - var i = 0; - - for (i = 0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vertPos); - indices.push(triangles[i] + vertPos); - indices.push(triangles[i+1] + vertPos); - indices.push(triangles[i+2] +vertPos); - indices.push(triangles[i+2] + vertPos); - } - - for (i = 0; i < length; i++) - { - verts.push(points[i * 2], points[i * 2 + 1], - r, g, b, alpha); - } - - return true; -}; - -PIXI.WebGLGraphics.graphicsDataPool = []; - -/** - * @class WebGLGraphicsData - * @private - * @static - */ -PIXI.WebGLGraphicsData = function(gl) -{ - this.gl = gl; - - //TODO does this need to be split before uploding?? - this.color = [0,0,0]; // color split! - this.points = []; - this.indices = []; - this.buffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.mode = 1; - this.alpha = 1; - this.dirty = true; -}; - -/** - * @method reset - */ -PIXI.WebGLGraphicsData.prototype.reset = function() -{ - this.points = []; - this.indices = []; -}; - -/** - * @method upload - */ -PIXI.WebGLGraphicsData.prototype.upload = function() -{ - var gl = this.gl; - -// this.lastIndex = graphics.graphicsData.length; - this.glPoints = new PIXI.Float32Array(this.points); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); - gl.bufferData(gl.ARRAY_BUFFER, this.glPoints, gl.STATIC_DRAW); - - this.glIndicies = new PIXI.Uint16Array(this.indices); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.glIndicies, gl.STATIC_DRAW); - - this.dirty = false; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLMaskManager.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLMaskManager.js deleted file mode 100644 index 607d5dd..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLMaskManager.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLMaskManager -* @constructor -* @private -*/ -PIXI.WebGLMaskManager = function() -{ -}; - -PIXI.WebGLMaskManager.prototype.constructor = PIXI.WebGLMaskManager; - -/** -* Sets the drawing context to the one given in parameter. -* -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLMaskManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Applies the Mask and adds it to the current filter stack. -* -* @method pushMask -* @param maskData {Array} -* @param renderSession {Object} -*/ -PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession) -{ - var gl = renderSession.gl; - - if(maskData.dirty) - { - PIXI.WebGLGraphics.updateGraphics(maskData, gl); - } - - if(!maskData._webGL[gl.id].data.length)return; - - renderSession.stencilManager.pushStencil(maskData, maskData._webGL[gl.id].data[0], renderSession); -}; - -/** -* Removes the last filter from the filter stack and doesn't return it. -* -* @method popMask -* @param maskData {Array} -* @param renderSession {Object} an object containing all the useful parameters -*/ -PIXI.WebGLMaskManager.prototype.popMask = function(maskData, renderSession) -{ - var gl = this.gl; - renderSession.stencilManager.popStencil(maskData, maskData._webGL[gl.id].data[0], renderSession); -}; - -/** -* Destroys the mask stack. -* -* @method destroy -*/ -PIXI.WebGLMaskManager.prototype.destroy = function() -{ - this.gl = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderManager.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderManager.js deleted file mode 100644 index a15974e..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderManager.js +++ /dev/null @@ -1,157 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLShaderManager -* @constructor -* @private -*/ -PIXI.WebGLShaderManager = function() -{ - /** - * @property maxAttibs - * @type Number - */ - this.maxAttibs = 10; - - /** - * @property attribState - * @type Array - */ - this.attribState = []; - - /** - * @property tempAttribState - * @type Array - */ - this.tempAttribState = []; - - for (var i = 0; i < this.maxAttibs; i++) - { - this.attribState[i] = false; - } - - /** - * @property stack - * @type Array - */ - this.stack = []; - -}; - -PIXI.WebGLShaderManager.prototype.constructor = PIXI.WebGLShaderManager; - -/** -* Initialises the context and the properties. -* -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLShaderManager.prototype.setContext = function(gl) -{ - this.gl = gl; - - // the next one is used for rendering primitives - this.primitiveShader = new PIXI.PrimitiveShader(gl); - - // the next one is used for rendering triangle strips - this.complexPrimitiveShader = new PIXI.ComplexPrimitiveShader(gl); - - // this shader is used for the default sprite rendering - this.defaultShader = new PIXI.PixiShader(gl); - - // this shader is used for the fast sprite rendering - this.fastShader = new PIXI.PixiFastShader(gl); - - // the next one is used for rendering triangle strips - this.stripShader = new PIXI.StripShader(gl); - this.setShader(this.defaultShader); -}; - -/** -* Takes the attributes given in parameters. -* -* @method setAttribs -* @param attribs {Array} attribs -*/ -PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs) -{ - // reset temp state - var i; - - for (i = 0; i < this.tempAttribState.length; i++) - { - this.tempAttribState[i] = false; - } - - // set the new attribs - for (i = 0; i < attribs.length; i++) - { - var attribId = attribs[i]; - this.tempAttribState[attribId] = true; - } - - var gl = this.gl; - - for (i = 0; i < this.attribState.length; i++) - { - if(this.attribState[i] !== this.tempAttribState[i]) - { - this.attribState[i] = this.tempAttribState[i]; - - if(this.tempAttribState[i]) - { - gl.enableVertexAttribArray(i); - } - else - { - gl.disableVertexAttribArray(i); - } - } - } -}; - -/** -* Sets the current shader. -* -* @method setShader -* @param shader {Any} -*/ -PIXI.WebGLShaderManager.prototype.setShader = function(shader) -{ - if(this._currentId === shader._UID)return false; - - this._currentId = shader._UID; - - this.currentShader = shader; - - this.gl.useProgram(shader.program); - this.setAttribs(shader.attributes); - - return true; -}; - -/** -* Destroys this object. -* -* @method destroy -*/ -PIXI.WebGLShaderManager.prototype.destroy = function() -{ - this.attribState = null; - - this.tempAttribState = null; - - this.primitiveShader.destroy(); - - this.complexPrimitiveShader.destroy(); - - this.defaultShader.destroy(); - - this.fastShader.destroy(); - - this.stripShader.destroy(); - - this.gl = null; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js deleted file mode 100644 index a7d7826..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @method initDefaultShaders -* @static -* @private -*/ -PIXI.initDefaultShaders = function() -{ -}; - -/** -* @method CompileVertexShader -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @return {Any} -*/ -PIXI.CompileVertexShader = function(gl, shaderSrc) -{ - return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); -}; - -/** -* @method CompileFragmentShader -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @return {Any} -*/ -PIXI.CompileFragmentShader = function(gl, shaderSrc) -{ - return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); -}; - -/** -* @method _CompileShader -* @static -* @private -* @param gl {WebGLContext} the current WebGL drawing context -* @param shaderSrc {Array} -* @param shaderType {Number} -* @return {Any} -*/ -PIXI._CompileShader = function(gl, shaderSrc, shaderType) -{ - var src = shaderSrc.join("\n"); - var shader = gl.createShader(shaderType); - gl.shaderSource(shader, src); - gl.compileShader(shader); - - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) - { - window.console.log(gl.getShaderInfoLog(shader)); - return null; - } - - return shader; -}; - -/** -* @method compileProgram -* @static -* @param gl {WebGLContext} the current WebGL drawing context -* @param vertexSrc {Array} -* @param fragmentSrc {Array} -* @return {Any} -*/ -PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc) -{ - var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); - var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); - - var shaderProgram = gl.createProgram(); - - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - gl.linkProgram(shaderProgram); - - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) - { - window.console.log("Could not initialise shaders"); - } - - return shaderProgram; -}; diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js deleted file mode 100755 index 711b4da..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js +++ /dev/null @@ -1,635 +0,0 @@ -/** - * @author Mat Groves - * - * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/ - * for creating the original pixi version! - * Also a thanks to https://github.com/bchevalier for tweaking the tint and alpha so that they now share 4 bytes on the vertex buffer - * - * Heavily inspired by LibGDX's WebGLSpriteBatch: - * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java - */ - - /** - * - * @class WebGLSpriteBatch - * @private - * @constructor - */ -PIXI.WebGLSpriteBatch = function() -{ - /** - * @property vertSize - * @type Number - */ - this.vertSize = 5; - - /** - * The number of images in the SpriteBatch before it flushes - * @property size - * @type Number - */ - this.size = 2000;//Math.pow(2, 16) / this.vertSize; - - //the total number of bytes in our batch - var numVerts = this.size * 4 * 4 * this.vertSize; - //the total number of indices in our batch - var numIndices = this.size * 6; - - /** - * Holds the vertices - * - * @property vertices - * @type ArrayBuffer - */ - this.vertices = new PIXI.ArrayBuffer(numVerts); - - /** - * View on the vertices as a Float32Array - * - * @property positions - * @type Float32Array - */ - this.positions = new PIXI.Float32Array(this.vertices); - - /** - * View on the vertices as a Uint32Array - * - * @property colors - * @type Uint32Array - */ - this.colors = new PIXI.Uint32Array(this.vertices); - - /** - * Holds the indices - * - * @property indices - * @type Uint16Array - */ - this.indices = new PIXI.Uint16Array(numIndices); - - /** - * @property lastIndexCount - * @type Number - */ - this.lastIndexCount = 0; - - for (var i=0, j=0; i < numIndices; i += 6, j += 4) - { - this.indices[i + 0] = j + 0; - this.indices[i + 1] = j + 1; - this.indices[i + 2] = j + 2; - this.indices[i + 3] = j + 0; - this.indices[i + 4] = j + 2; - this.indices[i + 5] = j + 3; - } - - /** - * @property drawing - * @type Boolean - */ - this.drawing = false; - - /** - * @property currentBatchSize - * @type Number - */ - this.currentBatchSize = 0; - - /** - * @property currentBaseTexture - * @type BaseTexture - */ - this.currentBaseTexture = null; - - /** - * @property dirty - * @type Boolean - */ - this.dirty = true; - - /** - * @property textures - * @type Array - */ - this.textures = []; - - /** - * @property blendModes - * @type Array - */ - this.blendModes = []; - - /** - * @property shaders - * @type Array - */ - this.shaders = []; - - /** - * @property sprites - * @type Array - */ - this.sprites = []; - - /** - * @property defaultShader - * @type AbstractFilter - */ - this.defaultShader = new PIXI.AbstractFilter([ - 'precision lowp float;', - 'varying vec2 vTextureCoord;', - 'varying vec4 vColor;', - 'uniform sampler2D uSampler;', - 'void main(void) {', - ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;', - '}' - ]); -}; - -/** -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLSpriteBatch.prototype.setContext = function(gl) -{ - this.gl = gl; - - // create a couple of buffers - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // 65535 is max index, so 65535 / 6 = 10922. - - //upload the index data - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW); - - this.currentBlendMode = 99999; - - var shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc = this.defaultShader.fragmentSrc; - shader.uniforms = {}; - shader.init(); - - this.defaultShader.shaders[gl.id] = shader; -}; - -/** -* @method begin -* @param renderSession {Object} The RenderSession object -*/ -PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession) -{ - this.renderSession = renderSession; - this.shader = this.renderSession.shaderManager.defaultShader; - - this.start(); -}; - -/** -* @method end -*/ -PIXI.WebGLSpriteBatch.prototype.end = function() -{ - this.flush(); -}; - -/** -* @method render -* @param sprite {Sprite} the sprite to render when using this spritebatch -*/ -PIXI.WebGLSpriteBatch.prototype.render = function(sprite) -{ - var texture = sprite.texture; - - //TODO set blend modes.. - // check texture.. - if(this.currentBatchSize >= this.size) - { - this.flush(); - this.currentBaseTexture = texture.baseTexture; - } - - // get the uvs for the texture - var uvs = texture._uvs; - // if the uvs have not updated then no point rendering just yet! - if(!uvs)return; - - // TODO trim?? - var aX = sprite.anchor.x; - var aY = sprite.anchor.y; - - var w0, w1, h0, h1; - - if (texture.trim) - { - // if the sprite is trimmed then we need to add the extra space before transforming the sprite coords.. - var trim = texture.trim; - - w1 = trim.x - aX * trim.width; - w0 = w1 + texture.crop.width; - - h1 = trim.y - aY * trim.height; - h0 = h1 + texture.crop.height; - - } - else - { - w0 = (texture.frame.width ) * (1-aX); - w1 = (texture.frame.width ) * -aX; - - h0 = texture.frame.height * (1-aY); - h1 = texture.frame.height * -aY; - } - - var index = this.currentBatchSize * 4 * this.vertSize; - - var resolution = texture.baseTexture.resolution; - - var worldTransform = sprite.worldTransform; - - var a = worldTransform.a / resolution; - var b = worldTransform.b / resolution; - var c = worldTransform.c / resolution; - var d = worldTransform.d / resolution; - var tx = worldTransform.tx; - var ty = worldTransform.ty; - - var colors = this.colors; - var positions = this.positions; - - if(this.renderSession.roundPixels) - { - // xy - positions[index] = a * w1 + c * h1 + tx | 0; - positions[index+1] = d * h1 + b * w1 + ty | 0; - - // xy - positions[index+5] = a * w0 + c * h1 + tx | 0; - positions[index+6] = d * h1 + b * w0 + ty | 0; - - // xy - positions[index+10] = a * w0 + c * h0 + tx | 0; - positions[index+11] = d * h0 + b * w0 + ty | 0; - - // xy - positions[index+15] = a * w1 + c * h0 + tx | 0; - positions[index+16] = d * h0 + b * w1 + ty | 0; - } - else - { - // xy - positions[index] = a * w1 + c * h1 + tx; - positions[index+1] = d * h1 + b * w1 + ty; - - // xy - positions[index+5] = a * w0 + c * h1 + tx; - positions[index+6] = d * h1 + b * w0 + ty; - - // xy - positions[index+10] = a * w0 + c * h0 + tx; - positions[index+11] = d * h0 + b * w0 + ty; - - // xy - positions[index+15] = a * w1 + c * h0 + tx; - positions[index+16] = d * h0 + b * w1 + ty; - } - - // uv - positions[index+2] = uvs.x0; - positions[index+3] = uvs.y0; - - // uv - positions[index+7] = uvs.x1; - positions[index+8] = uvs.y1; - - // uv - positions[index+12] = uvs.x2; - positions[index+13] = uvs.y2; - - // uv - positions[index+17] = uvs.x3; - positions[index+18] = uvs.y3; - - // color and alpha - var tint = sprite.tint; - colors[index+4] = colors[index+9] = colors[index+14] = colors[index+19] = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (sprite.worldAlpha * 255 << 24); - - // increment the batchsize - this.sprites[this.currentBatchSize++] = sprite; - - -}; - -/** -* Renders a TilingSprite using the spriteBatch. -* -* @method renderTilingSprite -* @param sprite {TilingSprite} the tilingSprite to render -*/ -PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite) -{ - var texture = tilingSprite.tilingTexture; - - // check texture.. - if(this.currentBatchSize >= this.size) - { - //return; - this.flush(); - this.currentBaseTexture = texture.baseTexture; - } - - // set the textures uvs temporarily - // TODO create a separate texture so that we can tile part of a texture - - if(!tilingSprite._uvs)tilingSprite._uvs = new PIXI.TextureUvs(); - - var uvs = tilingSprite._uvs; - - tilingSprite.tilePosition.x %= texture.baseTexture.width * tilingSprite.tileScaleOffset.x; - tilingSprite.tilePosition.y %= texture.baseTexture.height * tilingSprite.tileScaleOffset.y; - - var offsetX = tilingSprite.tilePosition.x/(texture.baseTexture.width*tilingSprite.tileScaleOffset.x); - var offsetY = tilingSprite.tilePosition.y/(texture.baseTexture.height*tilingSprite.tileScaleOffset.y); - - var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x); - var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y); - - uvs.x0 = 0 - offsetX; - uvs.y0 = 0 - offsetY; - - uvs.x1 = (1 * scaleX) - offsetX; - uvs.y1 = 0 - offsetY; - - uvs.x2 = (1 * scaleX) - offsetX; - uvs.y2 = (1 * scaleY) - offsetY; - - uvs.x3 = 0 - offsetX; - uvs.y3 = (1 * scaleY) - offsetY; - - // get the tilingSprites current alpha and tint and combining them into a single color - var tint = tilingSprite.tint; - var color = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (tilingSprite.alpha * 255 << 24); - - var positions = this.positions; - var colors = this.colors; - - var width = tilingSprite.width; - var height = tilingSprite.height; - - // TODO trim?? - var aX = tilingSprite.anchor.x; - var aY = tilingSprite.anchor.y; - var w0 = width * (1-aX); - var w1 = width * -aX; - - var h0 = height * (1-aY); - var h1 = height * -aY; - - var index = this.currentBatchSize * 4 * this.vertSize; - - var resolution = texture.baseTexture.resolution; - - var worldTransform = tilingSprite.worldTransform; - - var a = worldTransform.a / resolution;//[0]; - var b = worldTransform.b / resolution;//[3]; - var c = worldTransform.c / resolution;//[1]; - var d = worldTransform.d / resolution;//[4]; - var tx = worldTransform.tx;//[2]; - var ty = worldTransform.ty;//[5]; - - // xy - positions[index++] = a * w1 + c * h1 + tx; - positions[index++] = d * h1 + b * w1 + ty; - // uv - positions[index++] = uvs.x0; - positions[index++] = uvs.y0; - // color - colors[index++] = color; - - // xy - positions[index++] = (a * w0 + c * h1 + tx); - positions[index++] = d * h1 + b * w0 + ty; - // uv - positions[index++] = uvs.x1; - positions[index++] = uvs.y1; - // color - colors[index++] = color; - - // xy - positions[index++] = a * w0 + c * h0 + tx; - positions[index++] = d * h0 + b * w0 + ty; - // uv - positions[index++] = uvs.x2; - positions[index++] = uvs.y2; - // color - colors[index++] = color; - - // xy - positions[index++] = a * w1 + c * h0 + tx; - positions[index++] = d * h0 + b * w1 + ty; - // uv - positions[index++] = uvs.x3; - positions[index++] = uvs.y3; - // color - colors[index++] = color; - - // increment the batchsize - this.sprites[this.currentBatchSize++] = tilingSprite; -}; - -/** -* Renders the content and empties the current batch. -* -* @method flush -*/ -PIXI.WebGLSpriteBatch.prototype.flush = function() -{ - // If the batch is length 0 then return as there is nothing to draw - if (this.currentBatchSize===0)return; - - var gl = this.gl; - var shader; - - if(this.dirty) - { - this.dirty = false; - // bind the main texture - gl.activeTexture(gl.TEXTURE0); - - // bind the buffers - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - shader = this.defaultShader.shaders[gl.id]; - - // this is the same for each shader? - var stride = this.vertSize * 4; - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0); - gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4); - - // color attributes will be interpreted as unsigned bytes and normalized - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.UNSIGNED_BYTE, true, stride, 4 * 4); - } - - // upload the verts to the buffer - if(this.currentBatchSize > ( this.size * 0.5 ) ) - { - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices); - } - else - { - var view = this.positions.subarray(0, this.currentBatchSize * 4 * this.vertSize); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, view); - } - - var nextTexture, nextBlendMode, nextShader; - var batchSize = 0; - var start = 0; - - var currentBaseTexture = null; - var currentBlendMode = this.renderSession.blendModeManager.currentBlendMode; - var currentShader = null; - - var blendSwap = false; - var shaderSwap = false; - var sprite; - - for (var i = 0, j = this.currentBatchSize; i < j; i++) { - - sprite = this.sprites[i]; - - nextTexture = sprite.texture.baseTexture; - nextBlendMode = sprite.blendMode; - nextShader = sprite.shader || this.defaultShader; - - blendSwap = currentBlendMode !== nextBlendMode; - shaderSwap = currentShader !== nextShader; // should I use _UIDS??? - - if(currentBaseTexture !== nextTexture || blendSwap || shaderSwap) - { - this.renderBatch(currentBaseTexture, batchSize, start); - - start = i; - batchSize = 0; - currentBaseTexture = nextTexture; - - if( blendSwap ) - { - currentBlendMode = nextBlendMode; - this.renderSession.blendModeManager.setBlendMode( currentBlendMode ); - } - - if( shaderSwap ) - { - currentShader = nextShader; - - shader = currentShader.shaders[gl.id]; - - if(!shader) - { - shader = new PIXI.PixiShader(gl); - - shader.fragmentSrc =currentShader.fragmentSrc; - shader.uniforms =currentShader.uniforms; - shader.init(); - - currentShader.shaders[gl.id] = shader; - } - - // set shader function??? - this.renderSession.shaderManager.setShader(shader); - - if(shader.dirty)shader.syncUniforms(); - - // both thease only need to be set if they are changing.. - // set the projection - var projection = this.renderSession.projection; - gl.uniform2f(shader.projectionVector, projection.x, projection.y); - - // TODO - this is temprorary! - var offsetVector = this.renderSession.offset; - gl.uniform2f(shader.offsetVector, offsetVector.x, offsetVector.y); - - // set the pointers - } - } - - batchSize++; - } - - this.renderBatch(currentBaseTexture, batchSize, start); - - // then reset the batch! - this.currentBatchSize = 0; -}; - -/** -* @method renderBatch -* @param texture {Texture} -* @param size {Number} -* @param startIndex {Number} -*/ -PIXI.WebGLSpriteBatch.prototype.renderBatch = function(texture, size, startIndex) -{ - if(size === 0)return; - - var gl = this.gl; - - // check if a texture is dirty.. - if(texture._dirty[gl.id]) - { - this.renderSession.renderer.updateTexture(texture); - } - else - { - // bind the current texture - gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]); - } - - // now draw those suckas! - gl.drawElements(gl.TRIANGLES, size * 6, gl.UNSIGNED_SHORT, startIndex * 6 * 2); - - // increment the draw count - this.renderSession.drawCount++; -}; - -/** -* @method stop -*/ -PIXI.WebGLSpriteBatch.prototype.stop = function() -{ - this.flush(); - this.dirty = true; -}; - -/** -* @method start -*/ -PIXI.WebGLSpriteBatch.prototype.start = function() -{ - this.dirty = true; -}; - -/** -* Destroys the SpriteBatch. -* -* @method destroy -*/ -PIXI.WebGLSpriteBatch.prototype.destroy = function() -{ - this.vertices = null; - this.indices = null; - - this.gl.deleteBuffer( this.vertexBuffer ); - this.gl.deleteBuffer( this.indexBuffer ); - - this.currentBaseTexture = null; - - this.gl = null; -}; \ No newline at end of file diff --git a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLStencilManager.js b/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLStencilManager.js deleted file mode 100644 index 989d8cf..0000000 --- a/app/Lib/Vendor/src/pixi/renderers/webgl/utils/WebGLStencilManager.js +++ /dev/null @@ -1,297 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** -* @class WebGLStencilManager -* @constructor -* @private -*/ -PIXI.WebGLStencilManager = function() -{ - this.stencilStack = []; - this.reverse = true; - this.count = 0; -}; - -/** -* Sets the drawing context to the one given in parameter. -* -* @method setContext -* @param gl {WebGLContext} the current WebGL drawing context -*/ -PIXI.WebGLStencilManager.prototype.setContext = function(gl) -{ - this.gl = gl; -}; - -/** -* Applies the Mask and adds it to the current filter stack. -* -* @method pushMask -* @param graphics {Graphics} -* @param webGLData {Array} -* @param renderSession {Object} -*/ -PIXI.WebGLStencilManager.prototype.pushStencil = function(graphics, webGLData, renderSession) -{ - var gl = this.gl; - this.bindGraphics(graphics, webGLData, renderSession); - - if(this.stencilStack.length === 0) - { - gl.enable(gl.STENCIL_TEST); - gl.clear(gl.STENCIL_BUFFER_BIT); - this.reverse = true; - this.count = 0; - } - - this.stencilStack.push(webGLData); - - var level = this.count; - - gl.colorMask(false, false, false, false); - - gl.stencilFunc(gl.ALWAYS,0,0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT); - - // draw the triangle strip! - - if(webGLData.mode === 1) - { - gl.drawElements(gl.TRIANGLE_FAN, webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 ); - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - - // draw a quad to increment.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - } - - this.reverse = !this.reverse; - } - else - { - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level+1), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - } - } - - gl.colorMask(true, true, true, true); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - - this.count++; -}; - -/** - * TODO this does not belong here! - * - * @method bindGraphics - * @param graphics {Graphics} - * @param webGLData {Array} - * @param renderSession {Object} - */ -PIXI.WebGLStencilManager.prototype.bindGraphics = function(graphics, webGLData, renderSession) -{ - //if(this._currentGraphics === graphics)return; - this._currentGraphics = graphics; - - var gl = this.gl; - - // bind the graphics object.. - var projection = renderSession.projection, - offset = renderSession.offset, - shader;// = renderSession.shaderManager.primitiveShader; - - if(webGLData.mode === 1) - { - shader = renderSession.shaderManager.complexPrimitiveShader; - - renderSession.shaderManager.setShader( shader ); - - gl.uniform1f(shader.flipY, renderSession.flipY); - - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - gl.uniform3fv(shader.color, webGLData.color); - - gl.uniform1f(shader.alpha, graphics.worldAlpha * webGLData.alpha); - - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 2, 0); - - - // now do the rest.. - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - } - else - { - //renderSession.shaderManager.activatePrimitiveShader(); - shader = renderSession.shaderManager.primitiveShader; - renderSession.shaderManager.setShader( shader ); - - gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true)); - - gl.uniform1f(shader.flipY, renderSession.flipY); - gl.uniform2f(shader.projectionVector, projection.x, -projection.y); - gl.uniform2f(shader.offsetVector, -offset.x, -offset.y); - - gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint)); - - gl.uniform1f(shader.alpha, graphics.worldAlpha); - - gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer); - - gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGLData.indexBuffer); - } -}; - -/** - * @method popStencil - * @param graphics {Graphics} - * @param webGLData {Array} - * @param renderSession {Object} - */ -PIXI.WebGLStencilManager.prototype.popStencil = function(graphics, webGLData, renderSession) -{ - var gl = this.gl; - this.stencilStack.pop(); - - this.count--; - - if(this.stencilStack.length === 0) - { - // the stack is empty! - gl.disable(gl.STENCIL_TEST); - - } - else - { - - var level = this.count; - - this.bindGraphics(graphics, webGLData, renderSession); - - gl.colorMask(false, false, false, false); - - if(webGLData.mode === 1) - { - this.reverse = !this.reverse; - - if(this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - - // draw a quad to increment.. - gl.drawElements(gl.TRIANGLE_FAN, 4, gl.UNSIGNED_SHORT, ( webGLData.indices.length - 4 ) * 2 ); - - gl.stencilFunc(gl.ALWAYS,0,0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INVERT); - - // draw the triangle strip! - gl.drawElements(gl.TRIANGLE_FAN, webGLData.indices.length - 4, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - } - - } - else - { - // console.log("<<>>") - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL, 0xFF - (level+1), 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR); - } - else - { - gl.stencilFunc(gl.EQUAL,level+1, 0xFF); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR); - } - - gl.drawElements(gl.TRIANGLE_STRIP, webGLData.indices.length, gl.UNSIGNED_SHORT, 0 ); - - if(!this.reverse) - { - gl.stencilFunc(gl.EQUAL,0xFF-(level), 0xFF); - } - else - { - gl.stencilFunc(gl.EQUAL,level, 0xFF); - } - } - - gl.colorMask(true, true, true, true); - gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP); - - - } -}; - -/** -* Destroys the mask stack. -* -* @method destroy -*/ -PIXI.WebGLStencilManager.prototype.destroy = function() -{ - this.stencilStack = null; - this.gl = null; -}; diff --git a/app/Lib/Vendor/src/pixi/text/BitmapText.js b/app/Lib/Vendor/src/pixi/text/BitmapText.js deleted file mode 100644 index a1d20af..0000000 --- a/app/Lib/Vendor/src/pixi/text/BitmapText.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A BitmapText object will create a line or multiple lines of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' in your string. - * You can generate the fnt files using - * http://www.angelcode.com/products/bmfont/ for windows or - * http://www.bmglyph.com/ for mac. - * - * @class BitmapText - * @extends DisplayObjectContainer - * @constructor - * @param text {String} The copy that you would like the text to display - * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - */ -PIXI.BitmapText = function(text, style) -{ - PIXI.DisplayObjectContainer.call(this); - - /** - * [read-only] The width of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textWidth - * @type Number - * @readOnly - */ - this.textWidth = 0; - - /** - * [read-only] The height of the overall text, different from fontSize, - * which is defined in the style object - * - * @property textHeight - * @type Number - * @readOnly - */ - this.textHeight = 0; - - /** - * @property _pool - * @type Array - * @private - */ - this._pool = []; - - this.setText(text); - this.setStyle(style); - this.updateText(); - - /** - * The dirty state of this object. - * @property dirty - * @type Boolean - */ - this.dirty = false; -}; - -// constructor -PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); -PIXI.BitmapText.prototype.constructor = PIXI.BitmapText; - -/** - * Set the text string to be rendered. - * - * @method setText - * @param text {String} The text that you would like displayed - */ -PIXI.BitmapText.prototype.setText = function(text) -{ - this.text = text || ' '; - this.dirty = true; -}; - -/** - * Set the style of the text - * style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) - * [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single lines of text - * - * @method setStyle - * @param style {Object} The style parameters, contained as properties of an object - */ -PIXI.BitmapText.prototype.setStyle = function(style) -{ - style = style || {}; - style.align = style.align || 'left'; - this.style = style; - - var font = style.font.split(' '); - this.fontName = font[font.length - 1]; - this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size; - - this.dirty = true; - this.tint = style.tint; -}; - -/** - * Renders text and updates it when needed - * - * @method updateText - * @private - */ -PIXI.BitmapText.prototype.updateText = function() -{ - var data = PIXI.BitmapText.fonts[this.fontName]; - var pos = new PIXI.Point(); - var prevCharCode = null; - var chars = []; - var maxLineWidth = 0; - var lineWidths = []; - var line = 0; - var scale = this.fontSize / data.size; - - for(var i = 0; i < this.text.length; i++) - { - var charCode = this.text.charCodeAt(i); - - if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i))) - { - lineWidths.push(pos.x); - maxLineWidth = Math.max(maxLineWidth, pos.x); - line++; - - pos.x = 0; - pos.y += data.lineHeight; - prevCharCode = null; - continue; - } - - var charData = data.chars[charCode]; - - if(!charData) continue; - - if(prevCharCode && charData.kerning[prevCharCode]) - { - pos.x += charData.kerning[prevCharCode]; - } - - chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)}); - pos.x += charData.xAdvance; - - prevCharCode = charCode; - } - - lineWidths.push(pos.x); - maxLineWidth = Math.max(maxLineWidth, pos.x); - - var lineAlignOffsets = []; - - for(i = 0; i <= line; i++) - { - var alignOffset = 0; - if(this.style.align === 'right') - { - alignOffset = maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - alignOffset = (maxLineWidth - lineWidths[i]) / 2; - } - lineAlignOffsets.push(alignOffset); - } - - var lenChildren = this.children.length; - var lenChars = chars.length; - var tint = this.tint || 0xFFFFFF; - - for(i = 0; i < lenChars; i++) - { - var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool. - - if (c) c.setTexture(chars[i].texture); // check if got one before. - else c = new PIXI.Sprite(chars[i].texture); // if no create new one. - - c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale; - c.position.y = chars[i].position.y * scale; - c.scale.x = c.scale.y = scale; - c.tint = tint; - if (!c.parent) this.addChild(c); - } - - // remove unnecessary children. - // and put their into the pool. - while(this.children.length > lenChars) - { - var child = this.getChildAt(this.children.length - 1); - this._pool.push(child); - this.removeChild(child); - } - - this.textWidth = maxLineWidth * scale; - this.textHeight = (pos.y + data.lineHeight) * scale; -}; - -/** - * Updates the transform of this object - * - * @method updateTransform - * @private - */ -PIXI.BitmapText.prototype.updateTransform = function() -{ - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); -}; - -PIXI.BitmapText.fonts = {}; diff --git a/app/Lib/Vendor/src/pixi/text/Text.js b/app/Lib/Vendor/src/pixi/text/Text.js deleted file mode 100644 index abf0242..0000000 --- a/app/Lib/Vendor/src/pixi/text/Text.js +++ /dev/null @@ -1,533 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * Modified by Tom Slezakowski http://www.tomslezakowski.com @TomSlezakowski (24/03/2014) - Added dropShadowColor. - */ - -/** - * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string, - * or add a wordWrap property set to true and and wordWrapWidth property with a value in the style object. - * - * @class Text - * @extends Sprite - * @constructor - * @param text {String} The copy that you would like the text to display - * @param [style] {Object} The style parameters - * @param [style.font] {String} default 'bold 20px Arial' The style and size of the font - * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap, it needs wordWrap to be set to true - * @param [style.dropShadow=false] {Boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {String} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {Number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {Number} Set a distance of the drop shadow - */ -PIXI.Text = function(text, style) -{ - /** - * The canvas element that everything is drawn to - * - * @property canvas - * @type HTMLCanvasElement - */ - this.canvas = document.createElement('canvas'); - - /** - * The canvas 2d context that everything is drawn with - * @property context - * @type HTMLCanvasElement - */ - this.context = this.canvas.getContext('2d'); - - /** - * The resolution of the canvas. - * @property resolution - * @type Number - */ - this.resolution = 1; - - PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas)); - - this.setText(text); - this.setStyle(style); - -}; - -// constructor -PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype); -PIXI.Text.prototype.constructor = PIXI.Text; - -/** - * The width of the Text, setting this will actually modify the scale to achieve the value set - * - * @property width - * @type Number - */ -Object.defineProperty(PIXI.Text.prototype, 'width', { - get: function() { - - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - - return this.scale.x * this.texture.frame.width; - }, - set: function(value) { - this.scale.x = value / this.texture.frame.width; - this._width = value; - } -}); - -/** - * The height of the Text, setting this will actually modify the scale to achieve the value set - * - * @property height - * @type Number - */ -Object.defineProperty(PIXI.Text.prototype, 'height', { - get: function() { - - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - - return this.scale.y * this.texture.frame.height; - }, - set: function(value) { - this.scale.y = value / this.texture.frame.height; - this._height = value; - } -}); - -/** - * Set the style of the text - * - * @method setStyle - * @param [style] {Object} The style parameters - * @param [style.font='bold 20pt Arial'] {String} The style and size of the font - * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' - * @param [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke='black'] {String} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap - * @param [style.dropShadow=false] {Boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {String} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {Number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {Number} Set a distance of the drop shadow - */ -PIXI.Text.prototype.setStyle = function(style) -{ - style = style || {}; - style.font = style.font || 'bold 20pt Arial'; - style.fill = style.fill || 'black'; - style.align = style.align || 'left'; - style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/GoodBoyDigital/pixi.js/issues/136 - style.strokeThickness = style.strokeThickness || 0; - style.wordWrap = style.wordWrap || false; - style.wordWrapWidth = style.wordWrapWidth || 100; - - style.dropShadow = style.dropShadow || false; - style.dropShadowAngle = style.dropShadowAngle || Math.PI / 6; - style.dropShadowDistance = style.dropShadowDistance || 4; - style.dropShadowColor = style.dropShadowColor || 'black'; - - this.style = style; - this.dirty = true; -}; - -/** - * Set the copy for the text object. To split a line you can use '\n'. - * - * @method setText - * @param text {String} The copy that you would like the text to display - */ -PIXI.Text.prototype.setText = function(text) -{ - this.text = text.toString() || ' '; - this.dirty = true; -}; - -/** - * Renders text and updates it when needed - * - * @method updateText - * @private - */ -PIXI.Text.prototype.updateText = function() -{ - this.texture.baseTexture.resolution = this.resolution; - - this.context.font = this.style.font; - - var outputText = this.text; - - // word wrap - // preserve original text - if(this.style.wordWrap)outputText = this.wordWrap(this.text); - - //split text into lines - var lines = outputText.split(/(?:\r\n|\r|\n)/); - - //calculate text width - var lineWidths = []; - var maxLineWidth = 0; - var fontProperties = this.determineFontProperties(this.style.font); - for (var i = 0; i < lines.length; i++) - { - var lineWidth = this.context.measureText(lines[i]).width; - lineWidths[i] = lineWidth; - maxLineWidth = Math.max(maxLineWidth, lineWidth); - } - - var width = maxLineWidth + this.style.strokeThickness; - if(this.style.dropShadow)width += this.style.dropShadowDistance; - - this.canvas.width = ( width + this.context.lineWidth ) * this.resolution; - - //calculate text height - var lineHeight = fontProperties.fontSize + this.style.strokeThickness; - - var height = lineHeight * lines.length; - if(this.style.dropShadow)height += this.style.dropShadowDistance; - - this.canvas.height = height * this.resolution; - - this.context.scale( this.resolution, this.resolution); - - if(navigator.isCocoonJS) this.context.clearRect(0,0,this.canvas.width,this.canvas.height); - - // used for debugging.. - //this.context.fillStyle ="#FF0000" - //this.context.fillRect(0, 0, this.canvas.width,this.canvas.height); - - this.context.font = this.style.font; - this.context.strokeStyle = this.style.stroke; - this.context.lineWidth = this.style.strokeThickness; - this.context.textBaseline = 'alphabetic'; - //this.context.lineJoin = 'round'; - - var linePositionX; - var linePositionY; - - if(this.style.dropShadow) - { - this.context.fillStyle = this.style.dropShadowColor; - - var xShadowOffset = Math.sin(this.style.dropShadowAngle) * this.style.dropShadowDistance; - var yShadowOffset = Math.cos(this.style.dropShadowAngle) * this.style.dropShadowDistance; - - for (i = 0; i < lines.length; i++) - { - linePositionX = this.style.strokeThickness / 2; - linePositionY = (this.style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent; - - if(this.style.align === 'right') - { - linePositionX += maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - linePositionX += (maxLineWidth - lineWidths[i]) / 2; - } - - if(this.style.fill) - { - this.context.fillText(lines[i], linePositionX + xShadowOffset, linePositionY + yShadowOffset); - } - - // if(dropShadow) - } - } - - //set canvas text styles - this.context.fillStyle = this.style.fill; - - //draw lines line by line - for (i = 0; i < lines.length; i++) - { - linePositionX = this.style.strokeThickness / 2; - linePositionY = (this.style.strokeThickness / 2 + i * lineHeight) + fontProperties.ascent; - - if(this.style.align === 'right') - { - linePositionX += maxLineWidth - lineWidths[i]; - } - else if(this.style.align === 'center') - { - linePositionX += (maxLineWidth - lineWidths[i]) / 2; - } - - if(this.style.stroke && this.style.strokeThickness) - { - this.context.strokeText(lines[i], linePositionX, linePositionY); - } - - if(this.style.fill) - { - this.context.fillText(lines[i], linePositionX, linePositionY); - } - - // if(dropShadow) - } - - this.updateTexture(); -}; - -/** - * Updates texture size based on canvas size - * - * @method updateTexture - * @private - */ -PIXI.Text.prototype.updateTexture = function() -{ - this.texture.baseTexture.width = this.canvas.width; - this.texture.baseTexture.height = this.canvas.height; - this.texture.crop.width = this.texture.frame.width = this.canvas.width; - this.texture.crop.height = this.texture.frame.height = this.canvas.height; - - this._width = this.canvas.width; - this._height = this.canvas.height; - - // update the dirty base textures - this.texture.baseTexture.dirty(); -}; - -/** -* Renders the object using the WebGL renderer -* -* @method _renderWebGL -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Text.prototype._renderWebGL = function(renderSession) -{ - if(this.dirty) - { - this.resolution = renderSession.resolution; - - this.updateText(); - this.dirty = false; - } - - PIXI.Sprite.prototype._renderWebGL.call(this, renderSession); -}; - -/** -* Renders the object using the Canvas renderer -* -* @method _renderCanvas -* @param renderSession {RenderSession} -* @private -*/ -PIXI.Text.prototype._renderCanvas = function(renderSession) -{ - if(this.dirty) - { - this.resolution = renderSession.resolution; - - this.updateText(); - this.dirty = false; - } - - PIXI.Sprite.prototype._renderCanvas.call(this, renderSession); -}; - -/** -* Calculates the ascent, descent and fontSize of a given fontStyle -* -* @method determineFontProperties -* @param fontStyle {Object} -* @private -*/ -PIXI.Text.prototype.determineFontProperties = function(fontStyle) -{ - var properties = PIXI.Text.fontPropertiesCache[fontStyle]; - - if(!properties) - { - properties = {}; - - var canvas = PIXI.Text.fontPropertiesCanvas; - var context = PIXI.Text.fontPropertiesContext; - - context.font = fontStyle; - - var width = Math.ceil(context.measureText('|Mq').width); - var baseline = Math.ceil(context.measureText('M').width); - var height = 2 * baseline; - - baseline = baseline * 1.4 | 0; - - canvas.width = width; - canvas.height = height; - - context.fillStyle = '#f00'; - context.fillRect(0, 0, width, height); - - context.font = fontStyle; - - context.textBaseline = 'alphabetic'; - context.fillStyle = '#000'; - context.fillText('|MÉq', 0, baseline); - - var imagedata = context.getImageData(0, 0, width, height).data; - var pixels = imagedata.length; - var line = width * 4; - - var i, j; - - var idx = 0; - var stop = false; - - // ascent. scan from top to bottom until we find a non red pixel - for(i = 0; i < baseline; i++) - { - for(j = 0; j < line; j += 4) - { - if(imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - if(!stop) - { - idx += line; - } - else - { - break; - } - } - - properties.ascent = baseline - i; - - idx = pixels - line; - stop = false; - - // descent. scan from bottom to top until we find a non red pixel - for(i = height; i > baseline; i--) - { - for(j = 0; j < line; j += 4) - { - if(imagedata[idx + j] !== 255) - { - stop = true; - break; - } - } - if(!stop) - { - idx -= line; - } - else - { - break; - } - } - - properties.descent = i - baseline; - //TODO might need a tweak. kind of a temp fix! - properties.descent += 6; - properties.fontSize = properties.ascent + properties.descent; - - PIXI.Text.fontPropertiesCache[fontStyle] = properties; - } - - return properties; -}; - -/** - * Applies newlines to a string to have it optimally fit into the horizontal - * bounds set by the Text object's wordWrapWidth property. - * - * @method wordWrap - * @param text {String} - * @private - */ -PIXI.Text.prototype.wordWrap = function(text) -{ - // Greedy wrapping algorithm that will wrap words as the line grows longer - // than its horizontal bounds. - var result = ''; - var lines = text.split('\n'); - for (var i = 0; i < lines.length; i++) - { - var spaceLeft = this.style.wordWrapWidth; - var words = lines[i].split(' '); - for (var j = 0; j < words.length; j++) - { - var wordWidth = this.context.measureText(words[j]).width; - var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; - if(j === 0 || wordWidthWithSpace > spaceLeft) - { - // Skip printing the newline if it's the first word of the line that is - // greater than the word wrap width. - if(j > 0) - { - result += '\n'; - } - result += words[j]; - spaceLeft = this.style.wordWrapWidth - wordWidth; - } - else - { - spaceLeft -= wordWidthWithSpace; - result += ' ' + words[j]; - } - } - - if (i < lines.length-1) - { - result += '\n'; - } - } - return result; -}; - -/** -* Returns the bounds of the Text as a rectangle. The bounds calculation takes the worldTransform into account. -* -* @method getBounds -* @param matrix {Matrix} the transformation matrix of the Text -* @return {Rectangle} the framing rectangle -*/ -PIXI.Text.prototype.getBounds = function(matrix) -{ - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } - - return PIXI.Sprite.prototype.getBounds.call(this, matrix); -}; - -/** - * Destroys this text object. - * - * @method destroy - * @param destroyBaseTexture {Boolean} whether to destroy the base texture as well - */ -PIXI.Text.prototype.destroy = function(destroyBaseTexture) -{ - // make sure to reset the the context and canvas.. dont want this hanging around in memory! - this.context = null; - this.canvas = null; - - this.texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); -}; - -PIXI.Text.fontPropertiesCache = {}; -PIXI.Text.fontPropertiesCanvas = document.createElement('canvas'); -PIXI.Text.fontPropertiesContext = PIXI.Text.fontPropertiesCanvas.getContext('2d'); diff --git a/app/Lib/Vendor/src/pixi/textures/BaseTexture.js b/app/Lib/Vendor/src/pixi/textures/BaseTexture.js deleted file mode 100644 index 0145849..0000000 --- a/app/Lib/Vendor/src/pixi/textures/BaseTexture.js +++ /dev/null @@ -1,305 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -PIXI.BaseTextureCache = {}; - -PIXI.BaseTextureCacheIdGenerator = 0; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class BaseTexture - * @uses EventTarget - * @constructor - * @param source {String} the source object (image or canvas) - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - */ -PIXI.BaseTexture = function(source, scaleMode) -{ - /** - * The Resolution of the texture. - * - * @property resolution - * @type Number - */ - this.resolution = 1; - - /** - * [read-only] The width of the base texture set when the image has loaded - * - * @property width - * @type Number - * @readOnly - */ - this.width = 100; - - /** - * [read-only] The height of the base texture set when the image has loaded - * - * @property height - * @type Number - * @readOnly - */ - this.height = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @property scaleMode - * @type {Number} - * @default PIXI.scaleModes.LINEAR - */ - this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; - - /** - * [read-only] Set to true once the base texture has loaded - * - * @property hasLoaded - * @type Boolean - * @readOnly - */ - this.hasLoaded = false; - - /** - * The image source that is used to create the texture. - * - * @property source - * @type Image - */ - this.source = source; - - this._UID = PIXI._UID++; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * - * @property premultipliedAlpha - * @type Boolean - * @default true - */ - this.premultipliedAlpha = true; - - // used for webGL - - /** - * @property _glTextures - * @type Array - * @private - */ - this._glTextures = []; - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @property mipmap - * @type {Boolean} - */ - this.mipmap = false; - - // used for webGL texture updating... - // TODO - this needs to be addressed - - /** - * @property _dirty - * @type Array - * @private - */ - this._dirty = [true, true, true, true]; - - if(!source)return; - - if((this.source.complete || this.source.getContext) && this.source.width && this.source.height) - { - this.hasLoaded = true; - this.width = this.source.naturalWidth || this.source.width; - this.height = this.source.naturalHeight || this.source.height; - this.dirty(); - } - else - { - var scope = this; - - this.source.onload = function() { - - scope.hasLoaded = true; - scope.width = scope.source.naturalWidth || scope.source.width; - scope.height = scope.source.naturalHeight || scope.source.height; - - scope.dirty(); - - // add it to somewhere... - scope.dispatchEvent( { type: 'loaded', content: scope } ); - }; - - this.source.onerror = function() { - scope.dispatchEvent( { type: 'error', content: scope } ); - }; - } - - /** - * @property imageUrl - * @type String - */ - this.imageUrl = null; - - /** - * @property _powerOf2 - * @type Boolean - * @private - */ - this._powerOf2 = false; - -}; - -PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; - -PIXI.EventTarget.mixin(PIXI.BaseTexture.prototype); - -/** - * Destroys this base texture - * - * @method destroy - */ -PIXI.BaseTexture.prototype.destroy = function() -{ - if(this.imageUrl) - { - delete PIXI.BaseTextureCache[this.imageUrl]; - delete PIXI.TextureCache[this.imageUrl]; - this.imageUrl = null; - if (!navigator.isCocoonJS) this.source.src = ''; - } - else if (this.source && this.source._pixiId) - { - delete PIXI.BaseTextureCache[this.source._pixiId]; - } - this.source = null; - - this.unloadFromGPU(); -}; - -/** - * Changes the source image of the texture - * - * @method updateSourceImage - * @param newSrc {String} the path of the image - */ -PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) -{ - this.hasLoaded = false; - this.source.src = null; - this.source.src = newSrc; -}; - -/** - * Sets all glTextures to be dirty. - * - * @method dirty - */ -PIXI.BaseTexture.prototype.dirty = function() -{ - for (var i = 0; i < this._glTextures.length; i++) - { - this._dirty[i] = true; - } -}; - -/** - * Removes the base texture from the GPU, useful for managing resources on the GPU. - * Atexture is still 100% usable and will simply be reuploaded if there is a sprite on screen that is using it. - * - * @method unloadFromGPU - */ -PIXI.BaseTexture.prototype.unloadFromGPU = function() -{ - this.dirty(); - - // delete the webGL textures if any. - for (var i = this._glTextures.length - 1; i >= 0; i--) - { - var glTexture = this._glTextures[i]; - var gl = PIXI.glContexts[i]; - - if(gl && glTexture) - { - gl.deleteTexture(glTexture); - } - - } - - this._glTextures.length = 0; - - this.dirty(); -}; - -/** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @method fromImage - * @param imageUrl {String} The image url of the texture - * @param crossorigin {Boolean} - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return BaseTexture - */ -PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) -{ - var baseTexture = PIXI.BaseTextureCache[imageUrl]; - - if(crossorigin === undefined && imageUrl.indexOf('data:') === -1) crossorigin = true; - - if(!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - var image = new Image();//document.createElement('img'); - if (crossorigin) - { - image.crossOrigin = ''; - } - - image.src = imageUrl; - baseTexture = new PIXI.BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - PIXI.BaseTextureCache[imageUrl] = baseTexture; - - // if there is an @2x at the end of the url we are going to assume its a highres image - if( imageUrl.indexOf(PIXI.RETINA_PREFIX + '.') !== -1) - { - baseTexture.resolution = 2; - } - } - - return baseTexture; -}; - -/** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @method fromCanvas - * @param canvas {Canvas} The canvas element source of the texture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return BaseTexture - */ -PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode) -{ - if(!canvas._pixiId) - { - canvas._pixiId = 'canvas_' + PIXI.TextureCacheIdGenerator++; - } - - var baseTexture = PIXI.BaseTextureCache[canvas._pixiId]; - - if(!baseTexture) - { - baseTexture = new PIXI.BaseTexture(canvas, scaleMode); - PIXI.BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; -}; diff --git a/app/Lib/Vendor/src/pixi/textures/RenderTexture.js b/app/Lib/Vendor/src/pixi/textures/RenderTexture.js deleted file mode 100644 index 37dd7c8..0000000 --- a/app/Lib/Vendor/src/pixi/textures/RenderTexture.js +++ /dev/null @@ -1,336 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * A RenderTexture is a special texture that allows any Pixi display object to be rendered to it. - * - * __Hint__: All DisplayObjects (i.e. Sprites) that render to a RenderTexture should be preloaded otherwise black rectangles will be drawn instead. - * - * A RenderTexture takes a snapshot of any Display Object given to its render method. The position and rotation of the given Display Objects is ignored. For example: - * - * var renderTexture = new PIXI.RenderTexture(800, 600); - * var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); - * sprite.position.x = 800/2; - * sprite.position.y = 600/2; - * sprite.anchor.x = 0.5; - * sprite.anchor.y = 0.5; - * renderTexture.render(sprite); - * - * The Sprite in this case will be rendered to a position of 0,0. To render this sprite at its actual position a DisplayObjectContainer should be used: - * - * var doc = new PIXI.DisplayObjectContainer(); - * doc.addChild(sprite); - * renderTexture.render(doc); // Renders to center of renderTexture - * - * @class RenderTexture - * @extends Texture - * @constructor - * @param width {Number} The width of the render texture - * @param height {Number} The height of the render texture - * @param renderer {CanvasRenderer|WebGLRenderer} The renderer used for this RenderTexture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @param resolution {Number} The resolution of the texture being generated - */ -PIXI.RenderTexture = function(width, height, renderer, scaleMode, resolution) -{ - /** - * The with of the render texture - * - * @property width - * @type Number - */ - this.width = width || 100; - - /** - * The height of the render texture - * - * @property height - * @type Number - */ - this.height = height || 100; - - /** - * The Resolution of the texture. - * - * @property resolution - * @type Number - */ - this.resolution = resolution || 1; - - /** - * The framing rectangle of the render texture - * - * @property frame - * @type Rectangle - */ - this.frame = new PIXI.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); - - /** - * This is the area of the BaseTexture image to actually copy to the Canvas / WebGL when rendering, - * irrespective of the actual frame size or placement (which can be influenced by trimmed texture atlases) - * - * @property crop - * @type Rectangle - */ - this.crop = new PIXI.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); - - /** - * The base texture object that this texture uses - * - * @property baseTexture - * @type BaseTexture - */ - this.baseTexture = new PIXI.BaseTexture(); - this.baseTexture.width = this.width * this.resolution; - this.baseTexture.height = this.height * this.resolution; - this.baseTexture._glTextures = []; - this.baseTexture.resolution = this.resolution; - - this.baseTexture.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT; - - this.baseTexture.hasLoaded = true; - - PIXI.Texture.call(this, - this.baseTexture, - new PIXI.Rectangle(0, 0, this.width, this.height) - ); - - /** - * The renderer this RenderTexture uses. A RenderTexture can only belong to one renderer at the moment if its webGL. - * - * @property renderer - * @type CanvasRenderer|WebGLRenderer - */ - this.renderer = renderer || PIXI.defaultRenderer; - - if(this.renderer.type === PIXI.WEBGL_RENDERER) - { - var gl = this.renderer.gl; - this.baseTexture._dirty[gl.id] = false; - - this.textureBuffer = new PIXI.FilterTexture(gl, this.width * this.resolution, this.height * this.resolution, this.baseTexture.scaleMode); - this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture; - - this.render = this.renderWebGL; - this.projection = new PIXI.Point(this.width*0.5, -this.height*0.5); - } - else - { - this.render = this.renderCanvas; - this.textureBuffer = new PIXI.CanvasBuffer(this.width* this.resolution, this.height* this.resolution); - this.baseTexture.source = this.textureBuffer.canvas; - } - - /** - * @property valid - * @type Boolean - */ - this.valid = true; - - this._updateUvs(); -}; - -PIXI.RenderTexture.prototype = Object.create(PIXI.Texture.prototype); -PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; - -/** - * Resizes the RenderTexture. - * - * @method resize - * @param width {Number} The width to resize to. - * @param height {Number} The height to resize to. - * @param updateBase {Boolean} Should the baseTexture.width and height values be resized as well? - */ -PIXI.RenderTexture.prototype.resize = function(width, height, updateBase) -{ - if (width === this.width && height === this.height)return; - - this.valid = (width > 0 && height > 0); - - this.width = this.frame.width = this.crop.width = width; - this.height = this.frame.height = this.crop.height = height; - - if (updateBase) - { - this.baseTexture.width = this.width; - this.baseTexture.height = this.height; - } - - if (this.renderer.type === PIXI.WEBGL_RENDERER) - { - this.projection.x = this.width / 2; - this.projection.y = -this.height / 2; - } - - if(!this.valid)return; - - this.textureBuffer.resize(this.width * this.resolution, this.height * this.resolution); -}; - -/** - * Clears the RenderTexture. - * - * @method clear - */ -PIXI.RenderTexture.prototype.clear = function() -{ - if(!this.valid)return; - - if (this.renderer.type === PIXI.WEBGL_RENDERER) - { - this.renderer.gl.bindFramebuffer(this.renderer.gl.FRAMEBUFFER, this.textureBuffer.frameBuffer); - } - - this.textureBuffer.clear(); -}; - -/** - * This function will draw the display object to the texture. - * - * @method renderWebGL - * @param displayObject {DisplayObject} The display object to render this texture on - * @param [matrix] {Matrix} Optional matrix to apply to the display object before rendering. - * @param [clear] {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, matrix, clear) -{ - if(!this.valid)return; - //TOOD replace position with matrix.. - - //Lets create a nice matrix to apply to our display object. Frame buffers come in upside down so we need to flip the matrix - var wt = displayObject.worldTransform; - wt.identity(); - wt.translate(0, this.projection.y * 2); - if(matrix)wt.append(matrix); - wt.scale(1,-1); - - // setWorld Alpha to ensure that the object is renderer at full opacity - displayObject.worldAlpha = 1; - - // Time to update all the children of the displayObject with the new matrix.. - var children = displayObject.children; - - for(var i=0,j=children.length; i this.baseTexture.width || frame.y + frame.height > this.baseTexture.height)) - { - throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); - } - - this.valid = frame && frame.width && frame.height && this.baseTexture.source && this.baseTexture.hasLoaded; - - if (this.trim) - { - this.width = this.trim.width; - this.height = this.trim.height; - this.frame.width = this.trim.width; - this.frame.height = this.trim.height; - } - - if (this.valid) this._updateUvs(); - -}; - -/** - * Updates the internal WebGL UV cache. - * - * @method _updateUvs - * @private - */ -PIXI.Texture.prototype._updateUvs = function() -{ - if(!this._uvs)this._uvs = new PIXI.TextureUvs(); - - var frame = this.crop; - var tw = this.baseTexture.width; - var th = this.baseTexture.height; - - this._uvs.x0 = frame.x / tw; - this._uvs.y0 = frame.y / th; - - this._uvs.x1 = (frame.x + frame.width) / tw; - this._uvs.y1 = frame.y / th; - - this._uvs.x2 = (frame.x + frame.width) / tw; - this._uvs.y2 = (frame.y + frame.height) / th; - - this._uvs.x3 = frame.x / tw; - this._uvs.y3 = (frame.y + frame.height) / th; -}; - -/** - * Helper function that creates a Texture object from the given image url. - * If the image is not in the texture cache it will be created and loaded. - * - * @static - * @method fromImage - * @param imageUrl {String} The image url of the texture - * @param crossorigin {Boolean} Whether requests should be treated as crossorigin - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return Texture - */ -PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) -{ - var texture = PIXI.TextureCache[imageUrl]; - - if(!texture) - { - texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin, scaleMode)); - PIXI.TextureCache[imageUrl] = texture; - } - - return texture; -}; - -/** - * Helper function that returns a Texture objected based on the given frame id. - * If the frame id is not in the texture cache an error will be thrown. - * - * @static - * @method fromFrame - * @param frameId {String} The frame id of the texture - * @return Texture - */ -PIXI.Texture.fromFrame = function(frameId) -{ - var texture = PIXI.TextureCache[frameId]; - if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache '); - return texture; -}; - -/** - * Helper function that creates a new a Texture based on the given canvas element. - * - * @static - * @method fromCanvas - * @param canvas {Canvas} The canvas element source of the texture - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return Texture - */ -PIXI.Texture.fromCanvas = function(canvas, scaleMode) -{ - var baseTexture = PIXI.BaseTexture.fromCanvas(canvas, scaleMode); - - return new PIXI.Texture( baseTexture ); - -}; - -/** - * Adds a texture to the global PIXI.TextureCache. This cache is shared across the whole PIXI object. - * - * @static - * @method addTextureToCache - * @param texture {Texture} The Texture to add to the cache. - * @param id {String} The id that the texture will be stored against. - */ -PIXI.Texture.addTextureToCache = function(texture, id) -{ - PIXI.TextureCache[id] = texture; -}; - -/** - * Remove a texture from the global PIXI.TextureCache. - * - * @static - * @method removeTextureFromCache - * @param id {String} The id of the texture to be removed - * @return {Texture} The texture that was removed - */ -PIXI.Texture.removeTextureFromCache = function(id) -{ - var texture = PIXI.TextureCache[id]; - delete PIXI.TextureCache[id]; - delete PIXI.BaseTextureCache[id]; - return texture; -}; - -PIXI.TextureUvs = function() -{ - this.x0 = 0; - this.y0 = 0; - - this.x1 = 0; - this.y1 = 0; - - this.x2 = 0; - this.y2 = 0; - - this.x3 = 0; - this.y3 = 0; -}; - -PIXI.Texture.emptyTexture = new PIXI.Texture(new PIXI.BaseTexture()); - diff --git a/app/Lib/Vendor/src/pixi/textures/VideoTexture.js b/app/Lib/Vendor/src/pixi/textures/VideoTexture.js deleted file mode 100644 index ad58ec5..0000000 --- a/app/Lib/Vendor/src/pixi/textures/VideoTexture.js +++ /dev/null @@ -1,168 +0,0 @@ -/** - * A texture of a [playing] Video. - * - * See the ["deus" demo](http://www.goodboydigital.com/pixijs/examples/deus/). - * - * @class VideoTexture - * @extends BaseTexture - * @constructor - * @param source {HTMLVideoElement} - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - */ -PIXI.VideoTexture = function( source, scaleMode ) -{ - if( !source ){ - throw new Error( 'No video source element specified.' ); - } - - // hook in here to check if video is already available. - // PIXI.BaseTexture looks for a source.complete boolean, plus width & height. - - if( (source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA ) && source.width && source.height ) - { - source.complete = true; - } - - PIXI.BaseTexture.call( this, source, scaleMode ); - - this.autoUpdate = false; - this.updateBound = this._onUpdate.bind(this); - - if( !source.complete ) - { - this._onCanPlay = this.onCanPlay.bind(this); - - source.addEventListener( 'canplay', this._onCanPlay ); - source.addEventListener( 'canplaythrough', this._onCanPlay ); - - // started playing.. - source.addEventListener( 'play', this.onPlayStart.bind(this) ); - source.addEventListener( 'pause', this.onPlayStop.bind(this) ); - } - -}; - -PIXI.VideoTexture.prototype = Object.create( PIXI.BaseTexture.prototype ); - -PIXI.VideoTexture.constructor = PIXI.VideoTexture; - -PIXI.VideoTexture.prototype._onUpdate = function() -{ - if(this.autoUpdate) - { - window.requestAnimationFrame(this.updateBound); - this.dirty(); - } -}; - -PIXI.VideoTexture.prototype.onPlayStart = function() -{ - if(!this.autoUpdate) - { - window.requestAnimationFrame(this.updateBound); - this.autoUpdate = true; - } -}; - -PIXI.VideoTexture.prototype.onPlayStop = function() -{ - this.autoUpdate = false; -}; - -PIXI.VideoTexture.prototype.onCanPlay = function() -{ - if( event.type === 'canplaythrough' ) - { - this.hasLoaded = true; - - - if( this.source ) - { - this.source.removeEventListener( 'canplay', this._onCanPlay ); - this.source.removeEventListener( 'canplaythrough', this._onCanPlay ); - - this.width = this.source.videoWidth; - this.height = this.source.videoHeight; - - // prevent multiple loaded dispatches.. - if( !this.__loaded ){ - this.__loaded = true; - this.dispatchEvent( { type: 'loaded', content: this } ); - } - } - } -}; - -PIXI.VideoTexture.prototype.destroy = function() -{ - if( this.source && this.source._pixiId ) - { - PIXI.BaseTextureCache[ this.source._pixiId ] = null; - delete PIXI.BaseTextureCache[ this.source._pixiId ]; - - this.source._pixiId = null; - delete this.source._pixiId; - } - - PIXI.BaseTexture.prototype.destroy.call( this ); -}; - -/** - * Mimic Pixi BaseTexture.from.... method. - * - * @static - * @method baseTextureFromVideo - * @param video {HTMLVideoElement} - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return {VideoTexture} - */ -PIXI.VideoTexture.baseTextureFromVideo = function( video, scaleMode ) -{ - if( !video._pixiId ) - { - video._pixiId = 'video_' + PIXI.TextureCacheIdGenerator++; - } - - var baseTexture = PIXI.BaseTextureCache[ video._pixiId ]; - - if( !baseTexture ) - { - baseTexture = new PIXI.VideoTexture( video, scaleMode ); - PIXI.BaseTextureCache[ video._pixiId ] = baseTexture; - } - - return baseTexture; -}; - -/** - * Mimic Pixi BaseTexture.from.... method. - * - * @static - * @method textureFromVideo - * @param video {HTMLVideoElement} - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return {Texture} A Texture, but not a VideoTexture. - */ -PIXI.VideoTexture.textureFromVideo = function( video, scaleMode ) -{ - var baseTexture = PIXI.VideoTexture.baseTextureFromVideo( video, scaleMode ); - return new PIXI.Texture( baseTexture ); -}; - -/** - * Mimic Pixi BaseTexture.from.... method. - * - * @static - * @method fromUrl - * @param videoSrc {String} The URL for the video. - * @param scaleMode {Number} See {{#crossLink "PIXI/scaleModes:property"}}PIXI.scaleModes{{/crossLink}} for possible values - * @return {VideoTexture} - */ -PIXI.VideoTexture.fromUrl = function( videoSrc, scaleMode ) -{ - var video = document.createElement('video'); - video.src = videoSrc; - video.autoPlay = true; - video.play(); - return PIXI.VideoTexture.textureFromVideo( video, scaleMode); -}; diff --git a/app/Lib/Vendor/src/pixi/utils/Detector.js b/app/Lib/Vendor/src/pixi/utils/Detector.js deleted file mode 100644 index fe38f04..0000000 --- a/app/Lib/Vendor/src/pixi/utils/Detector.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -/** - * This helper function will automatically detect which renderer you should be using. - * WebGL is the preferred renderer as it is a lot faster. If webGL is not supported by - * the browser then this function will return a canvas renderer - * - * @method autoDetectRenderer - * @for PIXI - * @static - * @param width=800 {Number} the width of the renderers view - * @param height=600 {Number} the height of the renderers view - * - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * - */ -PIXI.autoDetectRenderer = function(width, height, options) -{ - if(!width)width = 800; - if(!height)height = 600; - - // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { - var canvas = document.createElement( 'canvas' ); - return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); - } catch( e ) { - return false; - } - } )(); - - if( webgl ) - { - return new PIXI.WebGLRenderer(width, height, options); - } - - return new PIXI.CanvasRenderer(width, height, options); -}; - -/** - * This helper function will automatically detect which renderer you should be using. - * This function is very similar to the autoDetectRenderer function except that is will return a canvas renderer for android. - * Even thought both android chrome supports webGL the canvas implementation perform better at the time of writing. - * This function will likely change and update as webGL performance improves on these devices. - * - * @method autoDetectRecommendedRenderer - * @for PIXI - * @static - * @param width=800 {Number} the width of the renderers view - * @param height=600 {Number} the height of the renderers view - * - * @param [options] {Object} The optional renderer parameters - * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional - * @param [options.transparent=false] {Boolean} If the render view is transparent, default false - * @param [options.antialias=false] {Boolean} sets antialias (only applicable in chrome at the moment) - * @param [options.preserveDrawingBuffer=false] {Boolean} enables drawing buffer preservation, enable this if you need to call toDataUrl on the webgl context - * @param [options.resolution=1] {Number} the resolution of the renderer retina would be 2 - * - */ -PIXI.autoDetectRecommendedRenderer = function(width, height, options) -{ - if(!width)width = 800; - if(!height)height = 600; - - // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { - var canvas = document.createElement( 'canvas' ); - return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); - } catch( e ) { - return false; - } - } )(); - - var isAndroid = /Android/i.test(navigator.userAgent); - - if( webgl && !isAndroid) - { - return new PIXI.WebGLRenderer(width, height, options); - } - - return new PIXI.CanvasRenderer(width, height, options); -}; diff --git a/app/Lib/Vendor/src/pixi/utils/EventTarget.js b/app/Lib/Vendor/src/pixi/utils/EventTarget.js deleted file mode 100644 index 35aa31b..0000000 --- a/app/Lib/Vendor/src/pixi/utils/EventTarget.js +++ /dev/null @@ -1,284 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - * @author Chad Engler https://github.com/englercj @Rolnaaba - */ - -/** - * Originally based on https://github.com/mrdoob/eventtarget.js/ from mr Doob. - * Currently takes inspiration from the nodejs EventEmitter, EventEmitter3, and smokesignals - */ - -/** - * Mixins event emitter functionality to a class - * - * @class EventTarget - * @example - * function MyEmitter() {} - * - * PIXI.EventTarget.mixin(MyEmitter.prototype); - * - * var em = new MyEmitter(); - * em.emit('eventName', 'some data', 'some more data', {}, null, ...); - */ -PIXI.EventTarget = { - /** - * Backward compat from when this used to be a function - */ - call: function callCompat(obj) { - if(obj) { - obj = obj.prototype || obj; - PIXI.EventTarget.mixin(obj); - } - }, - - /** - * Mixes in the properties of the EventTarget prototype onto another object - * - * @method mixin - * @param object {Object} The obj to mix into - */ - mixin: function mixin(obj) { - /** - * Return a list of assigned event listeners. - * - * @method listeners - * @param eventName {String} The events that should be listed. - * @return {Array} An array of listener functions - */ - obj.listeners = function listeners(eventName) { - this._listeners = this._listeners || {}; - - return this._listeners[eventName] ? this._listeners[eventName].slice() : []; - }; - - /** - * Emit an event to all registered event listeners. - * - * @method emit - * @alias dispatchEvent - * @param eventName {String} The name of the event. - * @return {Boolean} Indication if we've emitted an event. - */ - obj.emit = obj.dispatchEvent = function emit(eventName, data) { - this._listeners = this._listeners || {}; - - //backwards compat with old method ".emit({ type: 'something' })" - if(typeof eventName === 'object') { - data = eventName; - eventName = eventName.type; - } - - //ensure we are using a real pixi event - if(!data || data.__isEventObject !== true) { - data = new PIXI.Event(this, eventName, data); - } - - //iterate the listeners - if(this._listeners && this._listeners[eventName]) { - var listeners = this._listeners[eventName].slice(0), - length = listeners.length, - fn = listeners[0], - i; - - for(i = 0; i < length; fn = listeners[++i]) { - //call the event listener - fn.call(this, data); - - //if "stopImmediatePropagation" is called, stop calling sibling events - if(data.stoppedImmediate) { - return this; - } - } - - //if "stopPropagation" is called then don't bubble the event - if(data.stopped) { - return this; - } - } - - //bubble this event up the scene graph - if(this.parent && this.parent.emit) { - this.parent.emit.call(this.parent, eventName, data); - } - - return this; - }; - - /** - * Register a new EventListener for the given event. - * - * @method on - * @alias addEventListener - * @param eventName {String} Name of the event. - * @param callback {Functon} fn Callback function. - */ - obj.on = obj.addEventListener = function on(eventName, fn) { - this._listeners = this._listeners || {}; - - (this._listeners[eventName] = this._listeners[eventName] || []) - .push(fn); - - return this; - }; - - /** - * Add an EventListener that's only called once. - * - * @method once - * @param eventName {String} Name of the event. - * @param callback {Function} Callback function. - */ - obj.once = function once(eventName, fn) { - this._listeners = this._listeners || {}; - - var self = this; - function onceHandlerWrapper() { - fn.apply(self.off(eventName, onceHandlerWrapper), arguments); - } - onceHandlerWrapper._originalHandler = fn; - - return this.on(eventName, onceHandlerWrapper); - }; - - /** - * Remove event listeners. - * - * @method off - * @alias removeEventListener - * @param eventName {String} The event we want to remove. - * @param callback {Function} The listener that we need to find. - */ - obj.off = obj.removeEventListener = function off(eventName, fn) { - this._listeners = this._listeners || {}; - - if(!this._listeners[eventName]) - return this; - - var list = this._listeners[eventName], - i = fn ? list.length : 0; - - while(i-- > 0) { - if(list[i] === fn || list[i]._originalHandler === fn) { - list.splice(i, 1); - } - } - - if(list.length === 0) { - delete this._listeners[eventName]; - } - - return this; - }; - - /** - * Remove all listeners or only the listeners for the specified event. - * - * @method removeAllListeners - * @param eventName {String} The event you want to remove all listeners for. - */ - obj.removeAllListeners = function removeAllListeners(eventName) { - this._listeners = this._listeners || {}; - - if(!this._listeners[eventName]) - return this; - - delete this._listeners[eventName]; - - return this; - }; - } -}; - -/** - * Creates an homogenous object for tracking events so users can know what to expect. - * - * @class Event - * @extends Object - * @constructor - * @param target {Object} The target object that the event is called on - * @param name {String} The string name of the event that was triggered - * @param data {Object} Arbitrary event data to pass along - */ -PIXI.Event = function(target, name, data) { - //for duck typing in the ".on()" function - this.__isEventObject = true; - - /** - * Tracks the state of bubbling propagation. Do not - * set this directly, instead use `event.stopPropagation()` - * - * @property stopped - * @type Boolean - * @private - * @readOnly - */ - this.stopped = false; - - /** - * Tracks the state of sibling listener propagation. Do not - * set this directly, instead use `event.stopImmediatePropagation()` - * - * @property stoppedImmediate - * @type Boolean - * @private - * @readOnly - */ - this.stoppedImmediate = false; - - /** - * The original target the event triggered on. - * - * @property target - * @type Object - * @readOnly - */ - this.target = target; - - /** - * The string name of the event that this represents. - * - * @property type - * @type String - * @readOnly - */ - this.type = name; - - /** - * The data that was passed in with this event. - * - * @property data - * @type Object - * @readOnly - */ - this.data = data; - - //backwards compat with older version of events - this.content = data; - - /** - * The timestamp when the event occurred. - * - * @property timeStamp - * @type Number - * @readOnly - */ - this.timeStamp = Date.now(); -}; - -/** - * Stops the propagation of events up the scene graph (prevents bubbling). - * - * @method stopPropagation - */ -PIXI.Event.prototype.stopPropagation = function stopPropagation() { - this.stopped = true; -}; - -/** - * Stops the propagation of events to sibling listeners (no longer calls any listeners). - * - * @method stopImmediatePropagation - */ -PIXI.Event.prototype.stopImmediatePropagation = function stopImmediatePropagation() { - this.stoppedImmediate = true; -}; diff --git a/app/Lib/Vendor/src/pixi/utils/Polyk.js b/app/Lib/Vendor/src/pixi/utils/Polyk.js deleted file mode 100644 index 838e6a2..0000000 --- a/app/Lib/Vendor/src/pixi/utils/Polyk.js +++ /dev/null @@ -1,168 +0,0 @@ -/* - PolyK library - url: http://polyk.ivank.net - Released under MIT licence. - - Copyright (c) 2012 Ivan Kuckir - - 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. - - This is an amazing lib! - - Slightly modified by Mat Groves (matgroves.com); -*/ - -/** - * Based on the Polyk library http://polyk.ivank.net released under MIT licence. - * This is an amazing lib! - * Slightly modified by Mat Groves (matgroves.com); - * @class PolyK - */ -PIXI.PolyK = {}; - -/** - * Triangulates shapes for webGL graphic fills. - * - * @method Triangulate - */ -PIXI.PolyK.Triangulate = function(p) -{ - var sign = true; - - var n = p.length >> 1; - if(n < 3) return []; - - var tgs = []; - var avl = []; - for(var i = 0; i < n; i++) avl.push(i); - - i = 0; - var al = n; - while(al > 3) - { - var i0 = avl[(i+0)%al]; - var i1 = avl[(i+1)%al]; - var i2 = avl[(i+2)%al]; - - var ax = p[2*i0], ay = p[2*i0+1]; - var bx = p[2*i1], by = p[2*i1+1]; - var cx = p[2*i2], cy = p[2*i2+1]; - - var earFound = false; - if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign)) - { - earFound = true; - for(var j = 0; j < al; j++) - { - var vi = avl[j]; - if(vi === i0 || vi === i1 || vi === i2) continue; - - if(PIXI.PolyK._PointInTriangle(p[2*vi], p[2*vi+1], ax, ay, bx, by, cx, cy)) { - earFound = false; - break; - } - } - } - - if(earFound) - { - tgs.push(i0, i1, i2); - avl.splice((i+1)%al, 1); - al--; - i = 0; - } - else if(i++ > 3*al) - { - // need to flip flip reverse it! - // reset! - if(sign) - { - tgs = []; - avl = []; - for(i = 0; i < n; i++) avl.push(i); - - i = 0; - al = n; - - sign = false; - } - else - { - // window.console.log("PIXI Warning: shape too complex to fill"); - return null; - } - } - } - - tgs.push(avl[0], avl[1], avl[2]); - return tgs; -}; - -/** - * Checks whether a point is within a triangle - * - * @method _PointInTriangle - * @param px {Number} x coordinate of the point to test - * @param py {Number} y coordinate of the point to test - * @param ax {Number} x coordinate of the a point of the triangle - * @param ay {Number} y coordinate of the a point of the triangle - * @param bx {Number} x coordinate of the b point of the triangle - * @param by {Number} y coordinate of the b point of the triangle - * @param cx {Number} x coordinate of the c point of the triangle - * @param cy {Number} y coordinate of the c point of the triangle - * @private - * @return {Boolean} - */ -PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) -{ - var v0x = cx-ax; - var v0y = cy-ay; - var v1x = bx-ax; - var v1y = by-ay; - var v2x = px-ax; - var v2y = py-ay; - - var dot00 = v0x*v0x+v0y*v0y; - var dot01 = v0x*v1x+v0y*v1y; - var dot02 = v0x*v2x+v0y*v2y; - var dot11 = v1x*v1x+v1y*v1y; - var dot12 = v1x*v2x+v1y*v2y; - - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v < 1); -}; - -/** - * Checks whether a shape is convex - * - * @method _convex - * @private - * @return {Boolean} - */ -PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign) -{ - return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign; -}; diff --git a/app/Lib/Vendor/src/pixi/utils/Utils.js b/app/Lib/Vendor/src/pixi/utils/Utils.js deleted file mode 100644 index 3cfcff8..0000000 --- a/app/Lib/Vendor/src/pixi/utils/Utils.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @author Mat Groves http://matgroves.com/ @Doormat23 - */ - -// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ -// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating - -// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel - -// MIT license - -/** - * A polyfill for requestAnimationFrame - * You can actually use both requestAnimationFrame and requestAnimFrame, - * you will still benefit from the polyfill - * - * @method requestAnimationFrame - */ - -/** - * A polyfill for cancelAnimationFrame - * - * @method cancelAnimationFrame - */ -(function(window) { - var lastTime = 0; - var vendors = ['ms', 'moz', 'webkit', 'o']; - for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || - window[vendors[x] + 'CancelRequestAnimationFrame']; - } - - if (!window.requestAnimationFrame) { - window.requestAnimationFrame = function(callback) { - var currTime = new Date().getTime(); - var timeToCall = Math.max(0, 16 - (currTime - lastTime)); - var id = window.setTimeout(function() { callback(currTime + timeToCall); }, - timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - - if (!window.cancelAnimationFrame) { - window.cancelAnimationFrame = function(id) { - clearTimeout(id); - }; - } - - window.requestAnimFrame = window.requestAnimationFrame; -})(this); - -/** - * Converts a hex color number to an [R, G, B] array - * - * @method hex2rgb - * @param hex {Number} - */ -PIXI.hex2rgb = function(hex) { - return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; -}; - -/** - * Converts a color as an [R, G, B] array to a hex number - * - * @method rgb2hex - * @param rgb {Array} - */ -PIXI.rgb2hex = function(rgb) { - return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255); -}; - -/** - * A polyfill for Function.prototype.bind - * - * @method bind - */ -if (typeof Function.prototype.bind !== 'function') { - Function.prototype.bind = (function () { - return function (thisArg) { - var target = this, i = arguments.length - 1, boundArgs = []; - if (i > 0) - { - boundArgs.length = i; - while (i--) boundArgs[i] = arguments[i + 1]; - } - - if (typeof target !== 'function') throw new TypeError(); - - function bound() { - var i = arguments.length, args = new Array(i); - while (i--) args[i] = arguments[i]; - args = boundArgs.concat(args); - return target.apply(this instanceof bound ? this : thisArg, args); - } - - bound.prototype = (function F(proto) { - if (proto) F.prototype = proto; - if (!(this instanceof F)) return new F(); - })(target.prototype); - - return bound; - }; - })(); -} - -/** - * A wrapper for ajax requests to be handled cross browser - * - * @class AjaxRequest - * @constructor - */ -PIXI.AjaxRequest = function() -{ - var activexmodes = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; //activeX versions to check for in IE - - if (window.ActiveXObject) - { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) - for (var i=0; i 0 && (number & (number - 1)) === 0) // see: http://goo.gl/D9kPj - return number; - else - { - var result = 1; - while (result < number) result <<= 1; - return result; - } -}; - -PIXI.isPowerOfTwo = function(width, height) -{ - return (width > 0 && (width & (width - 1)) === 0 && height > 0 && (height & (height - 1)) === 0); - -}; diff --git a/app/Menu/Menu.js b/app/Menu/Menu.js deleted file mode 100644 index 62ae3cc..0000000 --- a/app/Menu/Menu.js +++ /dev/null @@ -1,435 +0,0 @@ -define([ - "Game/Config/Settings", - "Lib/Utilities/ColorConverter", - "Lib/Utilities/Exception", - "Game/Client/PointerLockManager", - "Lib/Utilities/QuerySelector" -], - -function (Settings, ColorConverter, Exception, pointerLockManager, qs) { - - "use strict"; - - var instance = null - var quickstartChannelName = "Quickstart"; - - function Menu() { - - } - - Menu.prototype.init = function() { - instance = this; // Dum und Dümmer - - if(localStorage["player"]) { - var player = JSON.parse(localStorage["player"]); - if(player.nickname) { - qs.$("#nick").value = player.nickname; - } - } - - if(localStorage["customname"]) { - qs.$("#customname").value = localStorage["customname"]; - } - qs.$("#scoreLimit").value = Settings.CHANNEL_DEFAULT_SCORE_LIMIT; - qs.$("#userLimit").value = Settings.CHANNEL_DEFAULT_MAX_USERS; - - - qs.$("#refresh").onclick = refresh; - refresh(); - populateMaps(); - this.channelDestructionTimeout = null; - this.refreshInterval = setInterval(refresh, 5000); - - qs.$("#createbutton").onclick = function() { - show('#createform'); - return false; - }; - qs.$("#quickstartbutton").onclick = quickstart; - - var cancelButtons = qs.$$(".cancel"); - for (var i = 0; i < cancelButtons.length; i++) { - cancelButtons[i].onclick = function() { - show('#listform'); - return false; - }; - }; - - this.colorConverter = new ColorConverter(); - var c = qs.$("#nick"); - c.onchange = c.onkeyup = c.onblur = c.onclick = this.updatePrimaryColor.bind(this); - this.updatePrimaryColor({target:c}); - }; - - Menu.prototype.updatePrimaryColor = function(e) { - qs.$("#primarycolor").style.backgroundColor = "#" + this.colorConverter.getColorByName(e.target.value).toString(16); - }; - - Menu.prototype.onRun = function(channelName, nickname) { - throw new Exception("Menu onRun has to be overwritten"); - } - - window.onhashchange = function() { - if(window.location.hash) { - if(qs.$("#game").style.display == "block") { - window.location.reload(); - } - refresh(function(list) { - var channelName = unescape(window.location.hash.substr(1)); - - if (channelName == quickstartChannelName) { - quickstart(); - return; - } - - if(channelExists(list, channelName)) { - showCustomJoinForm() - } else { - alert("Channel \"" + channelName + "\" does not exist (anymore).") - window.location.href = "/"; - } - }); - } - } - - window.onload = window.onhashchange; - - var lastRefreshResponse; - function refresh(callback) { - - ajax("getChannels", {}, function(response) { - if(response != lastRefreshResponse) { - lastRefreshResponse = response; - populate(JSON.parse(response).success); - } - document.body.className = ""; - - if(typeof callback == 'function') { - callback(JSON.parse(response).success) - } - - }, function(status, responseText) { - console.error("getChannels error: ", responseText) - }); - - return false; - } - - function ajax(command, options, callback, errorCallback) { - try { - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function() { - if(xhr.readyState == 4) { - if(xhr.status == 200) { - if(typeof callback == 'function') { - callback(xhr.responseText) - } - } else { - if(typeof errorCallback == 'function' && xhr.status == "400") { - errorCallback(xhr.status, xhr.responseText); - } else { - console.error("Ajax error: " + xhr.status + " " + xhr.responseText) - qs.$("#list").innerHTML = ""; - document.body.className = "offline"; - } - } - } - } - xhr.open("POST", "/api", true); - xhr.send(JSON.stringify({command:command, options:options})); - } catch(e) { - console.error(e) - } - } - - function populate(list) { - - - var html = ""; - if(list.length > 0) { - for (var i = 0; i < list.length; i++) { - - var channel = list[i]; - var fullState = channel.playerCount >= channel.maxUsers; - var fullString = fullState ? " Full" : ""; - var fullStyle = fullState ? 'class="full"' : ""; - var players = channel.playerCount - ? "Player:
- " + channel.players.join("
- ") + "
" - : ""; - - html += ""; - html += "" + channel.channelName + ""; - html += "death match"; - html += "" + channel.playerCount + fullString + players + ""; - html += ""; - }; - } else { - html += "No channels found."; - } - - qs.$("#list").innerHTML = html; - } - - function populateMaps() { - ajax("getMaps", {}, function(responseText) { - var maps = JSON.parse(responseText).success; - var html = ""; - for (var i = 0; i < maps.length; i++) { - var map = maps[i]; - html += "
  • "; - }; - - qs.$("#maps").innerHTML = html; - }, function(status, responseText) { - console.error("getMaps error:", status, responseText); - }); - } - - qs.$("form#listform").onsubmit = function(e) { - try { - var nickname = qs.$("#nick").value; - var channelName = getSelectedChannel(); - join(nickname, channelName); - } catch(e) { - console.error(e) - } - - return false; - } - - qs.$("form#createform").onsubmit = function(e) { - try { - - var options = { - channelName: qs.$("#customname").value, - levelUids: getSelectedMaps(), - maxUsers: parseInt(qs.$("#userLimit").value, 10), - scoreLimit: parseInt(qs.$("#scoreLimit").value, 10) - }; - - create(options, onCreateSuccess); - } catch(e) { - console.error(e) - } - - return false; - } - - qs.$("form#customjoinform").onsubmit = function(e) { - try { - var nickname = qs.$("#nick").value; - var channelName = qs.$("#customname").value; - join(nickname, channelName); - } catch(e) { - console.error(e); - } - - return false; - } - - function onCreateSuccess(options) { - window.location.hash = options.channelName; - startTimer(options.timeout); - } - - function showCustomJoinForm() { - qs.$("#customname").value = unescape(window.location.hash.substr(1)); - qs.$("#link").value = window.location.href; - show("#customjoinform"); - } - - function show(id) { - qs.$("#createform").style.display = "none"; - qs.$("#listform").style.display = "none"; - qs.$("#customjoinform").style.display = "none"; - qs.$("#game").style.display = "none"; - - if(id != "#customjoinform") { - history.pushState("", document.title, window.location.pathname); - } - - qs.$(id).style.display = "block"; - } - - function quickstart() { - refresh(function(list){ - var defaultChannelName = quickstartChannelName; - history.pushState("", document.title, window.location.pathname + "#" + defaultChannelName); - var nickname = qs.$("#nick").value; - - if(!nickname) { - nickname = "Guest" + (Math.floor(Math.random() * 899) + 100) - } - - if(!channelExists(list, defaultChannelName)) { - - var options = { - channelName: defaultChannelName, - levelUids: getSelectedMaps(), - maxUsers: parseInt(qs.$("#userLimit").value, 10), - scoreLimit: parseInt(qs.$("#scoreLimit").value, 10) - }; - - create(options, function() { - join(nickname, defaultChannelName); // only called on success - }); - } else { - join(nickname, defaultChannelName); - } - }); - return false; - } - - function startTimer(seconds) { - var now = new Date(); - var end = new Date(now.getTime() + seconds * 1000); - instance.channelDestructionTimeout = setInterval(function() { - now = new Date(); - var diff = new Date(end.getTime() - now.getTime()); - if(diff.getTime() < 0) { - alert("Your channel has timed out."); - window.location.href = "/"; - } else { - qs.$("#timeout").innerHTML = " within " + formatDate(diff) + " minutes"; - } - }, 1000); - } - - function formatDate(date) { - var minutes = date.getMinutes(); - var seconds = date.getSeconds(); - if(minutes < 10) minutes = "0" + minutes; - if(seconds < 10) seconds = "0" + seconds; - - return minutes + ":" + seconds; - } - - function channelExists(list, channelName) { - for (var i = 0; i < list.length; i++) { - var channel = list[i]; - if(channel.channelName == channelName) { - return true; - } - } - return false; - } - - function validateForJoin(nickname, channelName) { - if(!nickname || nickname.length < 3) { - alert("Nickname too short") - return false; - } - if(!channelName) { - alert('No channel name provided'); - return false; - } - return true; - } - - function validateForCreate(options) { - - return true; - // great validation on server side does it all. - - /* - if(options.levelUids.length < 1) { - alert("Please choose at least one map.") - return false; - } - - if(!options.channelName || options.channelName.length < 3) { - alert("Please provide a channel name of at least 3 characters.") - return false; - } - - if(!parseInt(options.maxUsers) > 1 || !parseInt(options.maxUsers) < 20) { - alert("Number of users must be larger than 1 and smaller than 20."); - return false; - } - - if(!parseInt(options.scoreLimit) > 1 || !parseInt(options.scoreLimit) < 99) { - alert("Score limit must be larger than 1 and smaller than 99."); - return false; - } - return true; - */ - } - - function getSelectedMaps() { - var maps = []; - var checkboxes = document.querySelectorAll("form#createform input[name=maps]"); - for (var i = 0; i < checkboxes.length; i++) { - var checkbox = checkboxes[i]; - if(checkbox.checked) { - maps.push(checkbox.value); - } - }; - return maps; - } - - function getSelectedChannel() { - var name = null; - var radios = document.querySelectorAll("form#listform input[name=channel]"); - for (var i = 0; i < radios.length; i++) { - var radio = radios[i]; - if(radio.checked) { - name = radio.value; - break; - } - }; - return name - } - - function join(nickname, channelName) { - if(validateForJoin(nickname, channelName)) { - localStorage["player"] = JSON.stringify({ - nickname: nickname - }); - localStorage["channel"] = JSON.stringify({ - name: channelName - }); - - //window.location.href = "/game.html"; - qs.$("#menu").style.display = "none"; - qs.$("#game").style.display = "block"; - instance.onRun(channelName, nickname); // Dumm und dümmer - - if(instance.refreshInterval) { - clearInterval(instance.refreshInterval); - } - - if(instance.channelDestructionTimeout) { - clearInterval(instance.channelDestructionTimeout); - } - - pointerLockManager.request(); - } - } - - function create(options, callback) { - - if(validateForCreate(options)) { - - options["minUsers"] = 1; - localStorage["customname"] = options.channelName; - - ajax("createChannel", options, function(responseText) { - if(typeof callback == 'function') { - callback(JSON.parse(responseText).success); - } - }, function(status, responseText) { - console.log(responseText) - alert(JSON.parse(responseText).error) - }); - } - } - - qs.$("#canvas").onclick = function(){ - pointerLockManager.request(); - }; - - return Menu; - -}); \ No newline at end of file diff --git a/app/Server/Api.js b/app/Server/Api.js index f237c26..23bb3cf 100644 --- a/app/Server/Api.js +++ b/app/Server/Api.js @@ -2,15 +2,12 @@ define([ "Lib/Utilities/NotificationCenter", "Lib/Utilities/Protocol/Helper", "Lib/Utilities/Validate", - "Lib/Utilities/OptionsHelper", - "Game/Config/Settings", - "fs" + "Lib/Utilities/Options", + "Game/Config/Settings" ], -function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { - - "use strict"; - +function (Nc, ProtocolHelper, validate, Options, Settings) { + function Api(coordinator) { this.coordinator = coordinator; this.isError = false; @@ -34,15 +31,12 @@ function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { switch(command) { case "getChannels": - output = this.getChannels(); + output = this.coordinator.getChannels(); break; case "createChannel": // FIXME: sanitize input output = this.createChannel(message.options); break; - case "getMaps": - output = this.getMaps(); - break; default: this.isError = true; output = "Command not found"; @@ -52,10 +46,6 @@ function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { this.output = output; } - Api.prototype.getChannels = function() { - return this.coordinator.getChannels(); - }; - Api.prototype.createChannel = function(options) { var allowedOptionKeys = [ @@ -83,7 +73,7 @@ function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { } for(var i = 0; i < options.levelUids.length; i++) { - if(!validate(options.levelUids[i], {type: 'string', in: this.getMaps()})) { + if(!validate(options.levelUids[i], {type: 'string', in: ['stones2', 'debug']})) { this.isError = true; return "Could not create channel, invalid map (" + options.levelUids[i] + ")."; } @@ -96,32 +86,34 @@ function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { newOptions.maxUsers = options.maxUsers; } else { this.isError = true; - return "Could not create channel, user limit invalid. Limited to " + Settings.CHANNEL_MAX_USERS + " users"; + return "Could not create channel, Max users invalid. (Limited to " + Settings.CHANNEL_MAX_USERS + " users)"; } if(validate(options.minUsers, {optional: true, type: 'number', min: 0, max: Settings.CHANNEL_MAX_USERS})) { newOptions.minUsers = options.minUsers; } else { this.isError = true; - return "Could not create channel, minimal users limit too high. Limited to: " + Settings.CHANNEL_MAX_USERS; + return "Could not create channel, Max users too high. Limited to: " + Settings.CHANNEL_MAX_USERS; } // Limits - var scoreLimitPreferences = {type: 'number', min: 1, max: 999}; - if(validate(options.scoreLimit, scoreLimitPreferences)) { + if(validate(options.scoreLimit, {type: 'number', min: 1, max: 999})) { newOptions.scoreLimit = options.scoreLimit; } else { this.isError = true; - return "Could not create channel, score limit (" + options.scoreLimit + ") must be between " + scoreLimitPreferences.min + " and " + scoreLimitPreferences.max; + return "Could not create channel, score limit (" + options.scoreLimit + ")."; } + + var defaultOptions = { maxUsers: Settings.CHANNEL_DEFAULT_MAX_USERS, minUsers: 0, scoreLimit: Settings.CHANNEL_DEFAULT_SCORE_LIMIT }; - options = optionsHelper.merge(options, defaultOptions); + options = Options.merge(options, defaultOptions); + var result = this.coordinator.createChannel(options); if(result !== false) { @@ -142,25 +134,14 @@ function (nc, ProtocolHelper, validate, optionsHelper, Settings, FileSystem) { } return JSON.stringify(output); + }; Api.prototype.getContentType = function() { return "application/json"; }; - Api.prototype.getMaps = function(callback) { - - var list = FileSystem.readdirSync(Settings.MAPS_PATH); - var maps = []; - for (var i = 0; i < list.length; i++) { - var fileinfo = list[i].split("."); - if(fileinfo[1] == "json") { - maps.push(fileinfo[0]); - } - }; - //return ["stones"]; - return maps.sort(); - }; + return Api; diff --git a/app/Server/Coordinator.js b/app/Server/Coordinator.js index 20d8c93..407b539 100644 --- a/app/Server/Coordinator.js +++ b/app/Server/Coordinator.js @@ -1,18 +1,17 @@ define([ "Server/User", + "Game/Channel/Channel", "Server/PipeToChannel", "Lib/Utilities/NotificationCenter", "Game/Config/Settings" ], -function (User, PipeToChannel, nc, Settings) { - - "use strict"; +function (User, Channel, PipeToChannel, Nc, Settings) { function Coordinator() { this.channelPipes = {}; - nc.on(nc.ns.server.events.controlCommand.coordinator, this.onMessage, this); + Nc.on(Nc.ns.server.events.controlCommand.coordinator, this.onMessage, this); console.checkpoint('create Coordinator'); } @@ -21,9 +20,9 @@ function (User, PipeToChannel, nc, Settings) { new User(socketLink, this); } - // was assignUserToChannel... - Coordinator.prototype.getChannelPipeByName = function (channelName) { - return this.channelPipes[channelName]; + Coordinator.prototype.assignUserToChannel = function (user, channelName) { + var channelPipe = this.channelPipes[channelName]; + user.setChannelPipe(channelPipe); } Coordinator.prototype.onDestroyPipe = function(channelName) { @@ -33,18 +32,9 @@ function (User, PipeToChannel, nc, Settings) { Coordinator.prototype.getChannels = function(options) { var list = []; for (var channelName in this.channelPipes) { - - var options = this.channelPipes[channelName].options; - - var playerNames = []; - var users = this.channelPipes[channelName].getUsers(); - for (var i = 0; i < users.length; i++) { - playerNames[i] = users[i].options.nickname; - }; - options.players = playerNames; - options.playerCount = options.players.length; - - list.push(options); + list.push({ + name: channelName + }); } return list; } diff --git a/app/Server/PipeToChannel.js b/app/Server/PipeToChannel.js index 19bee94..94bc11b 100755 --- a/app/Server/PipeToChannel.js +++ b/app/Server/PipeToChannel.js @@ -3,22 +3,16 @@ define([ "child_process" ], -function (nc, childProcess) { +function (Nc, childProcess) { - "use strict"; + var fork = childProcess.fork; function PipeToChannel (options) { this.fork = null; - this.options = options; - this.users = []; try { - this.fork = childProcess.fork('channel.js' - /*, { - execArgv: ['--debug=5859'] - }*/ - ); + this.fork = fork('channel.js'); } catch (err) { throw 'Failed to fork channel! (' + err + ')'; } @@ -28,6 +22,8 @@ function (nc, childProcess) { this.send('channel/' + options.channelName, { CREATE: true, options: options }); this.fork.on('message', this.onMessage.bind(this)); + + var self = this; } // While creating user @@ -50,42 +46,18 @@ function (nc, childProcess) { this.fork.send(message); } - PipeToChannel.prototype.isFull = function() { - return this.users.length >= this.options.maxUsers; - }; - PipeToChannel.prototype.onMessage = function (message) { switch(message.recipient) { case 'coordinator': - nc.trigger(nc.ns.server.events.controlCommand.coordinator, message.data); + Nc.trigger(Nc.ns.server.events.controlCommand.coordinator, message.data); break; default: - nc.trigger(nc.ns.server.events.controlCommand.user + message.recipient, message.data); + Nc.trigger(Nc.ns.server.events.controlCommand.user + message.recipient, message.data); break; } } - PipeToChannel.prototype.addUser = function(user) { - this.users.push(user); - this.send('channel', { addUser: user.options }); - }; - - PipeToChannel.prototype.removeUser = function(user) { - for(var i = 0; i < this.users.length; i++) { - if(this.users[i] === user) { - this.users.splice(i, 1); - break; - } - } - - this.send('channel', { releaseUser: user.id }); - }; - - PipeToChannel.prototype.getUsers = function() { - return this.users; - }; - return PipeToChannel; }); \ No newline at end of file diff --git a/app/Server/User.js b/app/Server/User.js index 1ba04bc..3f3b47f 100644 --- a/app/Server/User.js +++ b/app/Server/User.js @@ -4,9 +4,7 @@ define([ "Lib/Utilities/NotificationCenter" ], -function (Parent, ProtocolHelper, nc) { - - "use strict"; +function (Parent, ProtocolHelper, Nc) { function User (socketLink, coordinator) { Parent.call(this, socketLink.id, {}); @@ -14,33 +12,24 @@ function (Parent, ProtocolHelper, nc) { this.coordinator = coordinator; this.socketLink = socketLink; this.channelPipe = null; - this.options = null; socketLink.on('message', this.onMessage.bind(this)); socketLink.on('disconnect', this.onDisconnect.bind(this)); - nc.on(nc.ns.server.events.controlCommand.user + this.id, this.socketLink.send, this.socketLink); + Nc.on(Nc.ns.server.events.controlCommand.user + this.id, this.socketLink.send, this.socketLink); } User.prototype = Object.create(Parent.prototype); -/* User.prototype.setChannelPipe = function(channelPipe) { if(channelPipe) { - if (channelPipe.isWithinUserLimit()) { - this.channelPipe = channelPipe; - this.channelPipe.addUser(this); - } else { - var message = ProtocolHelper.encodeCommand("joinError", {message:"Channel is full"}); - this.socketLink.send(message); - } - + this.channelPipe = channelPipe; } else { var message = ProtocolHelper.encodeCommand("joinError", {message:"Channel not found"}); this.socketLink.send(message); } }; - */ + // Socket callbacks @@ -49,13 +38,12 @@ function (Parent, ProtocolHelper, nc) { } User.prototype.onDisconnect = function () { - if(!this.channelPipe) { - console.warn("Disconnecting user without a channel. (Maybe channel was full)"); + console.warn("Disconnecting user without a channel."); return; } - this.channelPipe.removeUser(this); + this.channelPipe.send('channel', { releaseUser: this.id }); } @@ -63,29 +51,18 @@ function (Parent, ProtocolHelper, nc) { // Remember: control commands are coordinator relevant commands User.prototype.onJoin = function(options) { + this.coordinator.assignUserToChannel(this, options.channelName); - var channelPipe = this.coordinator.getChannelPipeByName(options.channelName); - - if(!channelPipe) { - var message = ProtocolHelper.encodeCommand("joinError", {message:"Channel " + options.channelName + " not found."}); - this.socketLink.send(message); + if(!this.channelPipe) { + console.warn("Can not join user because channel (" + options.channelName + ") does not exist.") return; } - if (channelPipe.isFull()) { - var message = ProtocolHelper.encodeCommand("joinError", {message:"Sorry! Channel " + options.channelName + " is full."}); - this.socketLink.send(message); - return; - } - - this.channelPipe = channelPipe; - var userOptions = { id: this.id, nickname: options.nickname } - this.options = userOptions; - this.channelPipe.addUser(this); + this.channelPipe.send('channel', { addUser: userOptions }); }; /* FIXME: watch out and check in wich direction game and control commands flow */ @@ -97,7 +74,7 @@ function (Parent, ProtocolHelper, nc) { User.prototype.onPing = function(timestamp) { var message = ProtocolHelper.encodeCommand("pong", timestamp); - nc.trigger(nc.ns.server.events.controlCommand.user + this.id, message); + Nc.trigger(Nc.ns.server.events.controlCommand.user + this.id, message); }; return User; diff --git a/channel.js b/channel.js index a94689f..3294623 100755 --- a/channel.js +++ b/channel.js @@ -4,11 +4,7 @@ var requirejs = require('requirejs'); requirejs.config({ nodeRequire: require, baseUrl: 'app', - deps: ['Lib/Utilities/Channel/Extensions'], - paths: { - text: 'Lib/Vendor/RequireJs/Plugin/Text', - json: 'Lib/Vendor/RequireJs/Plugin/Json', - }, + deps: ['Lib/Utilities/Extensions'] }); var inspector = {}; diff --git a/client.js b/client.js index f96233a..6bc6999 100755 --- a/client.js +++ b/client.js @@ -1,45 +1,35 @@ -"use strict"; - -var GLOBALS = { context: "Client" }; +GLOBALS = { context: "Client" }; requirejs.config({ baseUrl: 'app', - deps: ['Lib/Utilities/Client/Extensions'], - waitSeconds: 0, - paths: { - text: 'Lib/Vendor/RequireJs/Plugin/Text', - json: 'Lib/Vendor/RequireJs/Plugin/Json', - screenfull: "/screenfull", - chart: "/chart", - socketio: "/socket.io/socket.io" - }, + deps: ['Lib/Utilities/Extensions'], + waitSeconds: 0 }); -if(!Chuck) var Chuck = {}; -Chuck.inspector = {}; +var inspector = {}; requirejs([ "Game/Client/Networker", "Lib/Vendor/SocketIO", "Game/Config/Settings", "Lib/Utilities/Exception", - "Lib/Utilities/NotificationCenter", - "Menu/Menu" + "Lib/Vendor/Pixi" ], -function (Networker, io, Settings, Exception, nc, Menu) { +function (Networker, SocketIO, Settings, Exception, PIXI) { - var menu = new Menu(); - menu.onRun = function(channelName, nickname) { - var options = { - transports: ["websocket"] // v4: only use websocket, flashsocket is gone - }; - var socket = io("/", options); - var networker = new Networker(socket, channelName, nickname); - Chuck.inspector.networker = networker; - Chuck.inspector.settings = Settings; - Chuck.inspector.nc = nc; - Chuck.inspector.resetLevel = function() { networker.sendGameCommand("resetLevel"); } - } - menu.init(); -}); + var options = { + "reconnect": false, + "reconnection delay": 500, + "max reconnection attempts": 10, + "transports": [ + "websocket", + "flashsocket" + ] + }; + var socket = SocketIO.connect("/", options); + var networker = new Networker(socket); + inspector.networker = networker; + inspector.settings = Settings; + inspector.resetLevel = function() { networker.sendGameCommand("resetLevel"); } +}); \ No newline at end of file diff --git a/config/build-profile.js b/config/build-profile.js deleted file mode 100644 index e650ccc..0000000 --- a/config/build-profile.js +++ /dev/null @@ -1,16 +0,0 @@ -({ - baseUrl: "../app", - paths: { - "text": 'Lib/Vendor/RequireJs/Plugin/Text', - "json": 'Lib/Vendor/RequireJs/Plugin/Json', - "screenfull": "../node_modules/screenfull/dist/screenfull", - "socketio": "../node_modules/socket.io/node_modules/socket.io-client/dist/socket.io", - "chart": "../node_modules/chart.js/Chart" - }, - name: "../client", - out: "../build/client.min.js", - onBuildRead: function (moduleName, path, contents) { - var contents = contents.replace(/\" \+ GLOBALS.context \+ \"/g, "Client"); - return contents; - } -}) diff --git a/config/ecosystem-dev.json5 b/config/ecosystem-dev.json5 deleted file mode 100644 index d09f2ec..0000000 --- a/config/ecosystem-dev.json5 +++ /dev/null @@ -1,42 +0,0 @@ -{ - /** - * This is a sample configuration file for PM2 - */ - - /** - * Here we declare the apps that must be managed by PM2 - * All options are listed here: - * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#json-app-declaration - * - */ - apps : [ - - // Development - { - name : "chuck-dev", - script : "server.js", - env : { - NODE_ENV: "dev", - PORT: "1234" - } - } - - ], - - - /** - * PM2 help you to deploy apps over your servers - * For more help go to : - * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#deployment-pm2--090 - */ - deploy : { - dev : { - user : "chuck", - host : "fuuuuu.de", - ref : "origin/master", - repo : "https://github.com/logsol/chuck.js.git", - path : "/home/chuck/development", - "post-deploy" : "npm install && pm2 startOrRestart config/ecosystem-dev.json5 --env dev", - } - } -} diff --git a/config/ecosystem.json5 b/config/ecosystem.json5 deleted file mode 100644 index 0f48026..0000000 --- a/config/ecosystem.json5 +++ /dev/null @@ -1,50 +0,0 @@ -{ - /** - * This is a sample configuration file for PM2 - */ - - /** - * Here we declare the apps that must be managed by PM2 - * All options are listed here: - * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#json-app-declaration - * - */ - apps : [ - - // Production - { - name : "chuck", - script : "server.js", - env_production : { - NODE_ENV: "production", - PORT: "1235" - } - } - - ], - - - /** - * PM2 help you to deploy apps over your servers - * For more help go to : - * https://github.com/Unitech/PM2/blob/master/ADVANCED_README.md#deployment-pm2--090 - */ - deploy : { - production : { - user : "chuck", - host : "fuuuuu.de", - ref : "origin/master", - repo : "https://github.com/logsol/chuck.js.git", - path : "/home/chuck/production", - "post-deploy" : "npm install && NODE_ENV=production sh scripts/build.sh && pm2 startOrRestart config/ecosystem.json5 --env production" - }, - production2 : { - user : "jeena", - host : "chuck2.fuuuuu.de", - ref : "origin/master", - repo : "https://github.com/logsol/chuck.js.git", - path : "/home/jeena/chuck/production", - "post-deploy" : "npm install && NODE_ENV=production sh scripts/build.sh && pm2 startOrRestart config/ecosystem.json5 --env production" - } - } -} diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..8d99702 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# cd /home/logsol/projects/js/chuck.js/ && forever stop server.js +# cd /home/logsol/projects/js/chuck.js/ && forever start server.js && echo "forever - just restarted server" + +cd /home/logsol/projects/js/chuck.js/ && forever restart server.js + diff --git a/lab/Worker.js b/lab/Worker.js index 04585b1..62483bb 100755 --- a/lab/Worker.js +++ b/lab/Worker.js @@ -6,7 +6,7 @@ define([ "Lib/Utilities/NotificationCenter" ], -function (Parent, ProtocolHelper, GameController, User) { +function (Parent, ProtocolHelper, GameController, User, Nc) { function Worker () { //this.socketLink = socketLink; @@ -40,7 +40,7 @@ function (Parent, ProtocolHelper, GameController, User) { } }, this); - nc.on(nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this); + Nc.on(Nc.ns.client.to.server.gameCommand.send, this.sendGameCommand, this); } Worker.prototype.sendCommand = function (command, options) { diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 3f2a506..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2352 +0,0 @@ -{ - "name": "chuck.js", - "version": "0.1.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "chuck.js", - "version": "0.1.0", - "dependencies": { - "chart.js": "^4.4.0", - "express": "^4.18.2", - "requirejs": "^2.3.6", - "screenfull": "^6.0.2", - "socket.io": "^4.7.4" - }, - "devDependencies": { - "nodemon": "^3.0.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@kurkle/color": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", - "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "24.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.14.tgz", - "integrity": "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==", - "dependencies": { - "undici-types": "~7.8.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/chart.js": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", - "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", - "dependencies": { - "@kurkle/color": "^0.3.0" - }, - "engines": { - "pnpm": ">=8" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/engine.io": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", - "dependencies": { - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/engine.io/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/requirejs": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz", - "integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==", - "bin": { - "r_js": "bin/r.js", - "r.js": "bin/r.js" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/screenfull": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-6.0.2.tgz", - "integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==", - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/socket.io": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.2.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "node_modules/socket.io-adapter/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-adapter/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-parser/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - }, - "dependencies": { - "@kurkle/color": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", - "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" - }, - "@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" - }, - "@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "24.0.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.14.tgz", - "integrity": "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==", - "requires": { - "undici-types": "~7.8.0" - } - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" - }, - "binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true - }, - "body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - } - }, - "call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "requires": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - } - }, - "chart.js": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.0.tgz", - "integrity": "sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==", - "requires": { - "@kurkle/color": "^0.3.0" - } - }, - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "requires": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "engine.io": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", - "requires": { - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - }, - "dependencies": { - "cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==" - }, - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==" - }, - "es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "requires": { - "es-errors": "^1.3.0" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "requires": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - } - }, - "get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "requires": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "nodemon": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", - "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", - "dev": true, - "requires": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "dependencies": { - "debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "requires": { - "side-channel": "^1.0.6" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "requirejs": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz", - "integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==" - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "screenfull": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-6.0.2.tgz", - "integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==" - }, - "semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true - }, - "send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "requires": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "requires": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - } - }, - "side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "requires": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - } - }, - "side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "requires": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - } - }, - "side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "requires": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - } - }, - "simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "socket.io": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", - "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "requires": { - "debug": "~4.3.4", - "ws": "~8.17.1" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "dependencies": { - "debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" - }, - "ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "requires": {} - } - } -} diff --git a/package.json b/package.json index 6fbcbb3..21de95a 100755 --- a/package.json +++ b/package.json @@ -1,9 +1,7 @@ { "name": "chuck.js", "author": "logsol ", - "contributors": [ - "Jeena Paradies (https://jeena.net)" - ], + "contributors": ["Jeena Paradies (https://jeena.net)"], "description": "Multiplayer browser jump and run game", "version": "0.1.0", "homepage": "http://chuck-game.tumblr.com/", @@ -15,28 +13,17 @@ "url": "https://github.com/logsol/chuck.js/issues", "email": "fartman@gmx.de" }, - "main": "server.js", + "main": "", "dependencies": { - "socket.io": "^4.7.4", - "express": "^4.18.2", - "requirejs": "^2.3.6", - "screenfull": "^6.0.2", - "chart.js": "^4.4.0" - }, - "devDependencies": { - "nodemon": "^3.0.2" + "socket.io": ">= 0.9.6", + "node-static": ">= 0.6.0", + "requirejs": "= 2.0.4", + "node-fork": ">= 0.4.2", + "screenfull": ">= 1.0.4" }, + "devDependencies": {}, "optionalDependencies": {}, - "engines": { - "node": ">=16.0.0" - }, - "config": { - "port": "1234" - }, - "private": true, - "scripts": { - "start": "node server.js", - "dev": "nodemon server.js", - "prestart": "scripts/build.sh" - } + "engine": "node >= 0.8.4", + "config": { "port": "1234" }, + "private": true } diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index 4b58bcb..0000000 --- a/scripts/build.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -if env | grep -q "^NODE_ENV=production$" -then - echo "[ PRODUCTION ]" - mkdir -p build - echo "- compiling client scripts.." - rm -f "build/client.min.js.gz" - node_modules/requirejs/bin/r.js -o config/build-profile.js \ - && gzip -c build/client.min.js > build/client.min.js.gz \ - && echo "- done." -else - echo "[ DEVELOPMENT ]" -fi diff --git a/scripts/core_analyzer.js b/scripts/core_analyzer.js deleted file mode 100644 index 3885d12..0000000 --- a/scripts/core_analyzer.js +++ /dev/null @@ -1,247 +0,0 @@ -/* - * This will generate a core/channel/client overview of a class - * - * usage: - * node scripts/core_analyzer.js [relative/path/class.js] -> relative path from core/client/channel split - * - * example: - * node scripts/core_analyzer.js GameObjects/Item.js - * - * example result: - * - * | CHANNEL | CORE | CLIENT - * |---------------------------------------|---------------------------------------|-------------------------------- - * | | getBodyDef | - * | | getFixtureDef | - * | | createFixture | - * | | flip | flip - * | beingGrabbed | beingGrabbed | - * | beingReleased | beingReleased | - * | onCollisionChange | onCollisionChange | - * | | reposition | - * | | getGrabPoint | - * | | throw | - * | | accelerateBody | - * | | destroy | destroy - * | | | createMesh - * | | | render - * | getLastMovedBy | | - * | setLastMovedBy | | - * | isGrabbingAllowed | | - * | isReleasingAllowed | | - * - */ - -var fs = require('fs'); -var util = require('util'); -var esprima = require('esprima'); -var escodegen = require('escodegen'); - -var info = []; -var overview = {}; - -var generatorOption = { - format: { - indent: { - style: ' ', - base: 0, - adjustMultilineComment: true//false - }, - newline: '\n', - space: ' ', - json: false, - renumber: false, - hexadecimal: false, - quotes: 'single', - escapeless: false, - compact: false, - parentheses: true, - semicolons: true, - safeConcatenation: true - }, - moz: { - starlessGenerator: false, - parenthesizedComprehensionBlock: false, - comprehensionExpressionStartsWithAssignment: false - }, - parse: null, - comment: true, - sourceMap: undefined, - sourceMapRoot: null, - sourceMapWithCode: false, - file: undefined, - directive: false, - verbatim: undefined -}; - -function readFile (path, category, fileName) { - //console.log("+++++ " + moduleName + " ++++++"); - var contents = fs.readFileSync(path + "/" + category + "/" + fileName); - contents = contents.toString(); - - getMethods(path, fileName, contents, category); -} - -function getMethods (path, fileName, contents, category) { - - category = category.toLowerCase(); - - overview[category] = []; - - var fullPath = path + "/" + fileName; - var moduleName = fileName.split(".js").join(""); - var tree = esprima.parse(contents); - - // find moduleId from return statement on module level - var module = tree.body[0].expression.arguments[1].body.body; - var moduleId = findModuleId(module); - - if (!moduleId) { - info.push("could not find moduleId in: " + fullPath); - return; - } - - if (moduleId == "Parent") { - info.push("not optimizing empty module (returning Parent) in: " + fullPath); - return; - } - - // find constructor - var constructorPosition = findConstructorPosition(module, moduleId); - if (constructorPosition === false) { - info.push("could not find constructor in: " + fileName) - return; - } - var constructor = module[constructorPosition]; - - - - for (var j = 0; j < module.length; j++) { - var expression = module[j]; - - if (expression.type == "ExpressionStatement") { - if(expression.expression && expression.expression.right) { - if(expression.expression.right.type == "FunctionExpression") { - overview[category].push(expression.expression.left.property.name); - } - } - } - } - - //console.log(escodegen.generate(tree, generatorOption)); -} - -function findModuleId (module) { - var moduleId = false; - for (var j = 0; j < module.length; j++) { - var expression = module[j]; - - //console.log(util.inspect(expression, { showHidden: true, depth: 4 })); - - if (expression.type == "ReturnStatement") { - - if(expression.argument.type == "Identifier") { - - // for return Module; - moduleId = expression.argument.name; - break; - - } else if (expression.argument.type == "NewExpression") { - - // for return new Module; - moduleId = expression.argument.callee.name; - break; - - } else { - info.push("Unexpected return type at module level. " + fullPath) - } - } - } - return moduleId; -}; - -function findConstructorPosition (module, moduleId) { - - for (var j = 0; j < module.length; j++) { - var expression = module[j]; - - if (expression.type == "FunctionDeclaration" && expression.id.name == moduleId) { - return j; - } - } - return false; -} - - -var superOverview = {}; -function display (category) { - - var all = ["core", "client", "channel"]; - var removeIndex = all.indexOf(category); - all.splice(removeIndex, 1); - - for (var k in overview[category]) { - - var name = overview[category][k]; - - if(superOverview.hasOwnProperty(name)) { - continue; - } - - var first = all[0]; - var second = all[1]; - - fv = 0 + (overview[first].indexOf(name) !== -1); - sv = 0 + (overview[second].indexOf(name) !== -1); - - superOverview[name] = {}; - - superOverview[name][category] = 1; - superOverview[name][first] = fv; - superOverview[name][second] = sv; - superOverview[name]['count'] = 1 + fv + sv; - } -} - -function show(){ - var alle = ['channel', 'core', 'client']; - console.log("| CHANNEL | CORE | CLIENT"); - console.log("|---------------------------------------|---------------------------------------|--------------------------------"); - for (var method in superOverview) { - var line = ""; - - for (var i = 0; i < alle.length; i++) { - if (superOverview[method] && superOverview[method].hasOwnProperty(alle[i])) { - - line += "| " ; - - if(superOverview[method][alle[i]] === 1) { - line += method; - line += Array(39 - method.length).join(" "); - } else { - line += Array(39).join(" "); - } - - - } else { - - } - - } - console.log(line) - } -} - - - -readFile("app/Game", "Core", process.argv[2]); -readFile("app/Game", "Channel", process.argv[2]); -readFile("app/Game", "Client", process.argv[2]); - -display("core") -display("client") -display("channel") - -console.log("\n") -show() -console.log("\n") \ No newline at end of file diff --git a/scripts/deploy.sh b/scripts/deploy.sh deleted file mode 100755 index 60b20ff..0000000 --- a/scripts/deploy.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - -# Get dir of this script -DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/.. - -if [ -z "$1" ] -then - pm2 deploy $DIR/config/ecosystem-dev.json5 dev - exit -fi - -if [ "$1" == "production" ] -then - pm2 deploy $DIR/config/ecosystem.json5 production - exit -fi - -if [ "$1" == "production2" ] -then - pm2 deploy $DIR/config/ecosystem.json5 production2 - exit -fi - -echo "Case ($1) not defined. doing nothing." \ No newline at end of file diff --git a/scripts/optimize.js b/scripts/optimize.js deleted file mode 100644 index 63d0a76..0000000 --- a/scripts/optimize.js +++ /dev/null @@ -1,218 +0,0 @@ -/* - * This is supposed to be a code optimizer. - * - * usage: - * node scripts/optimize.js - * - * based on https://developers.google.com/speed/articles/optimizing-javascript - * I wanted to automatically replace properties as discribed under "Initializing instance variables" - * - * So far it is the only thing this script does, but the potential for more is there. - * Also it does not (yet) write to any files, only outputs the results in the console. - * - * The script fully disasembles the entire codebase (with esprima) and reconstructs (via escodegen) it - * with a few optimisations unfortunately it loses ambiguous new lines and such, so that it might - * not be entirely usable as a code replacing script - it could perhaps be used as a compile script in - * production - * - * But it has also nice things as at will add semicolons everywhere automatically and will - * definately keep a solid indentation style for everything. Since it lacks a lot of extra - * \n newlines it looks quite cluttered though. - * - */ - -var fs = require('fs'); -var util = require('util'); -var esprima = require('esprima'); -var escodegen = require('escodegen'); - -var info = []; - -var generatorOption = { - format: { - indent: { - style: ' ', - base: 0, - adjustMultilineComment: true//false - }, - newline: '\n', - space: ' ', - json: false, - renumber: false, - hexadecimal: false, - quotes: 'single', - escapeless: false, - compact: false, - parentheses: true, - semicolons: true, - safeConcatenation: true - }, - moz: { - starlessGenerator: false, - parenthesizedComprehensionBlock: false, - comprehensionExpressionStartsWithAssignment: false - }, - parse: null, - comment: true, - sourceMap: undefined, - sourceMapRoot: null, - sourceMapWithCode: false, - file: undefined, - directive: false, - verbatim: undefined -}; - -function readdir (path) { - var filesNames = fs.readdirSync(path) - - for (var i = 0; i < filesNames.length; i++) { - - var fileName = filesNames[i]; - var fullPath = path + "/" + fileName; - - if(path == "app/Lib/Vendor"){ - continue; - } - - if(fileName.indexOf(".js") == -1) { - var stats = fs.lstatSync(fullPath); - if (stats.isDirectory()) { - readdir(fullPath); - } - continue; - } - - readFile(path, fileName); - }; -} - -function readFile (path, fileName) { - //console.log("+++++ " + moduleName + " ++++++"); - var contents = fs.readFileSync(path + "/" + fileName); - contents = contents.toString(); - - optimize(path, fileName, contents); -} - -function optimize (path, fileName, contents) { - var fullPath = path + "/" + fileName; - var moduleName = fileName.split(".js").join(""); - var tree = esprima.parse(contents); - - // find moduleId from return statement on module level - var module = tree.body[0].expression.arguments[1].body.body; - var moduleId = findModuleId(module); - - if (!moduleId) { - info.push("could not find moduleId in: " + fullPath); - return; - } - - if (moduleId == "Parent") { - info.push("not optimizing empty module (returning Parent) in: " + fullPath); - return; - } - - // find constructor - var constructorPosition = findConstructorPosition(module, moduleId); - if (constructorPosition === false) { - info.push("could not find constructor in: " + fileName) - return; - } - var constructor = module[constructorPosition]; - transformProps(tree, moduleId, constructor, constructorPosition); - - console.log(escodegen.generate(tree, generatorOption)); -} - -function findModuleId (module) { - var moduleId = false; - for (var j = 0; j < module.length; j++) { - var expression = module[j]; - - //console.log(util.inspect(expression, { showHidden: true, depth: 4 })); - - if (expression.type == "ReturnStatement") { - - if(expression.argument.type == "Identifier") { - - // for return Module; - moduleId = expression.argument.name; - break; - - } else if (expression.argument.type == "NewExpression") { - - // for return new Module; - moduleId = expression.argument.callee.name; - break; - - } else { - info.push("Unexpected return type at module level. " + fullPath) - } - } - } - return moduleId; -}; - -function findConstructorPosition (module, moduleId) { - - for (var j = 0; j < module.length; j++) { - var expression = module[j]; - - if (expression.type == "FunctionDeclaration" && expression.id.name == moduleId) { - return j; - } - } - return false; -} - -function transformProps (tree, moduleId, constructor, constructorPosition) { - var props = []; - for (var k = constructor.body.body.length - 1; k >= 0; k--) { - var line = constructor.body.body[k]; - - if(line.expression - && line.expression.type == "AssignmentExpression" - && line.expression.operator == "=" - && line.expression.left.type == "MemberExpression" - && line.expression.left.object.type == "ThisExpression" - && line.expression.right.type == "Literal") { - - // remove "this" properties with with value type from constructor - constructor.body.body.splice(k, 1); - //console.log(util.inspect(line, { showHidden: true, depth: 4 })); - - props.push({ - name: line.expression.left.property.name, - value: line.expression.right.value, - raw: line.expression.right.raw - }); - } - }; - - // generate prototype properties - for (var l = 0; l < props.length; l++) { - var attributes = props[l]; - - var prop = { type: 'ExpressionStatement', - expression: - { type: 'AssignmentExpression', - operator: '=', - left: - { type: 'MemberExpression', - computed: false, - object: - { type: 'MemberExpression', - computed: false, - object: { type: 'Identifier', name: moduleId }, - property: { type: 'Identifier', name: 'prototype' } }, - property: { type: 'Identifier', name: attributes.name } }, - right: { type: 'Literal', value: attributes.value, raw: attributes.raw } } } - - // place property after constructor - tree.body[0].expression.arguments[1].body.body.splice(constructorPosition+1, 0, prop); - }; -} - -readdir("app"); -console.log(info) diff --git a/scripts/optimize_.js b/scripts/optimize_.js deleted file mode 100644 index 4e5883a..0000000 --- a/scripts/optimize_.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * First version of the optimizer, relying completely on regular expressions - * - * it grabs the code as text and just executes the outermost function (module level) - * therefore it would not execute any real code, only setup the prototype functinos - * and the constructor - * - * since some modules use "return new Module();" to create a singleton, I added - * a mechanism to remove the "new" keyword and get the same kind of non-executing behaviour - * - * the trial failed because i could not replace the old constructor with the new one - * with simple replace algorithms because of whitespace differences - * - * Spits out some small statistics at the end, which is quite nice - */ - -var fs = require('fs'); - -var successful = []; -var canceled = []; -var noconstruct = []; -var repaired = []; - -function readdir (path) { - var filesNames = fs.readdirSync(path) - - for (var i = 0; i < filesNames.length; i++) { - - var fileName = filesNames[i]; - var newPath = path + "/" + fileName; - - if(path == "app/Lib/Vendor"){ - continue; - } - - if(fileName.indexOf(".js") == -1) { - var stats = fs.lstatSync(newPath); - if (stats.isDirectory()) { - readdir(newPath); - } - continue; - } - - var moduleName = fileName.split(".js").join(""); - - var contents = fs.readFileSync(newPath); - contents = contents.toString(); - - // remove define construct around module, just get the module function - contents = contents.replace(/define\(\[[^\]]*\],\s*([\s\S]*)\);/, '$1'); - - // remove new from last return / disable singletons (eg. return new NotificationCenter;) - var before = contents; - contents = contents.replace(/([\s\S]*)return new ([a-zA-Z0-9]*)\s*\(?.*\);/, '$1return $2;'); - if (contents != before){ - repaired.push(moduleName); - } - - - eval("var module = " + contents); - - try { - // test run, to get possible exceptions - var Parent = function(){}; - var constructor = module(Parent); - - if (typeof constructor == 'object') { - noconstruct.push(newPath); - continue; - } - - //var optimizedModule = optimize(moduleName, module); - //console.log(optimizedModule); - - successful.push(newPath); - - } catch (e) { - //console.log(e) // see whats making it cancel - canceled.push(newPath); - } - }; -} - -function optimize(moduleName, module) { -/* - var better = module.toString(); - - var Parent = function(){}; - var constructor = module(Parent).toString(); - - var regex = /^\s*this\.(.*) = (.*)\n?/mig; - var props = []; - - do { - match = regex.exec(constructor); - if(match) { - props.push(moduleName + ".prototype." + match[1] + " = " + match[2]); - } - - } while (match != null); - - // remove original this.prop - constructor = constructor.replace(regex, ''); - - // add prototype variables at bottom of constructor - if (props.length > 0) { - constructor = constructor + "\n\n" + props.join("\n"); - } - //constructor = constructor.replace("function " + moduleName + "(", "function " + moduleName + " ("); - */ - - return ""; -} - -readdir("app"); - - -console.log("- Successful:", successful.length) -console.log("- Canceled:", canceled.length) -console.log("- No Constructor:", noconstruct.length) -console.log("- Repaired Singletons:", repaired.length) - -console.log("canceled:", canceled) -console.log("no constructor:", noconstruct) -//console.log("successful:", successful) \ No newline at end of file diff --git a/server.js b/server.js index bb9586f..9d829aa 100755 --- a/server.js +++ b/server.js @@ -1,15 +1,12 @@ -"use strict" - -var GLOBALS = { context: "Channel" }; +GLOBALS = { context: "Channel" }; var requirejs = require('requirejs'); -var fs = require('fs'); var inspector; requirejs.config({ nodeRequire: require, baseUrl: 'app', - deps: ['Lib/Utilities/Channel/Extensions'] + deps: ['Lib/Utilities/Extensions'] }); var port = process.argv[2] @@ -26,17 +23,10 @@ var options = { requirejs([ "Bootstrap/HttpServer", "Bootstrap/Socket", - "Server/Coordinator", - "Game/Config/Settings" + "Server/Coordinator" ], -function (HttpServer, Socket, Coordinator, Settings) { - - var records = fs.readdirSync(Settings.CHANNEL_RECORDING_PATH); - if (records.length > 200) { - console.warn('Too many recordings!'); - } - +function (HttpServer, Socket, Coordinator) { var coordinator = new Coordinator(); var httpServer = new HttpServer(options, coordinator); var socket = new Socket(httpServer.getServer(), options, coordinator); diff --git a/snippets/cheats/leftRightBot.js b/snippets/cheats/leftRightBot.js deleted file mode 100644 index 45e6b92..0000000 --- a/snippets/cheats/leftRightBot.js +++ /dev/null @@ -1,31 +0,0 @@ -var runFor = 5000; -var jumpEvery = 1300; - -var runBot = setInterval(function(){ - - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'stop'); - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'lookAt', {x:-0.5, y:0}); - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'moveLeft'); - - setTimeout(function(){ - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'stop'); - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'lookAt', {x:0.5, y:0}); - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'moveRight'); - }, runFor); - -}, runFor * 2); - -var jumpBot = setInterval(function(){ - - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'jump'); - - setTimeout(function(){ - Chuck.inspector.nc.trigger(Chuck.inspector.nc.ns.client.to.server.gameCommand.send, 'jumpStop'); - }, (jumpEvery - 100)); - -}, jumpEvery); - -function stop () { - clearInterval(runBot); - clearInterval(jumpBot); -} \ No newline at end of file diff --git a/snippets/sublime/js-define-child.sublime-snippet b/snippets/sublime/js-define-child.sublime-snippet index 27857d4..9d74c6e 100644 --- a/snippets/sublime/js-define-child.sublime-snippet +++ b/snippets/sublime/js-define-child.sublime-snippet @@ -6,8 +6,6 @@ define([ function (Parent) { - "use strict"; - return Parent; }); diff --git a/snippets/sublime/js-define-extend.sublime-snippet b/snippets/sublime/js-define-extend.sublime-snippet index 1e9447d..711e7ce 100755 --- a/snippets/sublime/js-define-extend.sublime-snippet +++ b/snippets/sublime/js-define-extend.sublime-snippet @@ -5,8 +5,6 @@ define([ ], function (Parent) { - - "use strict"; function ${1:Module}() { Parent.call(this); @@ -16,7 +14,7 @@ function (Parent) { ${1:Module}.prototype.${3:name} = function(${4:arguments}) { return null; - }; + } return ${1:Module}; diff --git a/snippets/sublime/js-define.sublime-snippet b/snippets/sublime/js-define.sublime-snippet index 31eac40..390cb91 100755 --- a/snippets/sublime/js-define.sublime-snippet +++ b/snippets/sublime/js-define.sublime-snippet @@ -4,16 +4,13 @@ define([ ], function () { - - "use strict"; function ${1:Module}() { - } ${1:Module}.prototype.${2:name} = function(${3:arguments}) { return null; - }; + } return ${1:Module}; diff --git a/static/css/screen.css b/static/css/screen.css deleted file mode 100644 index 6cc74a3..0000000 --- a/static/css/screen.css +++ /dev/null @@ -1,211 +0,0 @@ -@font-face { - font-family: 'Joystix'; - src: url('/static/fonts/2D6D36_0_0.eot'); - src: url('/static/fonts/2D6D36_0_0.eot?#iefix') format('embedded-opentype'), - url('/static/fonts/2D6D36_0_0.woff2') format('woff2'), - url('/static/fonts/2D6D36_0_0.woff') format('woff'), - url('/static/fonts/2D6D36_0_0.ttf') format('truetype'); -} - -h1, h2, h3, h4, th { - font-weight: normal; -} - -html, body { - width: 100%; - height: 100%; -} - -body { - background: #222; - color: #ccc; - font-family: 'Joystix', "Lucida Grande", sans-serif; - /*text-transform: uppercase;*/ - margin: 0; - padding: 0; - display: table; - -moz-osx-font-smoothing: grayscale; -} - -#menuBar { - - list-style-type: none; - background: rgba(0, 0, 0, 0.5); - position: absolute; - z-index: 1; - width: 100%; - margin: 0; - padding: 5px 0; - - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -#menuBar button { - outline : 0; - -moz-outline : 0; -} - -#menuBar li { - float: left; - margin-left: 40px; -} - -#menuBar li label { - - padding: 5px 0; - display: block; -} - -#back-to-menu { - margin-left: 5px !important; -} - -#graph-fps { - background: rgba(0,0,0,0.3); - border: 1px solid rgba(0,0,0,0.5); - padding: 2px; - display: inline; -} - - -#fullscreen { - float: right !important; - margin-right: 5px; -} - -::selection { - background: #720000; /* Safari */ - } -::-moz-selection { - background: #720000; /* Firefox */ -} - -input, button { - background: black; - color: #ccc; - border: 0; - padding: 0.3em 0.6em 0.6em; - font-size: 1em; - font-family: inherit; - text-transform: inherit; -} - -#createform, #customjoinform, #game { - display: none; -} - -#createform #maps { - text-transform: capitalize; -} - -#primarycolor { - padding: 0.3em; - width: 1em; - background-color: #777; -} - -article#menu { - margin: 4em auto; - background: #1a1a1a; - padding: 2em; - max-width: 40em; -} - -table, th, td { - border: 1px solid #777; - border-collapse: collapse; -} - -th, td { - padding: 0.5em 1em; -} - -ul { - list-style-type: none; - padding-left: 0; -} - -#link { - width: 100%; -} - -.offline { - background: #ccc; -} - -tr:hover td { - background: #222; -} - -.full { - color: #777; -} - -.full a { - color: inherit; - cursor:not-allowed;; -} - -#players { - position: absolute; - - border: 1px solid #777; - padding: 20px; - margin-left: 35px; - margin-top: -10px; - background: rgba(20, 20, 20, 0.95); - box-shadow: 5px 5px 5px #000; - display: none; -} - -.playersCell:hover #players { - display: block; -} - -a { - color: #ccc; -} - - -#canvasContainer { - /* - text-align: center; - display: table-cell; - vertical-align: middle; - */ - height: 100%; -} - -#canvasContainer canvas { - position: absolute;/* - top: 50%; - left: 50%; - margin-top: -200px; - margin-left: -300px;*/ -} - - -:-webkit-full-screen { - top: 0; - left: 0; - margin: 0; - padding: 0; -} - -#devtools { - position: absolute; - right: 0; - top: 0; - padding: 10px; - background: #333; -} - -#devtools p { - padding: 5px 0 0 0; - margin: 0; -} diff --git a/static/fonts/2D6D36_0_0.eot b/static/fonts/2D6D36_0_0.eot deleted file mode 100644 index 6d3dfd6..0000000 Binary files a/static/fonts/2D6D36_0_0.eot and /dev/null differ diff --git a/static/fonts/2D6D36_0_0.ttf b/static/fonts/2D6D36_0_0.ttf deleted file mode 100644 index f2f5c2a..0000000 Binary files a/static/fonts/2D6D36_0_0.ttf and /dev/null differ diff --git a/static/fonts/2D6D36_0_0.woff b/static/fonts/2D6D36_0_0.woff deleted file mode 100644 index dfd6506..0000000 Binary files a/static/fonts/2D6D36_0_0.woff and /dev/null differ diff --git a/static/fonts/2D6D36_0_0.woff2 b/static/fonts/2D6D36_0_0.woff2 deleted file mode 100644 index 5a3a3c7..0000000 Binary files a/static/fonts/2D6D36_0_0.woff2 and /dev/null differ diff --git a/static/html/game.html b/static/html/game.html new file mode 100755 index 0000000..29ac5eb --- /dev/null +++ b/static/html/game.html @@ -0,0 +1,63 @@ + + + + + Chuck + + + +
    + +
    + + + diff --git a/static/html/index.html b/static/html/index.html index 24f0143..6b7399a 100644 --- a/static/html/index.html +++ b/static/html/index.html @@ -1,19 +1,26 @@ - - Chuck - - + Chuck Lobby + -