├── .cfignore ├── .gitignore ├── License.txt ├── README.md ├── manifest.yml ├── nodemon.json ├── package.json ├── project.json ├── public ├── css │ ├── style.css │ └── style.less ├── favicon.ico ├── index.html ├── js │ ├── form.js │ ├── game.js │ └── vendors │ │ ├── jquery │ │ ├── jquery-2.1.3.min.js │ │ └── jquery-2.1.3.min.map │ │ ├── phaser │ │ ├── ninja.js │ │ ├── ninja.min.js │ │ ├── p2.js │ │ ├── p2.min.js │ │ ├── phaser-arcade-physics.js │ │ ├── phaser-arcade-physics.min.js │ │ ├── phaser-ninja-physics.js │ │ ├── phaser-ninja-physics.min.js │ │ ├── phaser-no-libs.js │ │ ├── phaser-no-libs.min.js │ │ ├── phaser-no-physics.js │ │ ├── phaser-no-physics.min.js │ │ ├── phaser.js │ │ ├── phaser.map │ │ ├── phaser.min.js │ │ ├── pixi.js │ │ └── pixi.min.js │ │ └── qrcode │ │ ├── qrcode.js │ │ └── qrcode.min.js └── res │ ├── sprites │ └── pixel.png │ └── textures │ └── loading.png ├── server ├── app.js ├── main.js ├── routes.js ├── server.js └── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── slides ├── images ├── 4pong.png ├── GooglePlayGames.png ├── League_of_Legends_logo.png ├── Logo_di_World_of_Warcraft.gif ├── P2P-network.png ├── P2P-network.svg ├── PhotonCloud.png ├── Pong460x276.jpg ├── Quake3_Logo.PNG ├── Server-based-network.png ├── Server-based-network.svg ├── appwarp.png ├── callofduty.png ├── clientServer.gif ├── cono.png ├── game-center.png ├── hayday.png ├── hybrid-network.png ├── lan.jpg ├── nodejs.png ├── overvolt.png ├── points │ ├── p1.png │ ├── p2.png │ ├── p3.png │ ├── p4.png │ └── p5.png ├── pro.png ├── racer.png ├── ruzzle.png ├── smartfoxserver.png └── socketio.png └── slides.pptx /.cfignore: -------------------------------------------------------------------------------- 1 | launchConfigurations/ 2 | .git/ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | launchConfigurations/ 3 | 4 | # Logs 5 | logs 6 | *.log 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | 13 | # Directory for instrumented libs generated by jscoverage/JSCover 14 | lib-cov 15 | 16 | # Coverage directory used by tools like istanbul 17 | coverage 18 | 19 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 20 | .grunt 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # Commenting this out is preferred by some people, see 27 | # https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 28 | node_modules 29 | 30 | # Users Environment Variables 31 | .lock-wscript 32 | /.project 33 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction to development of multiplayer HTML5 games (with Socket.io) 2 | ============== 3 | 4 | Here you can find all the slides and demos showed at my talk during Rome's Codemotion 2015 5 | 6 | http://pong4.eu-gb.mybluemix.net - the example showed during the talk - not anymore online! but you can deploy your own copy on bluemix! This project is bluemix ready :) 7 | 8 | 9 | 10 | Here you can find other talks: 11 | 12 | https://github.com/Lotti/codemotion2014 13 | 14 | http://www.slideshare.net/Lotti86/codemotion-tech-meetup-36452886 15 | -------------------------------------------------------------------------------- /manifest.yml: -------------------------------------------------------------------------------- 1 | applications: 2 | - disk_quota: 1024M 3 | host: pong4 4 | name: Pong4 5 | command: node server/main.js 6 | path: . 7 | instances: 1 8 | memory: 256M 9 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | ".git", 4 | "node_modules", 5 | "node_modules/**/node_modules", 6 | "public", 7 | "slides" 8 | ], 9 | "verbose": true, 10 | "execMap": { 11 | "js": "node" 12 | }, 13 | "watch": [ 14 | "server/" 15 | ], 16 | "env": { 17 | "NODE_ENV": "development", 18 | "PORT": 3000, 19 | "DEBUG": "pong:*" 20 | }, 21 | "ext": "js json yml" 22 | } 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pong", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./server/main", 7 | "dev": "nodemon ./server/main" 8 | }, 9 | "dependencies": { 10 | "body-parser": "1.15.2", 11 | "compression": "1.6.2", 12 | "cookie-parser": "1.4.3", 13 | "debug": "2.3.3", 14 | "express": "4.14.0", 15 | "jade": "1.11.0", 16 | "morgan": "1.7.0", 17 | "nodemon": "1.11.0", 18 | "serve-favicon": "2.3.2", 19 | "socket.io": "1.3.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | {"Name": "lotti | pong"} -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | #container { 6 | position: relative; 7 | width: 480px; 8 | height: 480px; 9 | margin: 0 auto; 10 | } 11 | #connect { 12 | width: 320px; 13 | height: 320px; 14 | background-color: #777777; 15 | position: absolute; 16 | margin: auto; 17 | top: 0; 18 | bottom: 0; 19 | left: 0; 20 | right: 0; 21 | text-align: center; 22 | } 23 | #connect table { 24 | width: 100%; 25 | height: 100%; 26 | padding: 10px; 27 | } 28 | #connect table td { 29 | vertical-align: middle; 30 | text-align: center; 31 | } 32 | #connect table #endContainer td { 33 | vertical-align: bottom; 34 | text-align: center; 35 | } 36 | #game { 37 | width: 100%; 38 | height: 100%; 39 | } 40 | .button { 41 | width: 200px; 42 | height: 100px; 43 | font-size: 24px; 44 | text-align: center; 45 | border: none; 46 | margin: 5px 0px; 47 | } 48 | .hide { 49 | display: none; 50 | } 51 | #qrcode { 52 | text-align: center; 53 | } 54 | #qrcode img { 55 | display: inline !important; 56 | } 57 | -------------------------------------------------------------------------------- /public/css/style.less: -------------------------------------------------------------------------------- 1 | * { 2 | margin:0; 3 | padding:0; 4 | } 5 | 6 | #container { 7 | position: relative; 8 | width: 480px; 9 | height: 480px; 10 | margin: 0 auto; 11 | } 12 | 13 | #connect { 14 | width: 320px; 15 | height: 320px; 16 | background-color: #777777; 17 | 18 | position: absolute; 19 | margin: auto; 20 | top: 0; 21 | bottom: 0; 22 | left: 0; 23 | right: 0; 24 | 25 | text-align: center; 26 | 27 | table { 28 | width: 100%; 29 | height: 100%; 30 | padding: 10px; 31 | } 32 | 33 | table { 34 | td { 35 | vertical-align: middle; 36 | text-align: center; 37 | } 38 | #endContainer td { 39 | vertical-align: bottom; 40 | text-align: center; 41 | } 42 | } 43 | } 44 | 45 | #game { 46 | width: 100%; 47 | height: 100%; 48 | } 49 | 50 | .button { 51 | width: 200px; 52 | height: 100px; 53 | font-size: 24px; 54 | text-align: center; 55 | border: none; 56 | margin: 5px 0px; 57 | } 58 | 59 | .hide { 60 | display: none; 61 | } 62 | 63 | #qrcode { 64 | text-align: center; 65 | 66 | img { 67 | display: inline !important; 68 | } 69 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pong 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
or use game id:
24 | Waiting for players... (1/4) 25 |
34 |
35 |
36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /public/js/form.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | var hash = false; 3 | if (window.location.hash.length > 0) { 4 | hash = window.location.hash.substr(1); 5 | } 6 | 7 | var pong = new Pong(); 8 | var socket = pong.getSocket(); 9 | 10 | $("#buttonsContainer").removeClass("hide"); 11 | 12 | $("#hostGame").click(function () { 13 | $("#buttonsContainer").addClass("hide"); 14 | $("#qrcodeContainer").removeClass("hide"); 15 | 16 | var $playersCount= $("#playersCount"); 17 | 18 | socket.on('joined', function(data) { 19 | data.playersCount = parseInt(data.playersCount); 20 | 21 | if ($playersCount.length > 0) { 22 | $playersCount.text(data.playersCount); 23 | } 24 | if (data.playersCount == 4) { 25 | $("#connect").addClass("hide"); 26 | pong.sync({ hosting: true, playersCount: data.playersCount }); 27 | } 28 | }); 29 | socket.on('playerLeft', function (data) { 30 | data.playersCount = parseInt(data.playersCount); 31 | 32 | if ($playersCount.length > 0) { 33 | $playersCount.text(data.playersCount); 34 | } 35 | if (data.playersCount == 4) { 36 | $("#connect").addClass("hide"); 37 | pong.sync({ hosting: true, playersCount: data.playersCount }); 38 | } 39 | }); 40 | socket.emit('host', '', function(data) { 41 | new QRCode(document.getElementById("qrcode"), 42 | { 43 | text: window.location.href+"#"+data, 44 | width: 245, 45 | height: 245 46 | }); 47 | $("#gameId").text(data); 48 | }); 49 | }); 50 | 51 | $("#joinGame").click(function () { 52 | $("#buttonsContainer").addClass("hide"); 53 | $("#formContainer").removeClass("hide"); 54 | 55 | if (hash.length > 0) { 56 | $("#inputGameId").val(hash); 57 | } 58 | $("#inputGameId").select(); 59 | }); 60 | 61 | $("#joinGameId").click(function () { 62 | $("#connect").addClass("hide"); 63 | 64 | socket.emit('join', $("#inputGameId").val().trim(), function(data) { 65 | pong.sync({ hosting: false, playersCount: parseInt(data.playersCount) }); 66 | }); 67 | }); 68 | 69 | $("#restartGame").click(function () { 70 | socket.removeAllListeners('disconnect'); 71 | socket.disconnect(); 72 | location.href = location.href.replace(location.hash,""); 73 | }); 74 | 75 | if (hash.length > 0) { 76 | $("#joinGame").trigger('click'); 77 | } 78 | }); -------------------------------------------------------------------------------- /public/js/game.js: -------------------------------------------------------------------------------- 1 | function Pong() { 2 | var self = this; 3 | var socket = io(); 4 | socket.on('disconnect', function(data) { 5 | var msg = 'Connection loss :\\'; 6 | console.error(msg+"\n"+data); 7 | window.alert(msg+"\n"+data); 8 | location.href = location.href.replace(location.hash,""); 9 | }); 10 | socket.on('error', function(data) { 11 | console.error(data); 12 | window.alert(data); 13 | location.href = location.href.replace(location.hash,""); 14 | }); 15 | socket.on('errorMsg', function(data) { 16 | console.error("[Error:"+data.num+"] "+data.msg); 17 | window.alert("Error "+data.num+"\n"+data.msg); 18 | location.href = location.href.replace(location.hash,""); 19 | }); 20 | 21 | var pingTime; 22 | var ping; 23 | socket.on('pong', function () { 24 | latency = Date.now() - pingTime; 25 | ping = latency; 26 | }); 27 | 28 | function measurePing() { 29 | setTimeout(function () { 30 | pingTime = Date.now(); 31 | socket.emit('ping'); 32 | measurePing(); 33 | }, 2000); 34 | } 35 | measurePing(); 36 | 37 | var debug = false; 38 | 39 | var gameDiv = "game"; 40 | var gameWidth = parseInt(document.getElementById(gameDiv).offsetWidth); 41 | var gameHeight = parseInt(document.getElementById(gameDiv).offsetHeight); 42 | 43 | var game = new Phaser.Game(gameWidth, gameHeight, debug ? Phaser.CANVAS : Phaser.AUTO, gameDiv, null, false, false); 44 | 45 | var host = false; 46 | var paddles = []; 47 | var sprites; 48 | var ball; 49 | 50 | var currentPlayer = -1; 51 | var master = false; 52 | var cursors; 53 | 54 | var colors = ["ff0000", "00ff00", "0000ff", "ffff00"]; 55 | 56 | var ballSize = 10; 57 | var halfBallSize = ballSize / 2; 58 | var padSize = 8; 59 | var halfPadSize = padSize / 2; 60 | var moveFactor = 5; 61 | var maxScore = 10; 62 | 63 | function demoMovements(inactivePlayers) { 64 | if (inactivePlayers == undefined) { 65 | inactivePlayers = {0:true, 1:true, 2:true, 3:true}; 66 | } 67 | 68 | for (var i in paddles) { 69 | if (!inactivePlayers[i]) { 70 | continue; 71 | } 72 | 73 | var p = paddles[i]; 74 | var pH2 = p.body.height/2; 75 | var pW2 = p.body.width/2; 76 | switch (parseInt(i)) { 77 | case 0: 78 | case 2: 79 | if (ball.body.x >= pW2 && ball.body.x <= game.world.width - pW2) { 80 | p.position.x = ball.position.x; 81 | } 82 | break; 83 | case 1: 84 | case 3: 85 | if (ball.body.y >= pH2 && ball.body.y <= game.world.height - pH2) { 86 | p.position.y = ball.position.y; 87 | } 88 | break; 89 | } 90 | } 91 | } 92 | 93 | var BootState = { 94 | preload: function () { 95 | game.load.image('loadingBar', 'res/textures/loading.png'); 96 | }, 97 | create: function () { 98 | game.state.start('preload'); 99 | } 100 | }; 101 | 102 | var LoadingState = { 103 | preload: function () { 104 | game.stage.disableVisibilityChange = true; 105 | 106 | this.loadingBar = game.add.sprite(0, 0, 'loadingBar'); 107 | // Center the preload bar 108 | this.loadingBar.x = game.world.centerX - this.loadingBar.width / 2; 109 | this.loadingBar.y = game.world.centerY - this.loadingBar.height / 2; 110 | game.load.setPreloadSprite(this.loadingBar); 111 | 112 | game.load.image('pixel', 'res/sprites/pixel.png'); 113 | }, 114 | create: function () { 115 | this.loadingBar.destroy(); 116 | 117 | game.physics.startSystem(Phaser.Physics.ARCADE); 118 | 119 | sprites = game.add.group(); 120 | 121 | ball = sprites.create(game.world.centerX - halfBallSize, game.world.centerY - halfBallSize, 'pixel'); 122 | ball.name = 'ball'; 123 | ball.scale.setTo(ballSize, ballSize); 124 | ball.anchor.setTo(0.5, 0.5); 125 | 126 | game.physics.enable([ball], Phaser.Physics.ARCADE); 127 | var sign = game.rnd.integerInRange(0,1) == 0 ? 1 : -1; 128 | ball.body.velocity.x = game.rnd.integerInRange(100, 250) * sign; 129 | ball.body.velocity.y = game.rnd.integerInRange(100, 250) * sign; 130 | ball.body.bounce.x = 1; 131 | ball.body.bounce.y = 1; 132 | ball.body.minBounceVelocity = 0; 133 | ball.player = -1; 134 | 135 | paddles = []; 136 | paddles.push(sprites.create(game.world.centerX - halfPadSize, halfPadSize, 'pixel')); 137 | paddles.push(sprites.create(halfPadSize, game.world.height / 2 - halfPadSize, 'pixel')); 138 | paddles.push(sprites.create(game.world.centerX - halfPadSize, game.world.height - halfPadSize, 'pixel')); 139 | paddles.push(sprites.create(game.world.width - halfPadSize, game.world.centerY - halfPadSize, 'pixel')); 140 | 141 | paddles[0].tint = 0xff0000; 142 | paddles[1].tint = 0x00ff00; 143 | paddles[2].tint = 0x0000ff; 144 | paddles[3].tint = 0xffff00; 145 | 146 | for (var i in paddles) { 147 | paddles[i].op = paddles[i].position; 148 | paddles[i].player = i; 149 | paddles[i].name = 'Player' + (parseInt(i) + 1); 150 | if (i % 2 == 0) { 151 | paddles[i].scale.setTo(padSize*10, 10); 152 | } 153 | else { 154 | paddles[i].scale.setTo(10, padSize*10); 155 | } 156 | paddles[i].anchor.setTo(0.5, 0.5); 157 | game.physics.enable([ paddles[i] ], Phaser.Physics.ARCADE); 158 | paddles[i].body.bounce.x = 1; 159 | paddles[i].body.bounce.y = 1; 160 | paddles[i].body.minBounceVelocity = 0; 161 | paddles[i].body.immovable = true; 162 | paddles[i].body.collideWorldBounds = true; 163 | } 164 | }, 165 | update: function () { 166 | game.physics.arcade.collide(ball, paddles, function (ball, player) { 167 | ball.tint = player.tint; 168 | }); 169 | 170 | demoMovements(); 171 | } 172 | }; 173 | 174 | var SynchState = { 175 | p: false, 176 | players: 0, 177 | countdown: false, 178 | init: function (data) { 179 | game.stage.disableVisibilityChange = true; 180 | 181 | var self = this; 182 | 183 | self.players = parseInt(data.playersCount); 184 | if (data.hosting) { 185 | self.p = 0; 186 | host = true; 187 | socket.emit('startCounting', socket.id); 188 | } 189 | else { 190 | self.p = data.playersCount -1; 191 | socket.on('joined', function (data) { 192 | self.players = parseInt(data.playersCount); 193 | }); 194 | socket.on('playerLeft', function (data) { 195 | self.players = parseInt(data.playersCount); 196 | }); 197 | } 198 | socket.on('timeOut', function(data, ack) { 199 | self.countdown = parseInt(data.times); 200 | ack(socket.id); 201 | }); 202 | }, 203 | preload: function () { 204 | cursors = game.input.keyboard.createCursorKeys(); 205 | }, 206 | create: function () { 207 | var style = {font: "30px Arial", fill: "#ffffff", align: "center"}; 208 | this.text = game.add.text(game.world.centerX, game.world.centerY, "Awaiting other players (" + this.players + "/4)", style); 209 | this.text.anchor.setTo(0.5, 0.5); 210 | }, 211 | update: function () { 212 | game.physics.arcade.collide(ball, paddles, function (ball, player) { 213 | ball.tint = player.tint; 214 | }); 215 | 216 | if (this.countdown === false) { 217 | demoMovements(); 218 | } 219 | else { 220 | this.initGame(this.countdown); 221 | } 222 | 223 | if (this.countdown !== false) { 224 | this.text.text = "Ready to start..."; 225 | } 226 | else if (host || this.players == 4) { 227 | this.text.text = "Waiting for sync..."; 228 | } 229 | else { 230 | this.text.text = "Awaiting other players (" + this.players + "/4)"; 231 | } 232 | }, 233 | initGame: function(phase) { 234 | switch(phase) { 235 | case 1: 236 | ball.position.setTo(game.world.width / 2, game.world.height / 2); 237 | ball.tint = 0xffffff; 238 | ball.player = -1; 239 | ball.body.velocity.x = 0; 240 | ball.body.velocity.y = 0; 241 | case 2: 242 | for (var i in paddles) { 243 | paddles[i].position.setTo(paddles[i].op.x,paddles[i].op.y); 244 | } 245 | this.text.text = "GO!"; 246 | case 3: 247 | socket.removeAllListeners('joined'); 248 | socket.removeAllListeners('timeOut'); 249 | socket.removeAllListeners('playerLeft'); 250 | this.text.destroy(); 251 | game.state.start("game", false, false, { player: this.p }); 252 | break; 253 | } 254 | } 255 | }; 256 | 257 | var GameState = { 258 | inactivePlayers: { 0:false, 1:false, 2:false, 3:false }, 259 | gameRunning: false, 260 | init: function (data) { 261 | game.stage.disableVisibilityChange = true; 262 | 263 | var self = this; 264 | currentPlayer = data.player; 265 | master = data.player == 0; 266 | 267 | socket.on('playerLeft', function (data) { 268 | self.inactivePlayers[parseInt(data.playerLeft)] = true; 269 | }); 270 | socket.on('clientUpdate', function(data) { 271 | self.updateClient(data); 272 | }); 273 | socket.on('clientUpdateScores', function(data) { 274 | self.updateClientScores(data); 275 | }); 276 | socket.on('clientUpdateBall', function (data) { 277 | self.updateClientBall(data); 278 | }); 279 | socket.on('becomeHost', function (data) { 280 | master = true; 281 | ball.body.velocity.x = ball.currentSpeedX; 282 | ball.body.velocity.y = ball.currentSpeedY; 283 | }); 284 | }, 285 | create: function () { 286 | if (!master) { 287 | ball.body.velocity.x = 0; 288 | ball.body.velocity.y = 0; 289 | } 290 | else { 291 | var sign = game.rnd.integerInRange(0,1) == 0 ? 1 : -1; 292 | ball.body.velocity.x = game.rnd.integerInRange(100, 250) * sign; 293 | ball.body.velocity.y = game.rnd.integerInRange(100, 250) * sign; 294 | } 295 | 296 | var scoresPos = [ 297 | {w: game.world.centerX, h: game.world.centerY - 100}, 298 | {w: game.world.centerX - 100, h: game.world.centerY}, 299 | {w: game.world.centerX, h: game.world.centerY + 100}, 300 | {w: game.world.centerX + 100, h: game.world.centerY} 301 | ]; 302 | 303 | for (var i in paddles) { 304 | paddles[i].position.setTo(paddles[i].op.x,paddles[i].op.y); 305 | var style = {font: "50px Arial", fill: "#" + colors[i], align: "center"}; 306 | paddles[i].scoreLabel = game.add.text(scoresPos[i].w, scoresPos[i].h, "0", style); 307 | paddles[i].scoreLabel.anchor.setTo(0.5, 0.5); 308 | } 309 | 310 | this.gameRunning = true; 311 | }, 312 | update: function () { 313 | if (this.gameRunning) { 314 | for (var i in paddles) { 315 | if (paddles[i].scoreLabel.text >= maxScore) { 316 | this.endGame(paddles[i]); 317 | return; 318 | } 319 | } 320 | 321 | if (master) { 322 | game.physics.arcade.collide(ball, paddles, function (ball, player) { 323 | ball.tint = player.tint; 324 | ball.player = player.player; 325 | 326 | var data = {socketId: socket.id}; 327 | data['ballTint'] = ball.tint; 328 | socket.emit('gameBall', data); 329 | }); 330 | this.checkScore(); 331 | } 332 | this.inputManagement(); 333 | demoMovements(this.inactivePlayers); 334 | this.updateServer(); 335 | } 336 | }, 337 | checkScore: function () { 338 | if (master) { 339 | var scored = false; 340 | if (ball.body.y < -ball.body.height) { 341 | scored = true; 342 | if (ball.player == -1 || ball.player == 0) { 343 | paddles[0].scoreLabel.text--; 344 | scored = true; 345 | } 346 | else { 347 | paddles[ball.player].scoreLabel.text++; 348 | } 349 | } 350 | else if (ball.body.y > game.world.height + ball.body.height) { 351 | scored = true; 352 | if (ball.player == -1 || ball.player == 2) { 353 | paddles[2].scoreLabel.text--; 354 | } 355 | else { 356 | paddles[ball.player].scoreLabel.text++; 357 | } 358 | } 359 | else if (ball.body.x < -ball.body.width) { 360 | scored = true; 361 | if (ball.player == -1 || ball.player == 1) { 362 | paddles[1].scoreLabel.text--; 363 | } 364 | else { 365 | paddles[ball.player].scoreLabel.text++; 366 | } 367 | } 368 | else if (ball.body.x > game.world.width + ball.body.width) { 369 | scored = true; 370 | if (ball.player == -1 || ball.player == 3) { 371 | paddles[3].scoreLabel.text--; 372 | } 373 | else { 374 | paddles[ball.player].scoreLabel.text++; 375 | } 376 | } 377 | 378 | if (scored) { //reset ball position 379 | var data = { socketId: socket.id }; 380 | data['scores'] = []; 381 | for(var i in paddles) { 382 | data['scores'].push(parseInt(paddles[i].scoreLabel.text)); 383 | } 384 | socket.emit('gameScores', data); 385 | 386 | ball.body.position.setTo(game.world.centerX, game.world.centerY); 387 | ball.player = -1; 388 | ball.tint = 0xffffff; 389 | 390 | var sign = game.rnd.integerInRange(0,1) == 0 ? 1 : -1; 391 | ball.body.velocity.x = game.rnd.integerInRange(100, 250) * sign; 392 | ball.body.velocity.y = game.rnd.integerInRange(100, 250) * sign; 393 | } 394 | } 395 | }, 396 | inputManagement: function () { 397 | var p = paddles[currentPlayer]; 398 | 399 | if (cursors.left.isDown || cursors.up.isDown) { 400 | switch (currentPlayer) { 401 | case 0: 402 | case 2: 403 | p.position.x -= moveFactor; 404 | break; 405 | case 1: 406 | case 3: 407 | p.position.y -= moveFactor; 408 | break; 409 | } 410 | } 411 | else if (cursors.right.isDown || cursors.down.isDown) { 412 | switch (currentPlayer) { 413 | case 0: 414 | case 2: 415 | p.position.x += moveFactor; 416 | break; 417 | case 1: 418 | case 3: 419 | p.position.y += moveFactor; 420 | break; 421 | } 422 | } 423 | else { 424 | switch (currentPlayer) { 425 | case 0: case 2: 426 | if (game.input.activePointer.x >= paddles[currentPlayer].position.x + moveFactor) { 427 | p.position.x += moveFactor; 428 | } 429 | else if (game.input.activePointer.x <= paddles[currentPlayer].position.x - moveFactor) { 430 | p.position.x -= moveFactor; 431 | } 432 | break; 433 | case 1: case 3: 434 | if (game.input.activePointer.y >= paddles[currentPlayer].position.y + moveFactor) { 435 | p.position.y += moveFactor; 436 | } 437 | else if (game.input.activePointer.y <= paddles[currentPlayer].position.y - moveFactor) { 438 | p.position.y -= moveFactor; 439 | } 440 | break; 441 | } 442 | } 443 | 444 | var pH2 = p.body.height/2; 445 | var pW2 = p.body.width/2; 446 | switch (currentPlayer) { 447 | case 0: case 2: 448 | if (p.position.x < pW2) { 449 | p.position.x = pW2; 450 | } 451 | else if (p.position.x > game.world.width - pW2) { 452 | p.position.x = game.world.width - pW2; 453 | } 454 | break; 455 | case 1: case 3: 456 | if (p.position.y < pH2) { 457 | p.position.y = pH2; 458 | } 459 | else if (p.position.y > game.world.height - pH2) { 460 | p.position.y = game.world.height - pH2; 461 | } 462 | break; 463 | } 464 | }, 465 | endGame: function (player) { 466 | this.gameRunning = false; 467 | 468 | for (var i in paddles) { 469 | paddles[i].scoreLabel.destroy(); 470 | paddles[i].destroy(); 471 | } 472 | 473 | ball.destroy(); 474 | var style = {font: "50px Arial", fill: "#ffffff", align: "center"}; 475 | var wonSentence = player.player == currentPlayer ? "You win!" : player.name + " wins!"; 476 | var text = game.add.text(game.world.centerX, game.world.centerY, wonSentence, style); 477 | text.anchor.setTo(0.5, 0.5); 478 | 479 | socket.removeAllListeners('playerLeft'); 480 | socket.removeAllListeners('clientUpdate'); 481 | socket.removeAllListeners('clientUpdateScores'); 482 | socket.removeAllListeners('clientUpdateBall'); 483 | socket.removeAllListeners('becomeHost'); 484 | socket.removeAllListeners('disconnect'); 485 | socket.removeAllListeners('errorMsg'); 486 | socket.removeAllListeners('error'); 487 | 488 | $("#connect tr").addClass("hide"); 489 | $("#endContainer").removeClass("hide"); 490 | $("#connect").removeClass("hide").css("background-color", "transparent"); 491 | 492 | setTimeout(function() { 493 | socket.disconnect(); 494 | }, 5000); 495 | }, 496 | socketTiming: 0, 497 | socketDelay: 16, 498 | getSocketDelay: function() { 499 | return ping < this.socketDelay ? ping : this.socketDelay; 500 | }, 501 | updateServer: function () { 502 | this.socketTiming+=game.time.elapsed; 503 | if (this.socketTiming < this.getSocketDelay()) { 504 | return; 505 | } 506 | this.socketTiming = 0; 507 | var data = { socketId: socket.id }; 508 | 509 | if (master) { 510 | data['ball'] = true; 511 | data['ballX'] = parseFloat(ball.position.x).toFixed(2); 512 | data['ballY'] = parseFloat(ball.position.y).toFixed(2); 513 | data['ballSpeedX'] = parseFloat(ball.body.velocity.x).toFixed(2); 514 | data['ballSpeedY'] = parseFloat(ball.body.velocity.y).toFixed(2); 515 | } 516 | else { 517 | data['ball'] = false; 518 | } 519 | 520 | data['player'] = parseInt(currentPlayer); 521 | switch(data['player']) { 522 | case 0: 523 | case 2: 524 | data['paddle'] = parseFloat(paddles[currentPlayer].position.x).toFixed(2); 525 | break; 526 | case 1: 527 | case 3: 528 | data['paddle'] = parseFloat(paddles[currentPlayer].position.y).toFixed(2); 529 | break; 530 | } 531 | 532 | socket.emit('gameUpdate', data); 533 | }, 534 | updateClient: function (data) { 535 | if (!master && data.ball == true) { 536 | ball.position.x = parseFloat(data.ballX); 537 | ball.position.y = parseFloat(data.ballY); 538 | ball.currentSpeedX = parseFloat(data.ballSpeedX); 539 | ball.currentSpeedY = parseFloat(data.ballSpeedY); 540 | } 541 | 542 | if (currentPlayer != data.player) { 543 | switch(parseInt(data.player)) { 544 | case 0: 545 | case 2: 546 | paddles[data.player].position.x = parseFloat(data.paddle); 547 | break; 548 | case 1: 549 | case 3: 550 | paddles[data.player].position.y = parseFloat(data.paddle); 551 | break; 552 | } 553 | } 554 | }, 555 | updateClientScores: function(data) { 556 | if (!master) { 557 | ball.tint = 0xffffff; 558 | for(var i in data.scores) { 559 | paddles[i].scoreLabel.text = parseInt(data.scores[i]); 560 | } 561 | } 562 | }, 563 | updateClientBall: function(data) { 564 | if (!master) { 565 | ball.tint = data.ballTint; 566 | } 567 | }, 568 | render: function () { 569 | if (debug) { 570 | game.debug.body(ball); 571 | for (var i in paddles) { 572 | game.debug.body(paddles[i]); 573 | } 574 | } 575 | } 576 | }; 577 | 578 | game.state.add("boot", BootState, true); 579 | game.state.add("preload", LoadingState, false); 580 | game.state.add("sync", SynchState, false); 581 | game.state.add("game", GameState, false); 582 | 583 | this.switchToSync = function(data) { 584 | game.state.start("sync", false, false, data); 585 | }; 586 | 587 | this.getSocket = function() { 588 | return socket; 589 | }; 590 | 591 | return this; 592 | } 593 | 594 | Pong.prototype.getSocket = function () { 595 | return this.getSocket(); 596 | }; 597 | Pong.prototype.sync = function(data) { 598 | this.switchToSync(data); 599 | }; -------------------------------------------------------------------------------- /public/js/vendors/phaser/ninja.min.js: -------------------------------------------------------------------------------- 1 | /* Ninja Physics for Phaser v2.2.2 - http://phaser.io - @photonstorm - (c) 2014 Photon Storm Ltd. */ 2 | Phaser.Physics.Ninja=function(a){this.game=a,this.time=this.game.time,this.gravity=.2,this.bounds=new Phaser.Rectangle(0,0,a.world.width,a.world.height),this.maxObjects=10,this.maxLevels=4,this.quadTree=new Phaser.QuadTree(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.setBoundsToWorld()},Phaser.Physics.Ninja.prototype.constructor=Phaser.Physics.Ninja,Phaser.Physics.Ninja.prototype={enableAABB:function(a,b){this.enable(a,1,0,0,b)},enableCircle:function(a,b,c){this.enable(a,2,0,b,c)},enableTile:function(a,b,c){this.enable(a,3,b,0,c)},enable:function(a,b,c,d,e){if("undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=0),"undefined"==typeof e&&(e=!0),Array.isArray(a))for(var f=a.length;f--;)a[f]instanceof Phaser.Group?this.enable(a[f].children,b,c,d,e):(this.enableBody(a[f],b,c,d),e&&a[f].hasOwnProperty("children")&&a[f].children.length>0&&this.enable(a[f],b,c,d,!0));else a instanceof Phaser.Group?this.enable(a.children,b,c,d,e):(this.enableBody(a,b,c,d),e&&a.hasOwnProperty("children")&&a.children.length>0&&this.enable(a.children,b,c,d,!0))},enableBody:function(a,b,c,d){a.hasOwnProperty("body")&&null===a.body&&(a.body=new Phaser.Physics.Ninja.Body(this,a,b,c,d),a.anchor.set(.5))},setBounds:function(a,b,c,d){this.bounds.setTo(a,b,c,d)},setBoundsToWorld:function(){this.bounds.setTo(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height)},clearTilemapLayerBodies:function(a,b){b=a.getLayer(b);for(var c=a.layers[b].bodies.length;c--;)a.layers[b].bodies[c].destroy();a.layers[b].bodies.length=[]},convertTilemap:function(a,b,c){b=a.getLayer(b),this.clearTilemapLayerBodies(a,b);for(var d=0,e=a.layers[b].height;e>d;d++)for(var f=0,g=a.layers[b].width;g>f;f++){var h=a.layers[b].data[d][f];if(h&&c.hasOwnProperty(h.index)){var i=new Phaser.Physics.Ninja.Body(this,null,3,c[h.index],0,h.worldX+h.centerX,h.worldY+h.centerY,h.width,h.height);a.layers[b].bodies.push(i)}}return a.layers[b].bodies},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,b,c,d,e,f){return"undefined"!=typeof b||a.type!==Phaser.GROUP&&a.type!==Phaser.EMITTER?void(a&&b&&a.exists&&b.exists&&(a.type==Phaser.SPRITE||a.type==Phaser.TILESPRITE?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsSprite(a,b,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideSpriteVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,b,c,d,e):a.type==Phaser.GROUP?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsGroup(b,a,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideGroupVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,d,e):a.type==Phaser.TILEMAPLAYER?b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsTilemapLayer(b,a,c,d,e):(b.type==Phaser.GROUP||b.type==Phaser.EMITTER)&&this.collideGroupVsTilemapLayer(b,a,c,d,e):a.type==Phaser.EMITTER&&(b.type==Phaser.SPRITE||b.type==Phaser.TILESPRITE?this.collideSpriteVsGroup(b,a,c,d,e,f):b.type==Phaser.GROUP||b.type==Phaser.EMITTER?this.collideGroupVsGroup(a,b,c,d,e,f):b.type==Phaser.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,d,e)))):void this.collideGroupVsSelf(a,c,d,e,f)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,b,c,d,e,f){if(0!==b.length)for(var g=0,h=b.children.length;h>g;g++)b.children[g].exists&&b.children[g].body&&this.separate(a.body,b.children[g].body,d,e,f)&&(c&&c.call(e,a,b.children[g]),this._total++)},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a.children[g]&&a.children[h]&&a.children[g].exists&&a.children[h].exists&&this.collideSpriteVsSprite(a.children[g],a.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length)for(var g=0,h=a.children.length;h>g;g++)a.children[g].exists&&this.collideSpriteVsGroup(a.children[g],b,c,d,e,f)},separate:function(a,b){return a.type!==Phaser.Physics.NINJA||b.type!==Phaser.Physics.NINJA?!1:a.aabb&&b.aabb?a.aabb.collideAABBVsAABB(b.aabb):a.aabb&&b.tile?a.aabb.collideAABBVsTile(b.tile):a.tile&&b.aabb?b.aabb.collideAABBVsTile(a.tile):a.circle&&b.tile?a.circle.collideCircleVsTile(b.tile):a.tile&&b.circle?b.circle.collideCircleVsTile(a.tile):void 0}},Phaser.Physics.Ninja.Body=function(a,b,c,d,e,f,g,h,i){b=b||null,"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1),"undefined"==typeof e&&(e=16),this.sprite=b,this.game=a.game,this.type=Phaser.Physics.NINJA,this.system=a,this.aabb=null,this.tile=null,this.circle=null,this.shape=null,this.drag=1,this.friction=.05,this.gravityScale=1,this.bounce=.3,this.velocity=new Phaser.Point,this.facing=Phaser.NONE,this.immovable=!1,this.collideWorldBounds=!0,this.checkCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.maxSpeed=8,b&&(f=b.x,g=b.y,h=b.width,i=b.height,0===b.anchor.x&&(f+=.5*b.width),0===b.anchor.y&&(g+=.5*b.height)),1===c?(this.aabb=new Phaser.Physics.Ninja.AABB(this,f,g,h,i),this.shape=this.aabb):2===c?(this.circle=new Phaser.Physics.Ninja.Circle(this,f,g,e),this.shape=this.circle):3===c&&(this.tile=new Phaser.Physics.Ninja.Tile(this,f,g,h,i,d),this.shape=this.tile)},Phaser.Physics.Ninja.Body.prototype={preUpdate:function(){this.wasTouching.none=this.touching.none,this.wasTouching.up=this.touching.up,this.wasTouching.down=this.touching.down,this.wasTouching.left=this.touching.left,this.wasTouching.right=this.touching.right,this.touching.none=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.shape.integrate(),this.collideWorldBounds&&this.shape.collideWorldBounds()},postUpdate:function(){this.sprite&&(this.sprite.type===Phaser.TILESPRITE?(this.sprite.x=this.shape.pos.x-this.shape.xw,this.sprite.y=this.shape.pos.y-this.shape.yw):(this.sprite.x=this.shape.pos.x,this.sprite.y=this.shape.pos.y)),this.velocity.x<0?this.facing=Phaser.LEFT:this.velocity.x>0&&(this.facing=Phaser.RIGHT),this.velocity.y<0?this.facing=Phaser.UP:this.velocity.y>0&&(this.facing=Phaser.DOWN)},setZeroVelocity:function(){this.shape.oldpos.x=this.shape.pos.x,this.shape.oldpos.y=this.shape.pos.y},moveTo:function(a,b){var c=a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveFrom:function(a,b){var c=-a*this.game.time.physicsElapsed,b=this.game.math.degToRad(b);this.shape.pos.x=this.shape.oldpos.x+c*Math.cos(b),this.shape.pos.y=this.shape.oldpos.y+c*Math.sin(b)},moveLeft:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveRight:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.x=this.shape.oldpos.x+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.x-this.shape.oldpos.x+b))},moveUp:function(a){var b=-a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},moveDown:function(a){var b=a*this.game.time.physicsElapsed;this.shape.pos.y=this.shape.oldpos.y+Math.min(this.maxSpeed,Math.max(-this.maxSpeed,this.shape.pos.y-this.shape.oldpos.y+b))},reset:function(){this.velocity.set(0),this.shape.pos.x=this.sprite.x,this.shape.pos.y=this.sprite.y,this.shape.oldpos.copyFrom(this.shape.pos)},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaX:function(){return this.shape.pos.x-this.shape.oldpos.x},deltaY:function(){return this.shape.pos.y-this.shape.oldpos.y},destroy:function(){this.sprite=null,this.system=null,this.aabb=null,this.tile=null,this.circle=null,this.shape.destroy(),this.shape=null}},Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"x",{get:function(){return this.shape.pos.x},set:function(a){this.shape.pos.x=a}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"y",{get:function(){return this.shape.pos.y},set:function(a){this.shape.pos.y=a}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"width",{get:function(){return this.shape.width}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"height",{get:function(){return this.shape.height}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"bottom",{get:function(){return this.shape.pos.y+this.shape.yw}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"right",{get:function(){return this.shape.pos.x+this.shape.xw}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"speed",{get:function(){return Math.sqrt(this.shape.velocity.x*this.shape.velocity.x+this.shape.velocity.y*this.shape.velocity.y)}}),Object.defineProperty(Phaser.Physics.Ninja.Body.prototype,"angle",{get:function(){return Math.atan2(this.shape.velocity.y,this.shape.velocity.x)}}),Phaser.Physics.Ninja.Body.render=function(a,b,c,d){c=c||"rgba(0,255,0,0.4)","undefined"==typeof d&&(d=!0),(b.aabb||b.circle)&&b.shape.render(a,b.game.camera.x,b.game.camera.y,c,d)},Phaser.Physics.Ninja.AABB=function(a,b,c,d,e){this.body=a,this.system=a.system,this.pos=new Phaser.Point(b,c),this.oldpos=new Phaser.Point(b,c),this.xw=Math.abs(d/2),this.yw=Math.abs(e/2),this.width=d,this.height=e,this.oH=0,this.oV=0,this.velocity=new Phaser.Point,this.aabbTileProjections={},this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_FULL]=this.projAABB_Full,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_45DEG]=this.projAABB_45Deg,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONCAVE]=this.projAABB_Concave,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_CONVEX]=this.projAABB_Convex,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGs]=this.projAABB_22DegS,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_22DEGb]=this.projAABB_22DegB,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGs]=this.projAABB_67DegS,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_67DEGb]=this.projAABB_67DegB,this.aabbTileProjections[Phaser.Physics.Ninja.Tile.TYPE_HALF]=this.projAABB_Half},Phaser.Physics.Ninja.AABB.prototype.constructor=Phaser.Physics.Ninja.AABB,Phaser.Physics.Ninja.AABB.COL_NONE=0,Phaser.Physics.Ninja.AABB.COL_AXIS=1,Phaser.Physics.Ninja.AABB.COL_OTHER=2,Phaser.Physics.Ninja.AABB.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},reverse:function(){var a=this.pos.x-this.oldpos.x,b=this.pos.y-this.oldpos.y;this.oldpos.xthis.pos.x&&(this.oldpos.x=this.pos.x-a),this.oldpos.ythis.pos.y&&(this.oldpos.y=this.pos.y-b)},reportCollisionVsBody:function(a,b,c,d,e){var f=this.pos.x-this.oldpos.x,g=this.pos.y-this.oldpos.y,h=f*c+g*d;return this.body.immovable&&e.body.immovable?(a*=.5,b*=.5,this.pos.add(a,b),this.oldpos.set(this.pos.x,this.pos.y),e.pos.subtract(a,b),void e.oldpos.set(e.pos.x,e.pos.y)):void(this.body.immovable||e.body.immovable?this.body.immovable?e.body.immovable||(e.pos.subtract(a,b),0>h&&e.reverse()):(this.pos.subtract(a,b),0>h&&this.reverse()):(a*=.5,b*=.5,this.pos.add(a,b),e.pos.subtract(a,b),0>h&&(this.reverse(),e.reverse())))},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.right,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.bottom,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideAABBVsAABB:function(a){var b=this.pos,c=a,d=c.pos.x,e=c.pos.y,f=c.xw,g=c.yw,h=b.x-d,i=f+this.xw-Math.abs(h);if(i>0){var j=b.y-e,k=g+this.yw-Math.abs(j);if(k>0){k>i?0>h?(i*=-1,k=0):k=0:0>j?(i=0,k*=-1):i=0;var l=Math.sqrt(i*i+k*k);return this.reportCollisionVsBody(i,k,i/l,k/l,c),Phaser.Physics.Ninja.AABB.COL_AXIS}}return!1},collideAABBVsTile:function(a){var b=this.pos.x-a.pos.x,c=a.xw+this.xw-Math.abs(b);if(c>0){var d=this.pos.y-a.pos.y,e=a.yw+this.yw-Math.abs(d);if(e>0)return e>c?0>b?(c*=-1,e=0):e=0:0>d?(c=0,e*=-1):c=0,this.resolveTile(c,e,this,a)}return!1},resolveTile:function(a,b,c,d){return 0i){e*=-i,f*=-i;var j=Math.sqrt(e*e+f*f),k=Math.sqrt(a*a+b*b);return j>k?(c.reportCollisionVsWorld(a,b,a/k,b/k,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(e,f,d.signx,d.signy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_45Deg:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-d.pos.x,h=c.pos.y-f*c.yw-d.pos.y,i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_22DegS:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.y-f*c.yw,h=d.pos.y-g;if(h*f>0){var i=c.pos.x-e*c.xw-(d.pos.x+e*d.xw),j=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),k=d.sx,l=d.sy,m=i*k+j*l;if(0>m){k*=-m,l*=-m;var n=Math.sqrt(k*k+l*l),o=Math.sqrt(a*a+b*b),p=Math.abs(h);return n>o?o>p?(c.reportCollisionVsWorld(0,h,0,h/p,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(a,b,a/o,b/o,d),Phaser.Physics.Ninja.AABB.COL_AXIS):n>p?(c.reportCollisionVsWorld(0,h,0,h/p,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(k,l,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_22DegB:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y+f*d.yw),i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_67DegS:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw,h=d.pos.x-g;if(h*e>0){var i=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),j=c.pos.y-f*c.yw-(d.pos.y+f*d.yw),k=d.sx,l=d.sy,m=i*k+j*l;if(0>m){k*=-m,l*=-m;var n=Math.sqrt(k*k+l*l),o=Math.sqrt(a*a+b*b),p=Math.abs(h);return n>o?o>p?(c.reportCollisionVsWorld(h,0,h/p,0,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(a,b,a/o,b/o,d),Phaser.Physics.Ninja.AABB.COL_AXIS):n>p?(c.reportCollisionVsWorld(h,0,h/p,0,d),Phaser.Physics.Ninja.AABB.COL_OTHER):(c.reportCollisionVsWorld(k,l,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_67DegB:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x+e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),i=d.sx,j=d.sy,k=g*i+h*j;if(0>k){i*=-k,j*=-k;var l=Math.sqrt(i*i+j*j),m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(c.reportCollisionVsWorld(i,j,d.sx,d.sy,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_Convex:function(a,b,c,d){var e=d.signx,f=d.signy,g=c.pos.x-e*c.xw-(d.pos.x-e*d.xw),h=c.pos.y-f*c.yw-(d.pos.y-f*d.yw),i=Math.sqrt(g*g+h*h),j=2*d.xw,k=Math.sqrt(j*j+0),l=k-i;if(0>e*g||0>f*h){var m=Math.sqrt(a*a+b*b);return c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS}return l>0?(g/=i,h/=i,c.reportCollisionVsWorld(g*l,h*l,g,h,d),Phaser.Physics.Ninja.AABB.COL_OTHER):Phaser.Physics.Ninja.AABB.COL_NONE},projAABB_Concave:function(a,b,c,d){var e=d.signx,f=d.signy,g=d.pos.x+e*d.xw-(c.pos.x-e*c.xw),h=d.pos.y+f*d.yw-(c.pos.y-f*c.yw),i=2*d.xw,j=Math.sqrt(i*i+0),k=Math.sqrt(g*g+h*h),l=k-j;if(l>0){var m=Math.sqrt(a*a+b*b);return l>m?(c.reportCollisionVsWorld(a,b,a/m,b/m,d),Phaser.Physics.Ninja.AABB.COL_AXIS):(g/=k,h/=k,c.reportCollisionVsWorld(g*l,h*l,g,h,d),Phaser.Physics.Ninja.AABB.COL_OTHER)}return Phaser.Physics.Ninja.AABB.COL_NONE},destroy:function(){this.body=null,this.system=null},render:function(a,b,c,d,e){var f=this.pos.x-this.xw-b,g=this.pos.y-this.yw-c;e?(a.fillStyle=d,a.fillRect(f,g,this.width,this.height)):(a.strokeStyle=d,a.strokeRect(f,g,this.width,this.height))}},Phaser.Physics.Ninja.Tile=function(a,b,c,d,e,f){"undefined"==typeof f&&(f=Phaser.Physics.Ninja.Tile.EMPTY),this.body=a,this.system=a.system,this.id=f,this.type=Phaser.Physics.Ninja.Tile.TYPE_EMPTY,this.pos=new Phaser.Point(b,c),this.oldpos=new Phaser.Point(b,c),this.id>1&&this.id<30&&(e=d),this.xw=Math.abs(d/2),this.yw=Math.abs(e/2),this.width=d,this.height=e,this.velocity=new Phaser.Point,this.signx=0,this.signy=0,this.sx=0,this.sy=0,this.body.gravityScale=0,this.body.collideWorldBounds=!1,this.id>0&&this.setType(this.id)},Phaser.Physics.Ninja.Tile.prototype.constructor=Phaser.Physics.Ninja.Tile,Phaser.Physics.Ninja.Tile.prototype={integrate:function(){var a=this.pos.x,b=this.pos.y;this.pos.x+=this.body.drag*this.pos.x-this.body.drag*this.oldpos.x,this.pos.y+=this.body.drag*this.pos.y-this.body.drag*this.oldpos.y+this.system.gravity*this.body.gravityScale,this.velocity.set(this.pos.x-a,this.pos.y-b),this.oldpos.set(a,b)},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.xw);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.xw-this.system.bounds.right,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.yw);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.yw-this.system.bounds.bottom,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},reportCollisionVsWorld:function(a,b,c,d){var e,f,g,h,i,j=this.pos,k=this.oldpos,l=j.x-k.x,m=j.y-k.y,n=l*c+m*d,o=n*c,p=n*d,q=l-o,r=m-p;0>n?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},setType:function(a){return a===Phaser.Physics.Ninja.Tile.EMPTY?this.clear():(this.id=a,this.updateType()),this},clear:function(){this.id=Phaser.Physics.Ninja.Tile.EMPTY,this.updateType()},destroy:function(){this.body=null,this.system=null},updateType:function(){if(0===this.id)return this.type=Phaser.Physics.Ninja.Tile.TYPE_EMPTY,this.signx=0,this.signy=0,this.sx=0,this.sy=0,!0;if(this.idn?(h=q*this.body.friction,i=r*this.body.friction,e=1+this.body.bounce,f=o*e,g=p*e,1===c?this.body.touching.left=!0:-1===c&&(this.body.touching.right=!0),1===d?this.body.touching.up=!0:-1===d&&(this.body.touching.down=!0)):f=g=h=i=0,j.x+=a,j.y+=b,k.x+=a+f+h,k.y+=b+g+i},collideWorldBounds:function(){var a=this.system.bounds.x-(this.pos.x-this.radius);a>0?this.reportCollisionVsWorld(a,0,1,0,null):(a=this.pos.x+this.radius-this.system.bounds.right,a>0&&this.reportCollisionVsWorld(-a,0,-1,0,null));var b=this.system.bounds.y-(this.pos.y-this.radius);b>0?this.reportCollisionVsWorld(0,b,0,1,null):(b=this.pos.y+this.radius-this.system.bounds.bottom,b>0&&this.reportCollisionVsWorld(0,-b,0,-1,null))},collideCircleVsTile:function(a){var b=this.pos,c=this.radius,d=a,e=d.pos.x,f=d.pos.y,g=d.xw,h=d.yw,i=b.x-e,j=g+c-Math.abs(i);if(j>0){var k=b.y-f,l=h+c-Math.abs(k);if(l>0)return this.oH=0,this.oV=0,-g>i?this.oH=-1:i>g&&(this.oH=1),-h>k?this.oV=-1:k>h&&(this.oV=1),this.resolveCircleTile(j,l,this.oH,this.oV,this,d)}},resolveCircleTile:function(a,b,c,d,e,f){return 0a){var g=e.pos.x-f.pos.x;return 0>g?(e.reportCollisionVsWorld(-a,0,-1,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(a,0,1,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS)}var h=e.pos.y-f.pos.y;return 0>h?(e.reportCollisionVsWorld(0,-b,0,-1,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(0,b,0,1,f),Phaser.Physics.Ninja.Circle.COL_AXIS)}return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS}if(0===d)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var i=f.pos.x+c*f.xw,j=f.pos.y+d*f.yw,g=e.pos.x-i,h=e.pos.y-j,k=Math.sqrt(g*g+h*h),l=e.radius-k;return l>0?(0===k?(g=c/Math.SQRT2,h=d/Math.SQRT2):(g/=k,h/=k),e.reportCollisionVsWorld(g*l,h*l,g,h,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_45Deg:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0===c)if(0===d){var j=f.sx,k=f.sy,l=e.pos.x-j*e.radius-f.pos.x,m=e.pos.y-k*e.radius-f.pos.y,n=l*j+m*k;if(0>n){j*=-n,k*=-n,b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1));var o=Math.sqrt(j*j+k*k);return o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,l=e.pos.x-(f.pos.x-h*f.xw),m=e.pos.y-(f.pos.y+d*f.yw),p=l*-k+m*j;if(p*h*i>0){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER 3 | }else{var n=l*j+m*k,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(j*r,k*r,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0===d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,l=e.pos.x-(f.pos.x+c*f.xw),m=e.pos.y-(f.pos.y-i*f.yw),p=l*-k+m*j;if(0>p*h*i){var q=Math.sqrt(l*l+m*m),r=e.radius-q;if(r>0)return l/=q,m/=q,e.reportCollisionVsWorld(l*r,m*r,l,m,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var n=l*j+m*k,r=e.radius-Math.abs(n);if(r>0)return e.reportCollisionVsWorld(j*r,k*r,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(h*c+i*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;var s=f.pos.x+c*f.xw,t=f.pos.y+d*f.yw,u=e.pos.x-s,v=e.pos.y-t,q=Math.sqrt(u*u+v*v),r=e.radius-q;if(r>0)return 0===q?(u=c/Math.SQRT2,v=d/Math.SQRT2):(u/=q,v/=q),e.reportCollisionVsWorld(u*r,v*r,u,v,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Concave:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0===c){if(0===d){var j=f.pos.x+h*f.xw-e.pos.x,k=f.pos.y+i*f.yw-e.pos.y,l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=n+e.radius-m;return o>0?(b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER)):Phaser.Physics.Ninja.Circle.COL_NONE}if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=f.pos.x-h*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0===n?(r=0,s=d):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(0===d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=f.pos.x+c*f.xw,q=f.pos.y-i*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0===n?(r=c,s=0):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{if(h*c+i*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;var p=f.pos.x+c*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0===n?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Convex:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0===c)if(0===d){var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),o>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}else{if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(0===d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(h*c+i*d>0){var j=e.pos.x-(f.pos.x-h*f.xw),k=e.pos.y-(f.pos.y-i*f.yw),l=2*f.xw,m=Math.sqrt(l*l+0),n=Math.sqrt(j*j+k*k),o=m+e.radius-n;if(o>0)return j/=n,k/=n,e.reportCollisionVsWorld(j*o,k*o,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var p=f.pos.x+c*f.xw,q=f.pos.y+d*f.yw,r=e.pos.x-p,s=e.pos.y-q,n=Math.sqrt(r*r+s*s),o=e.radius-n;if(o>0)return 0===n?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=n,s/=n),e.reportCollisionVsWorld(r*o,s*o,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_Half:function(a,b,c,d,e,f){var g=f.signx,h=f.signy,i=c*g+d*h;if(i>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0===c)if(0===d){var j=e.radius,k=e.pos.x-g*j-f.pos.x,l=e.pos.y-h*j-f.pos.y,m=g,n=h,o=k*m+l*n;if(0>o){m*=-o,n*=-o;var p=Math.sqrt(m*m+n*n),q=Math.sqrt(a*a+b*b);return p>q?(e.reportCollisionVsWorld(a,b,a/q,b/q,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(m,n,f.signx,f.signy),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0!==i)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var r=e.pos.x-f.pos.x;if(0>r*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var s=e.pos.y-(f.pos.y+d*f.yw),t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0===t?(r=g/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else if(0===d){if(0!==i)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var s=e.pos.y-f.pos.y;if(0>s*h)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var r=e.pos.x-(f.pos.x+c*f.xw),t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0===t?(r=g/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var v=f.pos.x+c*f.xw,w=f.pos.y+d*f.yw,r=e.pos.x-v,s=e.pos.y-w,t=Math.sqrt(r*r+s*s),u=e.radius-t;if(u>0)return 0===t?(r=c/Math.SQRT2,s=d/Math.SQRT2):(r/=t,s/=t),e.reportCollisionVsWorld(r*u,s*u,r,s,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_22DegS:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(i*d>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0===c){if(0!==d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,l=e.radius,m=e.pos.x-(f.pos.x-h*f.xw),n=e.pos.y-f.pos.y,o=m*-k+n*j;if(o*h*i>0){var p=Math.sqrt(m*m+n*n),q=l-p;if(q>0)return m/=p,n/=p,e.reportCollisionVsWorld(m*q,n*q,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{m-=l*j,n-=l*k;var r=m*j+n*k;if(0>r){j*=-r,k*=-r;var s=Math.sqrt(j*j+k*k);return b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),s>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}}else if(0===d)if(0>h*c){var t=f.pos.x-h*f.xw,u=f.pos.y,v=e.pos.x-t,w=e.pos.y-u;if(0>w*i)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=Math.sqrt(v*v+w*w),q=e.radius-p;if(q>0)return 0===p?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=p,w/=p),e.reportCollisionVsWorld(v*q,w*q,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var j=f.sx,k=f.sy,m=e.pos.x-(f.pos.x+c*f.xw),n=e.pos.y-(f.pos.y-i*f.yw),o=m*-k+n*j;if(0>o*h*i){var p=Math.sqrt(m*m+n*n),q=e.radius-p;if(q>0)return m/=p,n/=p,e.reportCollisionVsWorld(m*q,n*q,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var r=m*j+n*k,q=e.radius-Math.abs(r);if(q>0)return e.reportCollisionVsWorld(j*q,k*q,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{var t=f.pos.x+c*f.xw,u=f.pos.y+d*f.yw,v=e.pos.x-t,w=e.pos.y-u,p=Math.sqrt(v*v+w*w),q=e.radius-p;if(q>0)return 0===p?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=p,w/=p),e.reportCollisionVsWorld(v*q,w*q,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_22DegB:function(a,b,c,d,e,f){var g,h=f.signx,i=f.signy;if(0===c)if(0===d){var j=f.sx,k=f.sy,l=e.radius,m=e.pos.x-j*l-(f.pos.x-h*f.xw),n=e.pos.y-k*l-(f.pos.y+i*f.yw),o=m*j+n*k;if(0>o){j*=-o,k*=-o;var p=Math.sqrt(j*j+k*k);return b>a?(g=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(g=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),p>g?(e.reportCollisionVsWorld(a,b,a/g,b/g,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>i*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,m=e.pos.x-(f.pos.x-h*f.xw),n=e.pos.y-(f.pos.y+i*f.yw),q=m*-k+n*j;if(q*h*i>0){var r=Math.sqrt(m*m+n*n),s=e.radius-r;if(s>0)return m/=r,n/=r,e.reportCollisionVsWorld(m*s,n*s,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=e.radius-Math.abs(o);if(s>0)return e.reportCollisionVsWorld(j*s,k*s,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0===d){if(0>h*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var m=e.pos.x-(f.pos.x+h*f.xw),n=e.pos.y-f.pos.y;if(0>n*i)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,q=m*-k+n*j;if(0>q*h*i){var r=Math.sqrt(m*m+n*n),s=e.radius-r;if(s>0)return m/=r,n/=r,e.reportCollisionVsWorld(m*s,n*s,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=e.radius-Math.abs(o);if(s>0)return e.reportCollisionVsWorld(j*s,k*s,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(h*c+i*d>0){var t=Math.sqrt(5),j=1*h/t,k=2*i/t,l=e.radius,m=e.pos.x-j*l-(f.pos.x-h*f.xw),n=e.pos.y-k*l-(f.pos.y+i*f.yw),o=m*j+n*k;return 0>o?(e.reportCollisionVsWorld(-j*o,-k*o,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE}var u=f.pos.x+c*f.xw,v=f.pos.y+d*f.yw,w=e.pos.x-u,x=e.pos.y-v,r=Math.sqrt(w*w+x*x),s=e.radius-r;if(s>0)return 0===r?(w=c/Math.SQRT2,x=d/Math.SQRT2):(w/=r,x/=r),e.reportCollisionVsWorld(w*s,x*s,w,x,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_67DegS:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(g*c>0)return Phaser.Physics.Ninja.Circle.COL_NONE;if(0===c)if(0===d){var i,j=f.sx,k=f.sy,l=e.radius,m=e.pos.x-f.pos.x,n=e.pos.y-(f.pos.y-h*f.yw),o=m*-k+n*j;if(0>o*g*h){var p=Math.sqrt(m*m+n*n),q=l-p;if(q>0)return m/=p,n/=p,e.reportCollisionVsWorld(m*q,n*q,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{m-=l*j,n-=l*k;var r=m*j+n*k;if(0>r){j*=-r,k*=-r;var s=Math.sqrt(j*j+k*k);return b>a?(i=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(i=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),s>i?(e.reportCollisionVsWorld(a,b,a/i,b/i,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}}else if(0>h*d){var t=f.pos.x,u=f.pos.y-h*f.yw,v=e.pos.x-t,w=e.pos.y-u;if(0>v*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var p=Math.sqrt(v*v+w*w),q=e.radius-p;if(q>0)return 0===p?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=p,w/=p),e.reportCollisionVsWorld(v*q,w*q,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var j=f.sx,k=f.sy,m=e.pos.x-(f.pos.x-g*f.xw),n=e.pos.y-(f.pos.y+d*f.yw),o=m*-k+n*j;if(o*g*h>0){var p=Math.sqrt(m*m+n*n),q=e.radius-p;if(q>0)return m/=p,n/=p,e.reportCollisionVsWorld(m*q,n*q,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var r=m*j+n*k,q=e.radius-Math.abs(r);if(q>0)return e.reportCollisionVsWorld(j*q,k*q,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(0===d)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var t=f.pos.x+c*f.xw,u=f.pos.y+d*f.yw,v=e.pos.x-t,w=e.pos.y-u,p=Math.sqrt(v*v+w*w),q=e.radius-p;if(q>0)return 0===p?(v=c/Math.SQRT2,w=d/Math.SQRT2):(v/=p,w/=p),e.reportCollisionVsWorld(v*q,w*q,v,w,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},projCircle_67DegB:function(a,b,c,d,e,f){var g=f.signx,h=f.signy;if(0===c)if(0===d){var i,j=f.sx,k=f.sy,l=e.radius,m=e.pos.x-j*l-(f.pos.x+g*f.xw),n=e.pos.y-k*l-(f.pos.y-h*f.yw),o=m*j+n*k;if(0>o){j*=-o,k*=-o;var p=Math.sqrt(j*j+k*k);return b>a?(i=a,b=0,e.pos.x-f.pos.x<0&&(a*=-1)):(i=b,a=0,e.pos.y-f.pos.y<0&&(b*=-1)),p>i?(e.reportCollisionVsWorld(a,b,a/i,b/i,f),Phaser.Physics.Ninja.Circle.COL_AXIS):(e.reportCollisionVsWorld(j,k,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER)}}else{if(0>h*d)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var m=e.pos.x-f.pos.x,n=e.pos.y-(f.pos.y+h*f.yw);if(0>m*g)return e.reportCollisionVsWorld(0,b*d,0,d,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var j=f.sx,k=f.sy,q=m*-k+n*j;if(q*g*h>0){var r=Math.sqrt(m*m+n*n),s=e.radius-r;if(s>0)return m/=r,n/=r,e.reportCollisionVsWorld(m*s,n*s,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=e.radius-Math.abs(o);if(s>0)return e.reportCollisionVsWorld(j*s,k*s,j,k,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else if(0===d){if(0>g*c)return e.reportCollisionVsWorld(a*c,0,c,0,f),Phaser.Physics.Ninja.Circle.COL_AXIS;var t=Math.sqrt(5),j=2*g/t,k=1*h/t,m=e.pos.x-(f.pos.x+g*f.xw),n=e.pos.y-(f.pos.y-h*f.yw),q=m*-k+n*j;if(0>q*g*h){var r=Math.sqrt(m*m+n*n),s=e.radius-r;if(s>0)return m/=r,n/=r,e.reportCollisionVsWorld(m*s,n*s,m,n,f),Phaser.Physics.Ninja.Circle.COL_OTHER}else{var o=m*j+n*k,s=e.radius-Math.abs(o);if(s>0)return e.reportCollisionVsWorld(j*s,k*s,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER}}else{if(g*c+h*d>0){var j=f.sx,k=f.sy,l=e.radius,m=e.pos.x-j*l-(f.pos.x+g*f.xw),n=e.pos.y-k*l-(f.pos.y-h*f.yw),o=m*j+n*k;return 0>o?(e.reportCollisionVsWorld(-j*o,-k*o,f.sx,f.sy,f),Phaser.Physics.Ninja.Circle.COL_OTHER):Phaser.Physics.Ninja.Circle.COL_NONE}var u=f.pos.x+c*f.xw,v=f.pos.y+d*f.yw,w=e.pos.x-u,x=e.pos.y-v,r=Math.sqrt(w*w+x*x),s=e.radius-r;if(s>0)return 0===r?(w=c/Math.SQRT2,x=d/Math.SQRT2):(w/=r,x/=r),e.reportCollisionVsWorld(w*s,x*s,w,x,f),Phaser.Physics.Ninja.Circle.COL_OTHER}return Phaser.Physics.Ninja.Circle.COL_NONE},destroy:function(){this.body=null,this.system=null},render:function(a,b,c,d,e){var f=this.pos.x-b,g=this.pos.y-c;a.beginPath(),a.arc(f,g,this.radius,0,2*Math.PI,!1),e?(a.fillStyle=d,a.fill()):(a.strokeStyle=d,a.stroke())}}; -------------------------------------------------------------------------------- /public/js/vendors/qrcode/qrcode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * - Using the 'QRCode for Javascript library' 4 | * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. 5 | * - this library has no dependencies. 6 | * 7 | * @author davidshimjs 8 | * @see http://www.d-project.com/ 9 | * @see http://jeromeetienne.github.com/jquery-qrcode/ 10 | */ 11 | var QRCode; 12 | 13 | (function () { 14 | //--------------------------------------------------------------------- 15 | // QRCode for JavaScript 16 | // 17 | // Copyright (c) 2009 Kazuhiko Arase 18 | // 19 | // URL: http://www.d-project.com/ 20 | // 21 | // Licensed under the MIT license: 22 | // http://www.opensource.org/licenses/mit-license.php 23 | // 24 | // The word "QR Code" is registered trademark of 25 | // DENSO WAVE INCORPORATED 26 | // http://www.denso-wave.com/qrcode/faqpatent-e.html 27 | // 28 | //--------------------------------------------------------------------- 29 | function QR8bitByte(data) { 30 | this.mode = QRMode.MODE_8BIT_BYTE; 31 | this.data = data; 32 | this.parsedData = []; 33 | 34 | // Added to support UTF-8 Characters 35 | for (var i = 0, l = this.data.length; i < l; i++) { 36 | var byteArray = []; 37 | var code = this.data.charCodeAt(i); 38 | 39 | if (code > 0x10000) { 40 | byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); 41 | byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); 42 | byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); 43 | byteArray[3] = 0x80 | (code & 0x3F); 44 | } else if (code > 0x800) { 45 | byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); 46 | byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); 47 | byteArray[2] = 0x80 | (code & 0x3F); 48 | } else if (code > 0x80) { 49 | byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); 50 | byteArray[1] = 0x80 | (code & 0x3F); 51 | } else { 52 | byteArray[0] = code; 53 | } 54 | 55 | this.parsedData.push(byteArray); 56 | } 57 | 58 | this.parsedData = Array.prototype.concat.apply([], this.parsedData); 59 | 60 | if (this.parsedData.length != this.data.length) { 61 | this.parsedData.unshift(191); 62 | this.parsedData.unshift(187); 63 | this.parsedData.unshift(239); 64 | } 65 | } 66 | 67 | QR8bitByte.prototype = { 68 | getLength: function (buffer) { 69 | return this.parsedData.length; 70 | }, 71 | write: function (buffer) { 72 | for (var i = 0, l = this.parsedData.length; i < l; i++) { 73 | buffer.put(this.parsedData[i], 8); 74 | } 75 | } 76 | }; 77 | 78 | function QRCodeModel(typeNumber, errorCorrectLevel) { 79 | this.typeNumber = typeNumber; 80 | this.errorCorrectLevel = errorCorrectLevel; 81 | this.modules = null; 82 | this.moduleCount = 0; 83 | this.dataCache = null; 84 | this.dataList = []; 85 | } 86 | 87 | QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);} 88 | return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row=7){this.setupTypeNumber(test);} 90 | if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);} 91 | this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}} 92 | return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;} 98 | for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}} 99 | for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}} 100 | this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex>>bitIndex)&1)==1);} 101 | var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;} 102 | this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}} 103 | row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;itotalDataCount*8){throw new Error("code length overflow. (" 106 | +buffer.getLengthInBits() 107 | +">" 108 | +totalDataCount*8 109 | +")");} 110 | if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);} 111 | while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);} 112 | while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;} 113 | buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;} 114 | buffer.put(QRCodeModel.PAD1,8);} 115 | return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r=0)?modPoly.get(modIndex):0;}} 117 | var totalCodeCount=0;for(var i=0;i=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));} 121 | return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));} 122 | return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;} 123 | return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i5){lostPoint+=(3+sameCount-5);}}} 129 | for(var row=0;row=256){n-=255;} 136 | return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);} 151 | if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));} 152 | this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; 153 | 154 | function _isSupportCanvas() { 155 | return typeof CanvasRenderingContext2D != "undefined"; 156 | } 157 | 158 | // android 2.x doesn't support Data-URI spec 159 | function _getAndroid() { 160 | var android = false; 161 | var sAgent = navigator.userAgent; 162 | 163 | if (/android/i.test(sAgent)) { // android 164 | android = true; 165 | var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); 166 | 167 | if (aMat && aMat[1]) { 168 | android = parseFloat(aMat[1]); 169 | } 170 | } 171 | 172 | return android; 173 | } 174 | 175 | var svgDrawer = (function() { 176 | 177 | var Drawing = function (el, htOption) { 178 | this._el = el; 179 | this._htOption = htOption; 180 | }; 181 | 182 | Drawing.prototype.draw = function (oQRCode) { 183 | var _htOption = this._htOption; 184 | var _el = this._el; 185 | var nCount = oQRCode.getModuleCount(); 186 | var nWidth = Math.floor(_htOption.width / nCount); 187 | var nHeight = Math.floor(_htOption.height / nCount); 188 | 189 | this.clear(); 190 | 191 | function makeSVG(tag, attrs) { 192 | var el = document.createElementNS('http://www.w3.org/2000/svg', tag); 193 | for (var k in attrs) 194 | if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); 195 | return el; 196 | } 197 | 198 | var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); 199 | svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); 200 | _el.appendChild(svg); 201 | 202 | svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"})); 203 | svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); 204 | 205 | for (var row = 0; row < nCount; row++) { 206 | for (var col = 0; col < nCount; col++) { 207 | if (oQRCode.isDark(row, col)) { 208 | var child = makeSVG("use", {"x": String(row), "y": String(col)}); 209 | child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") 210 | svg.appendChild(child); 211 | } 212 | } 213 | } 214 | }; 215 | Drawing.prototype.clear = function () { 216 | while (this._el.hasChildNodes()) 217 | this._el.removeChild(this._el.lastChild); 218 | }; 219 | return Drawing; 220 | })(); 221 | 222 | var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; 223 | 224 | // Drawing in DOM by using Table tag 225 | var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { 226 | var Drawing = function (el, htOption) { 227 | this._el = el; 228 | this._htOption = htOption; 229 | }; 230 | 231 | /** 232 | * Draw the QRCode 233 | * 234 | * @param {QRCode} oQRCode 235 | */ 236 | Drawing.prototype.draw = function (oQRCode) { 237 | var _htOption = this._htOption; 238 | var _el = this._el; 239 | var nCount = oQRCode.getModuleCount(); 240 | var nWidth = Math.floor(_htOption.width / nCount); 241 | var nHeight = Math.floor(_htOption.height / nCount); 242 | var aHTML = ['']; 243 | 244 | for (var row = 0; row < nCount; row++) { 245 | aHTML.push(''); 246 | 247 | for (var col = 0; col < nCount; col++) { 248 | aHTML.push(''); 249 | } 250 | 251 | aHTML.push(''); 252 | } 253 | 254 | aHTML.push('
'); 255 | _el.innerHTML = aHTML.join(''); 256 | 257 | // Fix the margin values as real size. 258 | var elTable = _el.childNodes[0]; 259 | var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; 260 | var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; 261 | 262 | if (nLeftMarginTable > 0 && nTopMarginTable > 0) { 263 | elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; 264 | } 265 | }; 266 | 267 | /** 268 | * Clear the QRCode 269 | */ 270 | Drawing.prototype.clear = function () { 271 | this._el.innerHTML = ''; 272 | }; 273 | 274 | return Drawing; 275 | })() : (function () { // Drawing in Canvas 276 | function _onMakeImage() { 277 | this._elImage.src = this._elCanvas.toDataURL("image/png"); 278 | this._elImage.style.display = "block"; 279 | this._elCanvas.style.display = "none"; 280 | } 281 | 282 | // Android 2.1 bug workaround 283 | // http://code.google.com/p/android/issues/detail?id=5141 284 | if (this._android && this._android <= 2.1) { 285 | var factor = 1 / window.devicePixelRatio; 286 | var drawImage = CanvasRenderingContext2D.prototype.drawImage; 287 | CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { 288 | if (("nodeName" in image) && /img/i.test(image.nodeName)) { 289 | for (var i = arguments.length - 1; i >= 1; i--) { 290 | arguments[i] = arguments[i] * factor; 291 | } 292 | } else if (typeof dw == "undefined") { 293 | arguments[1] *= factor; 294 | arguments[2] *= factor; 295 | arguments[3] *= factor; 296 | arguments[4] *= factor; 297 | } 298 | 299 | drawImage.apply(this, arguments); 300 | }; 301 | } 302 | 303 | /** 304 | * Check whether the user's browser supports Data URI or not 305 | * 306 | * @private 307 | * @param {Function} fSuccess Occurs if it supports Data URI 308 | * @param {Function} fFail Occurs if it doesn't support Data URI 309 | */ 310 | function _safeSetDataURI(fSuccess, fFail) { 311 | var self = this; 312 | self._fFail = fFail; 313 | self._fSuccess = fSuccess; 314 | 315 | // Check it just once 316 | if (self._bSupportDataURI === null) { 317 | var el = document.createElement("img"); 318 | var fOnError = function() { 319 | self._bSupportDataURI = false; 320 | 321 | if (self._fFail) { 322 | self._fFail.call(self); 323 | } 324 | }; 325 | var fOnSuccess = function() { 326 | self._bSupportDataURI = true; 327 | 328 | if (self._fSuccess) { 329 | self._fSuccess.call(self); 330 | } 331 | }; 332 | 333 | el.onabort = fOnError; 334 | el.onerror = fOnError; 335 | el.onload = fOnSuccess; 336 | el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. 337 | return; 338 | } else if (self._bSupportDataURI === true && self._fSuccess) { 339 | self._fSuccess.call(self); 340 | } else if (self._bSupportDataURI === false && self._fFail) { 341 | self._fFail.call(self); 342 | } 343 | }; 344 | 345 | /** 346 | * Drawing QRCode by using canvas 347 | * 348 | * @constructor 349 | * @param {HTMLElement} el 350 | * @param {Object} htOption QRCode Options 351 | */ 352 | var Drawing = function (el, htOption) { 353 | this._bIsPainted = false; 354 | this._android = _getAndroid(); 355 | 356 | this._htOption = htOption; 357 | this._elCanvas = document.createElement("canvas"); 358 | this._elCanvas.width = htOption.width; 359 | this._elCanvas.height = htOption.height; 360 | el.appendChild(this._elCanvas); 361 | this._el = el; 362 | this._oContext = this._elCanvas.getContext("2d"); 363 | this._bIsPainted = false; 364 | this._elImage = document.createElement("img"); 365 | this._elImage.alt = "Scan me!"; 366 | this._elImage.style.display = "none"; 367 | this._el.appendChild(this._elImage); 368 | this._bSupportDataURI = null; 369 | }; 370 | 371 | /** 372 | * Draw the QRCode 373 | * 374 | * @param {QRCode} oQRCode 375 | */ 376 | Drawing.prototype.draw = function (oQRCode) { 377 | var _elImage = this._elImage; 378 | var _oContext = this._oContext; 379 | var _htOption = this._htOption; 380 | 381 | var nCount = oQRCode.getModuleCount(); 382 | var nWidth = _htOption.width / nCount; 383 | var nHeight = _htOption.height / nCount; 384 | var nRoundedWidth = Math.round(nWidth); 385 | var nRoundedHeight = Math.round(nHeight); 386 | 387 | _elImage.style.display = "none"; 388 | this.clear(); 389 | 390 | for (var row = 0; row < nCount; row++) { 391 | for (var col = 0; col < nCount; col++) { 392 | var bIsDark = oQRCode.isDark(row, col); 393 | var nLeft = col * nWidth; 394 | var nTop = row * nHeight; 395 | _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 396 | _oContext.lineWidth = 1; 397 | _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 398 | _oContext.fillRect(nLeft, nTop, nWidth, nHeight); 399 | 400 | // 안티 앨리어싱 방지 처리 401 | _oContext.strokeRect( 402 | Math.floor(nLeft) + 0.5, 403 | Math.floor(nTop) + 0.5, 404 | nRoundedWidth, 405 | nRoundedHeight 406 | ); 407 | 408 | _oContext.strokeRect( 409 | Math.ceil(nLeft) - 0.5, 410 | Math.ceil(nTop) - 0.5, 411 | nRoundedWidth, 412 | nRoundedHeight 413 | ); 414 | } 415 | } 416 | 417 | this._bIsPainted = true; 418 | }; 419 | 420 | /** 421 | * Make the image from Canvas if the browser supports Data URI. 422 | */ 423 | Drawing.prototype.makeImage = function () { 424 | if (this._bIsPainted) { 425 | _safeSetDataURI.call(this, _onMakeImage); 426 | } 427 | }; 428 | 429 | /** 430 | * Return whether the QRCode is painted or not 431 | * 432 | * @return {Boolean} 433 | */ 434 | Drawing.prototype.isPainted = function () { 435 | return this._bIsPainted; 436 | }; 437 | 438 | /** 439 | * Clear the QRCode 440 | */ 441 | Drawing.prototype.clear = function () { 442 | this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); 443 | this._bIsPainted = false; 444 | }; 445 | 446 | /** 447 | * @private 448 | * @param {Number} nNumber 449 | */ 450 | Drawing.prototype.round = function (nNumber) { 451 | if (!nNumber) { 452 | return nNumber; 453 | } 454 | 455 | return Math.floor(nNumber * 1000) / 1000; 456 | }; 457 | 458 | return Drawing; 459 | })(); 460 | 461 | /** 462 | * Get the type by string length 463 | * 464 | * @private 465 | * @param {String} sText 466 | * @param {Number} nCorrectLevel 467 | * @return {Number} type 468 | */ 469 | function _getTypeNumber(sText, nCorrectLevel) { 470 | var nType = 1; 471 | var length = _getUTF8Length(sText); 472 | 473 | for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { 474 | var nLimit = 0; 475 | 476 | switch (nCorrectLevel) { 477 | case QRErrorCorrectLevel.L : 478 | nLimit = QRCodeLimitLength[i][0]; 479 | break; 480 | case QRErrorCorrectLevel.M : 481 | nLimit = QRCodeLimitLength[i][1]; 482 | break; 483 | case QRErrorCorrectLevel.Q : 484 | nLimit = QRCodeLimitLength[i][2]; 485 | break; 486 | case QRErrorCorrectLevel.H : 487 | nLimit = QRCodeLimitLength[i][3]; 488 | break; 489 | } 490 | 491 | if (length <= nLimit) { 492 | break; 493 | } else { 494 | nType++; 495 | } 496 | } 497 | 498 | if (nType > QRCodeLimitLength.length) { 499 | throw new Error("Too long data"); 500 | } 501 | 502 | return nType; 503 | } 504 | 505 | function _getUTF8Length(sText) { 506 | var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); 507 | return replacedText.length + (replacedText.length != sText ? 3 : 0); 508 | } 509 | 510 | /** 511 | * @class QRCode 512 | * @constructor 513 | * @example 514 | * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); 515 | * 516 | * @example 517 | * var oQRCode = new QRCode("test", { 518 | * text : "http://naver.com", 519 | * width : 128, 520 | * height : 128 521 | * }); 522 | * 523 | * oQRCode.clear(); // Clear the QRCode. 524 | * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. 525 | * 526 | * @param {HTMLElement|String} el target element or 'id' attribute of element. 527 | * @param {Object|String} vOption 528 | * @param {String} vOption.text QRCode link data 529 | * @param {Number} [vOption.width=256] 530 | * @param {Number} [vOption.height=256] 531 | * @param {String} [vOption.colorDark="#000000"] 532 | * @param {String} [vOption.colorLight="#ffffff"] 533 | * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 534 | */ 535 | QRCode = function (el, vOption) { 536 | this._htOption = { 537 | width : 256, 538 | height : 256, 539 | typeNumber : 4, 540 | colorDark : "#000000", 541 | colorLight : "#ffffff", 542 | correctLevel : QRErrorCorrectLevel.H 543 | }; 544 | 545 | if (typeof vOption === 'string') { 546 | vOption = { 547 | text : vOption 548 | }; 549 | } 550 | 551 | // Overwrites options 552 | if (vOption) { 553 | for (var i in vOption) { 554 | this._htOption[i] = vOption[i]; 555 | } 556 | } 557 | 558 | if (typeof el == "string") { 559 | el = document.getElementById(el); 560 | } 561 | 562 | if (this._htOption.useSVG) { 563 | Drawing = svgDrawer; 564 | } 565 | 566 | this._android = _getAndroid(); 567 | this._el = el; 568 | this._oQRCode = null; 569 | this._oDrawing = new Drawing(this._el, this._htOption); 570 | 571 | if (this._htOption.text) { 572 | this.makeCode(this._htOption.text); 573 | } 574 | }; 575 | 576 | /** 577 | * Make the QRCode 578 | * 579 | * @param {String} sText link data 580 | */ 581 | QRCode.prototype.makeCode = function (sText) { 582 | this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); 583 | this._oQRCode.addData(sText); 584 | this._oQRCode.make(); 585 | this._el.title = sText; 586 | this._oDrawing.draw(this._oQRCode); 587 | this.makeImage(); 588 | }; 589 | 590 | /** 591 | * Make the Image from Canvas element 592 | * - It occurs automatically 593 | * - Android below 3 doesn't support Data-URI spec. 594 | * 595 | * @private 596 | */ 597 | QRCode.prototype.makeImage = function () { 598 | if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { 599 | this._oDrawing.makeImage(); 600 | } 601 | }; 602 | 603 | /** 604 | * Clear the QRCode 605 | */ 606 | QRCode.prototype.clear = function () { 607 | this._oDrawing.clear(); 608 | }; 609 | 610 | /** 611 | * @name QRCode.CorrectLevel 612 | */ 613 | QRCode.CorrectLevel = QRErrorCorrectLevel; 614 | })(); 615 | -------------------------------------------------------------------------------- /public/js/vendors/qrcode/qrcode.min.js: -------------------------------------------------------------------------------- 1 | var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); -------------------------------------------------------------------------------- /public/res/sprites/pixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/public/res/sprites/pixel.png -------------------------------------------------------------------------------- /public/res/textures/loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/public/res/textures/loading.png -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | var compress = require('compression'); 8 | 9 | var routes = require('./routes.js'); 10 | 11 | var app = express(); 12 | 13 | app.use(compress()); 14 | 15 | // view engine setup 16 | app.set('views', path.join(__dirname, 'views')); 17 | app.set('view engine', 'jade'); 18 | 19 | // uncomment after placing your favicon in /public 20 | app.use(favicon(path.join(__dirname, '../public/favicon.ico'))); 21 | /* 22 | app.use(logger('dev')); 23 | app.use(bodyParser.json()); 24 | app.use(bodyParser.urlencoded({ extended: false })); 25 | app.use(cookieParser()); 26 | */ 27 | app.use(express.static(path.join(__dirname, '../public'))); 28 | 29 | app.use('/api/', routes); 30 | 31 | // catch 404 and forward to error handler 32 | app.use(function(req, res, next) { 33 | var err = new Error('Not Found'); 34 | err.status = 404; 35 | next(err); 36 | }); 37 | 38 | // error handlers 39 | 40 | // development error handler 41 | // will print stacktrace 42 | if (app.get('env') === 'development') { 43 | app.use(function(err, req, res, next) { 44 | res.status(err.status || 500); 45 | res.render('error', { 46 | message: err.message, 47 | error: err 48 | }); 49 | }); 50 | } 51 | else { 52 | // production error handler 53 | // no stacktraces leaked to user 54 | app.use(function (err, req, res, next) { 55 | res.status(err.status || 500); 56 | res.render('error', { 57 | message: err.message, 58 | error: {} 59 | }); 60 | }); 61 | } 62 | 63 | module.exports = app; 64 | -------------------------------------------------------------------------------- /server/main.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('./app.js'); 8 | var debug = require('debug')('pong:main'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | var io = require('socket.io')(server); 24 | //var io = require('socket.io').listen(server, { log: false }); 25 | var gameServer = require('./server.js')(io); 26 | 27 | 28 | /** 29 | * Listen on provided port, on all network interfaces. 30 | */ 31 | 32 | server.listen(port); 33 | server.on('error', onError); 34 | server.on('listening', onListening); 35 | 36 | /** 37 | * Normalize a port into a number, string, or false. 38 | */ 39 | 40 | function normalizePort(val) { 41 | var port = parseInt(val, 10); 42 | 43 | if (isNaN(port)) { 44 | // named pipe 45 | return val; 46 | } 47 | 48 | if (port >= 0) { 49 | // port number 50 | return port; 51 | } 52 | 53 | return false; 54 | } 55 | 56 | /** 57 | * Event listener for HTTP server "error" event. 58 | */ 59 | 60 | function onError(error) { 61 | if (error.syscall !== 'listen') { 62 | throw error; 63 | } 64 | 65 | var bind = typeof port === 'string' 66 | ? 'Pipe ' + port 67 | : 'Port ' + port 68 | 69 | // handle specific listen errors with friendly messages 70 | switch (error.code) { 71 | case 'EACCES': 72 | console.error(bind + ' requires elevated privileges'); 73 | process.exit(1); 74 | break; 75 | case 'EADDRINUSE': 76 | console.error(bind + ' is already in use'); 77 | process.exit(1); 78 | break; 79 | default: 80 | throw error; 81 | } 82 | } 83 | 84 | /** 85 | * Event listener for HTTP server "listening" event. 86 | */ 87 | 88 | function onListening() { 89 | var addr = server.address(); 90 | var bind = typeof addr === 'string' 91 | ? 'pipe ' + addr 92 | : 'port ' + addr.port; 93 | debug('Listening on ' + bind); 94 | } 95 | -------------------------------------------------------------------------------- /server/routes.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Pong' }); 7 | }); 8 | 9 | module.exports = router; -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | var err = require('debug')('pong:server:error'); 2 | var warn = require('debug')('pong:server:warning'); 3 | var log = require('debug')('pong:server:log'); 4 | 5 | function server(io) { 6 | var debug = false; 7 | var timeOutDelay = 2500; 8 | var maxPlayers = 4; 9 | if (debug) { 10 | maxPlayers = 2; 11 | } 12 | 13 | var clientPlayers = {}; 14 | var clients = {}; 15 | var hosts = {}; 16 | var games = []; 17 | 18 | function in_array(search, array) { 19 | return array.indexOf(search) >= 0; 20 | } 21 | 22 | function makeGameId() { 23 | var r; 24 | do { 25 | r = (0|Math.random()*9e6).toString(36).substring(0,4); 26 | } 27 | while (in_array(r, games)); 28 | return r; 29 | } 30 | 31 | function roomExists(room) { 32 | return io.nsps["/"].adapter.rooms[room] != undefined; 33 | } 34 | 35 | function getSocket(socketId) { 36 | return io.sockets.connected[socketId]; 37 | } 38 | 39 | function getRoom(room) { 40 | return io.nsps["/"].adapter.rooms[room]; 41 | } 42 | 43 | function socketsInRoom(room) { 44 | if (io == undefined) { 45 | err('io is undefined :\\'); 46 | } 47 | 48 | if (io.nsps["/"] == undefined) { 49 | err('/ namespace is undefined :\\'); 50 | } 51 | 52 | if (io.nsps["/"].adapter == undefined) { 53 | err('adapter is undefined :\\'); 54 | } 55 | 56 | if (io.nsps["/"].adapter.rooms == undefined) { 57 | err('rooms is undefined :\\'); 58 | } 59 | 60 | var r = getRoom(room); 61 | if (typeof r === 'object') { 62 | return Object.keys(r.sockets); 63 | } 64 | else { 65 | return []; 66 | } 67 | } 68 | 69 | function sendError(number, msg, socket, room) { 70 | try { 71 | if (room != undefined) { 72 | socket = socket.to(room); 73 | } 74 | socket.emit('errorMsg', {num: number, msg: msg}); 75 | } 76 | catch(ex) { 77 | err(ex); 78 | } 79 | } 80 | 81 | function startTimeOut(room, playerCounter, times) { 82 | if (playerCounter == undefined) { 83 | playerCounter = 0; 84 | } 85 | 86 | if (times == undefined) { 87 | times = 0; 88 | } 89 | 90 | var players = socketsInRoom(room); 91 | 92 | if (times > 3) { 93 | return; 94 | } 95 | else if (playerCounter >= maxPlayers) { 96 | startTimeOut(room, 0, ++times); 97 | } 98 | else { 99 | var sid = players[playerCounter]; 100 | var socket = io.sockets.connected[players[playerCounter]]; 101 | //var socket = getSocket(sid); 102 | if (socket != undefined) { 103 | log('ticking... '+times+' '+ sid); 104 | socket.emit('timeOut', {times: times}, function (socketId) { 105 | log('ticking back... '+times+' '+ socketId); 106 | startTimeOut(room, ++playerCounter, times); 107 | }); 108 | } 109 | else { 110 | err('socket not found :\\ '+sid); 111 | } 112 | } 113 | } 114 | 115 | io.on('connection', function(socket) { 116 | clients[socket.id] = null; 117 | 118 | socket.on('error', function(data) { 119 | err('onError', data); 120 | }); 121 | 122 | socket.on('host', function(data, ack) { 123 | var room = makeGameId(); 124 | if (debug) room = 1; 125 | socket.join(room, function (err) { 126 | if (!err) { 127 | clientPlayers[socket.id] = 0; 128 | clients[socket.id] = room; 129 | hosts[socket.id] = true; 130 | ack(room); 131 | log('host '+socket.id+' connected'); 132 | } 133 | else { 134 | err(err); 135 | sendError(1, "host: can't join room", socket); 136 | } 137 | }); 138 | }); 139 | 140 | socket.on('join', function(data, ack) { 141 | var room = data; 142 | if (debug) room = 1; 143 | if (roomExists(room)) { 144 | var c = socketsInRoom(room).length; 145 | if (c < 1) { 146 | sendError(4, "that room doesn't exists", socket); 147 | } 148 | else if (c >= maxPlayers) { 149 | sendError(5, "the room is full!", socket); 150 | } 151 | else { 152 | socket.join(room, function (err) { 153 | if (!err) { 154 | clients[socket.id] = room; 155 | var players = socketsInRoom(room); 156 | clientPlayers[socket.id] = players.length - 1; 157 | ack({ playersCount: players.length}); 158 | log('client ' + socket.id + ' connected to room ' + room + ' (' + players.length + '/'+maxPlayers+')'); 159 | io.to(room).emit('joined', { playersCount: players.length }); 160 | } 161 | else { 162 | err(err); 163 | sendError(3, "client: can't join room", socket); 164 | } 165 | }); 166 | } 167 | } 168 | else { 169 | sendError(2, "that room doesn't exists", socket); 170 | } 171 | }); 172 | 173 | socket.on('startCounting', function(socketId) { 174 | var room = clients[socketId]; 175 | var players = socketsInRoom(room); 176 | if (players.length == maxPlayers) { 177 | setTimeout(function () { 178 | startTimeOut(room); 179 | }, timeOutDelay); 180 | } 181 | else { 182 | sendError(7, "players are not reachable :\\", socket, room); 183 | } 184 | }); 185 | 186 | socket.on('disconnect', function() { 187 | var p = clientPlayers[socket.id]; 188 | clientPlayers[socket.id] = null; 189 | delete clientPlayers[socket.id]; 190 | 191 | var room = clients[socket.id]; 192 | clients[socket.id] = null; 193 | delete clients[socket.id]; 194 | 195 | var players = socketsInRoom(room); 196 | 197 | if (room != null && players.length > 0) { 198 | io.to(room).emit('playerLeft', { playerLeft: p, playersCount: players.length }); 199 | 200 | if (hosts[socket.id] && players.length > 1) { 201 | hosts[socket.id] = false; 202 | delete hosts[socket.id]; 203 | 204 | var newSocketId = players[Math.floor(Math.random()*players.length)]; 205 | hosts[newSocketId] = true; 206 | 207 | //sendError(6, "host left the game", socket, room); 208 | getSocket(newSocketId).emit('becomeHost'); 209 | } 210 | else if (players.length == 1) { 211 | sendError(8, "all the other players left the game!", socket, room); 212 | } 213 | } 214 | else { 215 | log('room ' + room + ' destroyed'); 216 | if (games[room] != undefined) { 217 | delete games[room]; 218 | } 219 | } 220 | }); 221 | 222 | socket.on('ping', function() { 223 | socket.emit('pong'); 224 | }); 225 | 226 | socket.on('gameUpdate', function(data) { 227 | var room = clients[data.socketId]; 228 | delete data.socketId; 229 | io.to(room).emit('clientUpdate', data); 230 | }); 231 | socket.on('gameScores', function(data) { 232 | var room = clients[data.socketId]; 233 | delete data.socketId; 234 | io.to(room).emit('clientUpdateScores', data); 235 | }); 236 | socket.on('gameBall', function(data) { 237 | var room = clients[data.socketId]; 238 | delete data.socketId; 239 | io.to(room).emit('clientUpdateBall', data); 240 | }); 241 | }); 242 | } 243 | 244 | module.exports = server; -------------------------------------------------------------------------------- /server/views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= message 5 | h2= error.status 6 | pre #{error.stack} 7 | -------------------------------------------------------------------------------- /server/views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | h1= title 5 | p Welcome to #{title} 6 | -------------------------------------------------------------------------------- /server/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | link(rel='stylesheet', href='/stylesheets/style.css') 6 | body 7 | block content -------------------------------------------------------------------------------- /slides/images/4pong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/4pong.png -------------------------------------------------------------------------------- /slides/images/GooglePlayGames.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/GooglePlayGames.png -------------------------------------------------------------------------------- /slides/images/League_of_Legends_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/League_of_Legends_logo.png -------------------------------------------------------------------------------- /slides/images/Logo_di_World_of_Warcraft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/Logo_di_World_of_Warcraft.gif -------------------------------------------------------------------------------- /slides/images/P2P-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/P2P-network.png -------------------------------------------------------------------------------- /slides/images/PhotonCloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/PhotonCloud.png -------------------------------------------------------------------------------- /slides/images/Pong460x276.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/Pong460x276.jpg -------------------------------------------------------------------------------- /slides/images/Quake3_Logo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/Quake3_Logo.PNG -------------------------------------------------------------------------------- /slides/images/Server-based-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/Server-based-network.png -------------------------------------------------------------------------------- /slides/images/appwarp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/appwarp.png -------------------------------------------------------------------------------- /slides/images/callofduty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/callofduty.png -------------------------------------------------------------------------------- /slides/images/clientServer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/clientServer.gif -------------------------------------------------------------------------------- /slides/images/cono.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/cono.png -------------------------------------------------------------------------------- /slides/images/game-center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/game-center.png -------------------------------------------------------------------------------- /slides/images/hayday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/hayday.png -------------------------------------------------------------------------------- /slides/images/hybrid-network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/hybrid-network.png -------------------------------------------------------------------------------- /slides/images/lan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/lan.jpg -------------------------------------------------------------------------------- /slides/images/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/nodejs.png -------------------------------------------------------------------------------- /slides/images/overvolt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/overvolt.png -------------------------------------------------------------------------------- /slides/images/points/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/points/p1.png -------------------------------------------------------------------------------- /slides/images/points/p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/points/p2.png -------------------------------------------------------------------------------- /slides/images/points/p3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/points/p3.png -------------------------------------------------------------------------------- /slides/images/points/p4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/points/p4.png -------------------------------------------------------------------------------- /slides/images/points/p5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/points/p5.png -------------------------------------------------------------------------------- /slides/images/pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/pro.png -------------------------------------------------------------------------------- /slides/images/racer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/racer.png -------------------------------------------------------------------------------- /slides/images/ruzzle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/ruzzle.png -------------------------------------------------------------------------------- /slides/images/smartfoxserver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/smartfoxserver.png -------------------------------------------------------------------------------- /slides/images/socketio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/images/socketio.png -------------------------------------------------------------------------------- /slides/slides.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lotti/codemotion2015/cfbceed12f2f8700f45370d94708302820a47973/slides/slides.pptx --------------------------------------------------------------------------------