commit cfa29297a4c9efdd1a4c1261c7590ed1cdb7c44d Author: febbweiss Date: Thu Sep 28 09:27:36 2017 +0000 Initialization diff --git a/README.md b/README.md new file mode 100644 index 0000000..064ecaa --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ + ,-----.,--. ,--. ,---. ,--.,------. ,------. + ' .--./| | ,---. ,--.,--. ,-| || o \ | || .-. \ | .---' + | | | || .-. || || |' .-. |`..' | | || | \ :| `--, + ' '--'\| |' '-' '' '' '\ `-' | .' / | || '--' /| `---. + `-----'`--' `---' `----' `---' `--' `--'`-------' `------' + ----------------------------------------------------------------- + + +Hi there! Welcome to Cloud9 IDE! + +To get you started, we included a small hello world application. + +1) Open the hello-world.html file + +2) Click on the Preview button to open a live preview pane + +3) Make some changes to the file, save, watch the preview, and have fun! + +Happy coding! +The Cloud9 IDE team + + +## Support & Documentation + +Visit http://docs.c9.io for documentation, or http://support.c9.io for support. +To watch some training videos, visit http://www.youtube.com/user/c9ide diff --git a/css/wordfighters.css b/css/wordfighters.css new file mode 100644 index 0000000..e09ad07 --- /dev/null +++ b/css/wordfighters.css @@ -0,0 +1,414 @@ +.letter { + width: 62px; + height: 62px; + background-image: url( "../images/scrabble_sprite.png" ); + background-position: -372px -186px; + display: inline-block; +} + +.blank { + width: 16px; + height: 16px; + display: block; + float: left; +} + +.a { + background-position: 0px 0px; +} +.b { + background-position: -62px 0px; +} +.c { + background-position: -124px 0px; +} +.d { + background-position: -186px 0px; +} +.e { + background-position: -248px 0px; +} +.f { + background-position: -310px 0px; +} +.g { + background-position: -372px 0px; +} +.h { + background-position: 0px -62px; +} +.i { + background-position: -62px -62px; +} +.j { + background-position: -124px -62px; +} +.k { + background-position: -186px -62px; +} +.l { + background-position: -248px -62px; +} +.m { + background-position: -310px -62px; +} +.n { + background-position: -372px -62px; +} +.o { + background-position: 0px -124px; +} +.p { + background-position: -62px -124px; +} +.q { + background-position: -124px -124px; +} +.r { + background-position: -186px -124px; +} +.s { + background-position: -248px -124px; +} +.t { + background-position: -310px -124px; +} +.u { + background-position: -372px -124px; +} +.v { + background-position: 0px -186px; +} +.w { + background-position: -62px -186px; +} +.x { + background-position: -124px -186px; +} +.y { + background-position: -186px -186px; +} +.z { + background-position: -248px -186px; +} + +.hideLetter { + visibility: hidden; +} +.showLetter { + visibility: visible; +} + +#typed { + height: 62px; +} + +#typed span img { + display: none; +} + +#valid div { + float: none; + clear: both; +} + +#valid span { + font-weight: bold; +} + +#valid ul { + list-style-type:none; +} + +#valid li { + display: block; + float: left ; + margin-left:2px; + margin-bottom:2px; + padding:2px; + height: 1em; + text-align: center; +} + +#valid3 li { + width: 2em; +} +#valid4 li { + width: 3em; +} +#valid5 li { + width: 4em; +} +#valid6 li { + width: 5em; +} +#valid7 li { + width: 6em; +} + +#howtoLayout { +} + +#howto { + position:fixed; + _position:absolute; /* hack for internet explorer 6*/ + z-index:1; +} + +.levelChoice { + height: 60%; + opacity: 0.85; + position:relative; + width: 100%; + height: 40px; + margin-bottom: 5px; +} + +.levelChoice:HOVER { + cursor: pointer; +} + +.levelChoice .character { + float: left; +} + +#playground { + height: 96px; + clear: both; +} + +.character { + width: 40px; + height: 40px; + background-image: url( "../images/characters.png" ); + opacity: 0.6; +} + +.character.box_center { + position:absolute; + left: 50%; + top: 50%; + margin-top: -20px; /* moiti� de la hauteur */ + margin-left: -20px; /* moiti� de la largeur */ +} + +.character.E { + background-position: 0px 0px; +} +.character.M { + background-position: -40px 0px; +} +.character.H { + background-position: -80px 0px; +} +.character.X { + background-position: -120px 0px; +} +.character.VS { + background-position: -160px 0px; +} + +#countdown { + position: relative; + margin-left: auto; + margin-right: auto; + width: 48px; + top: 2px; +} + +.clock { + background: transparent url( "../images/font.png" ) no-repeat top left; + height:16px; + width:16px; + float:left; +} + +.n0 { + background-position : 0 0px; +} +.n1 { + background-position : -16px 0; +} +.n2 { + background-position : -32px 0; +} +.n3 { + background-position : -48px 0; +} +.n4 { + background-position : -64px 0; +} +.n5 { + background-position : -80px 0; +} +.n6 { + background-position : -96px 0; +} +.n7 { + background-position : -112px 0; +} +.n8 { + background-position : -128px 0; +} +.n9 { + background-position : -144px 0; +} + +#scoreboard { + position: absolute; + left: 10px; + top: 2px; + width: 96px; + height: 16px; +} + +#scoreboard .n0 { + background-position : -160px 0; +} +#scoreboard .n1 { + background-position : -176px 0; +} +#scoreboard .n2 { + background-position : -192px 0; +} +#scoreboard .n3 { + background-position : -208px 0; +} +#scoreboard .n4 { + background-position : -224px 0; +} +#scoreboard .n5 { + background-position : -240px 0; +} +#scoreboard .n6 { + background-position : -256px 0; +} +#scoreboard .n7 { + background-position : -272px 0; +} +#scoreboard .n8 { + background-position : -288px 0; +} +#scoreboard .n9 { + background-position : -304px 0; +} + +#step_title { + height: 16px; + position: absolute; + left: 50%; + top: 50%; + margin-top: -8px; +} + +.portrait { + width: 264px; + height: 225px; + visibility: hidden; + background-image: url( "../images/portraits.png" ); + background-repeat: no-repeat; + position: relative; + margin-top: -130px; + margin-left: -100px; + top: 50%; + left: 50%; +} + +.portrait.E { + background-position: 0px 0px; +} +.portrait.M { + background-position: -264px 0px; +} +.portrait.H { + background-position: -528px 0px; +} +.portrait.X { + background-position: -792px 0px; +} + +.levelDescription { + position: relative; + clear: both; + padding: 15px; +} + +.levelDescription div.level { + height: 16px; + float: left; +} + +.desc { + position: absolute; + top: 32px; + left: 60px; +} + +.health_bar { + height: 10px; + width: 100px; + position: absolute; + top: 5px; + background-color: black; +} + +.health_level { + height: 8px; + position: relative; + margin: 1px; +} +.health_level.good { + background-color: green; +} +.health_level.middle { + background-color: yellow; +} +.health_level.bad { + background-color: red; +} + +.level { + position: relative; + top: 7px; + left: 7px; + float: right; +} +.highlight { + display: none; +} + +body { + position: fixed; + width: 550px; + left: 50%; + margin-left: -275px; +} + +#waitingGame > div { + display: inline-block; + height: 261px; + float: left; +} + +#level { + width:100%; + float: both; +} + +#label { + width: 100%; +} + +.button { + background-color: white; + border: 2px solid #e7e7e7; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + border-radius: 12%; + margin: auto; + margin-top: 25px; +} \ No newline at end of file diff --git a/images/0_dot.gif b/images/0_dot.gif new file mode 100644 index 0000000..f7237ab Binary files /dev/null and b/images/0_dot.gif differ diff --git a/images/akuma.png b/images/akuma.png new file mode 100644 index 0000000..5a73f15 Binary files /dev/null and b/images/akuma.png differ diff --git a/images/background.png b/images/background.png new file mode 100644 index 0000000..218e12a Binary files /dev/null and b/images/background.png differ diff --git a/images/banner.png b/images/banner.png new file mode 100644 index 0000000..9073078 Binary files /dev/null and b/images/banner.png differ diff --git a/images/characters.png b/images/characters.png new file mode 100644 index 0000000..584dd4a Binary files /dev/null and b/images/characters.png differ diff --git a/images/felicia.png b/images/felicia.png new file mode 100644 index 0000000..4740e1b Binary files /dev/null and b/images/felicia.png differ diff --git a/images/font.png b/images/font.png new file mode 100644 index 0000000..13b7b73 Binary files /dev/null and b/images/font.png differ diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..8b01d09 Binary files /dev/null and b/images/logo.png differ diff --git a/images/portraits.png b/images/portraits.png new file mode 100644 index 0000000..5a49dd3 Binary files /dev/null and b/images/portraits.png differ diff --git a/images/ryu.png b/images/ryu.png new file mode 100644 index 0000000..fa774b8 Binary files /dev/null and b/images/ryu.png differ diff --git a/images/sakura.png b/images/sakura.png new file mode 100644 index 0000000..368c220 Binary files /dev/null and b/images/sakura.png differ diff --git a/images/scrabble_sprite.png b/images/scrabble_sprite.png new file mode 100644 index 0000000..9319380 Binary files /dev/null and b/images/scrabble_sprite.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..76f7f41 --- /dev/null +++ b/index.html @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Search words between 3 and 7 letters +
+
+ + + + + + + + \ No newline at end of file diff --git a/js/countdown.js b/js/countdown.js new file mode 100644 index 0000000..b1d8fd4 --- /dev/null +++ b/js/countdown.js @@ -0,0 +1,84 @@ +var COUNTDOWN = { + mustStop: false, + + init: function( minutes, seconds ) { + COUNTDOWN.minutes = minutes; + COUNTDOWN.seconds = seconds; + COUNTDOWN.mustStop = false; +// $( "#countdown" ).width( ( minutes > 0 ? 90 : 0 ) + 90); +// $( "#countdown" ).css( "background-color", "black" ); + }, + + start: function() { + if( COUNTDOWN.mustStop ) + return; + + COUNTDOWN.running = true; + + var currentMinutes = ""; + var currentSeconds = ""; + var imageMinutes = ""; + var imageSeconds = ""; + + currentMinutes = COUNTDOWN.minutes; + currentSeconds = COUNTDOWN.seconds; + + var nextMinutes = COUNTDOWN.minutes; + var nextSeconds = COUNTDOWN.seconds - 1; + + if( nextSeconds < 0 && nextMinutes > 0 ) { + nextSeconds = 59; + nextMinutes = Math.min(0, nextMinutes -1); + } + + COUNTDOWN.minutes = nextMinutes; + COUNTDOWN.seconds = nextSeconds; + + if( currentMinutes <= 0 && currentSeconds < 10 ) + $( "#countdown" ).css( "background-color", "red" ); + + if(parseInt(currentMinutes) < 10 ) currentMinutes = "0" + currentMinutes; + if(parseInt(currentSeconds) < 10 ) currentSeconds = "0" + currentSeconds; + + for(i = 0; i < String(currentMinutes).length; i++) { + imageMinutes += "
"; + } + + for(i = 0; i < String(currentSeconds).length; i++) { + imageSeconds += "
"; + } + + if( COUNTDOWN.minutes > 0) { + $("#subMinutes").empty().removeClass( "hide" ).append( imageMinutes );; + $(".clock.clock.separator").removeClass( "hide" ); + } else { + $("#subMinutes").empty().addClass( "hide" ); + $(".clock.clock.separator").addClass( "hide" ); + } + + $("#subSeconds").empty().append( imageSeconds ); + + if( nextMinutes >= 0 && nextSeconds >= 0 ) + setTimeout( "COUNTDOWN.start()", 1000 ); + else + COUNTDOWN.callback(); + }, + + add: function(seconds) { + console.log( "Adding " + seconds + " seconds to countdown" ); + COUNTDOWN.seconds = COUNTDOWN.seconds + seconds; + }, + + setTime: function( seconds ) { + console.log( "Setting " + seconds + " seconds to countdown" ); + COUNTDOWN.seconds = seconds; + }, + + stop: function() { + COUNTDOWN.mustStop = true; + }, + + callback: function() { + console.log( "COUNTDOWN.callback" ); + } +}; \ No newline at end of file diff --git a/js/dictionary.js b/js/dictionary.js new file mode 100644 index 0000000..b3cd65f --- /dev/null +++ b/js/dictionary.js @@ -0,0 +1,52 @@ +var dictionary = { + 'en' : { + 'wordfighter.howto.1' : 'When you click on the "Start" button, a combinaison of letters is generated.', + 'wordfighter.howto.2' : 'The goal is to retrieve a maximum of words with these letters using your keyboard.', + 'wordfighter.howto.3' : 'To validate a word, simply press the "Enter" key.', + 'wordfighter.howto.4' : 'To get new letters, press the "Space" bar.', + 'wordfighter.howto.E' : 'Search words between 3 and 7 letters', + 'wordfighter.howto.M' : 'Search words between 3 and 6 letters', + 'wordfighter.howto.H' : 'Search words between 4 and 7 letters', + 'wordfighter.howto.X' : 'No escape ! You can\'t have new letters before reach all words !', + 'wordfighter.title' : 'Word Fighters', + 'wordfighter.letters' : '%s letters', + 'game.no.score' : 'No highscore', + 'game.waiting.opponent' : 'Waiting for your opponent', + 'game.waiting.ready' : 'Get ready !!', + 'game.start' : 'Start !!', + 'game.win' : 'You win !!', + 'game.loose' : 'You loose !!', + 'game.draw' : 'Draw !!', + 'game.replay' : 'Play again', + 'game.level.E' : 'Easy', + 'game.level.M' : 'Medium', + 'game.level.H' : 'Hard', + 'game.level.X' : 'Extrem', + 'game.choose.level' : 'Choose your level' + }, + 'fr' : { + 'wordfighter.howto.1' : 'Dès que vous cliquez sur le bouton "Jouer", une combinaison de lettres est générée.', + 'wordfighter.howto.2' : 'Le but est de retrouver le maximum de mots avec ces lettres en utilisant le clavier.', + 'wordfighter.howto.3' : 'Pour valider un mot, utilisez simplement la touche "Entrer".', + 'wordfighter.howto.4' : 'Pour avoir un nouveau tirage, pressez la touche "Espace".', + 'wordfighter.howto.E' : 'Trouver des mots de 3 à 7 lettres', + 'wordfighter.howto.M' : 'Trouver des mots de 3 à 6 lettres', + 'wordfighter.howto.H' : 'Trouver des mots de 4 à 7 lettres', + 'wordfighter.howto.X' : 'Il n\'y a pas déchappatoire! Vous ne pouvez pas changer vos lettres tant que tous les mots n\'ont pas été trouvés!', + 'wordfighter.title' : 'Word Fighters', + 'wordfighter.letters' : '%s lettres', + 'game.no.score' : 'Aucun score', + 'game.waiting.opponent' : 'En attente de votre adversaire', + 'game.waiting.ready' : 'Pret !!', + 'game.start' : 'Partez !!', + 'game.win' : 'Victoire !!', + 'game.loose' : 'Vous avez perdu !!', + 'game.draw' : 'Match nul !!', + 'game.replay' : 'Rejouer', + 'game.level.E' : 'Facile', + 'game.level.M' : 'Intermediaire', + 'game.level.H' : 'Diffile', + 'game.level.X' : 'Extreme', + 'game.choose.level' : 'Choisissez votre niveau' + } +} \ No newline at end of file diff --git a/js/fighters.js b/js/fighters.js new file mode 100644 index 0000000..399da9f --- /dev/null +++ b/js/fighters.js @@ -0,0 +1,563 @@ +var PLAYGROUND_WIDTH = 384; +var PLAYGROUND_HEIGHT = 96; +var FIGHTER_STD_WIDTH = 82; +var FIGHTER_EXT_WIDTH = 126; +var FIGHTER_EXT_WIDTH_2 = 136; +var FIGHTER_EXT_WIDTH_3 = 95; +var FIGHTER_EXT_WIDTH_4 = 105; +var FIGHTER_EXT_WIDTH_5 = 86; +var FIGHTER1_POSX = PLAYGROUND_WIDTH / 2 - (FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH) / 2 - FIGHTER_STD_WIDTH; +var FIGHTER2_POSX = PLAYGROUND_WIDTH / 2 + (FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH) / 2; +var COUNTDOWN_WIDTH = 48; +var COUNTDOWN_POSX = (PLAYGROUND_WIDTH - COUNTDOWN_WIDTH) / 2; +var HEALTH_REFRESH_RATE = 15; +var FIGHTER_HEALTH = 60; +var LOOP_COUNT_REFRESH = 66; +var fighter1 = null; +var fighter2 = null; +var loopCount = 0; + +var fighters = new Array(); + +$(function(){ + //Playground Sprites + var background = new $.gameQuery.Animation({imageURL: "images/background.png", offsety: PLAYGROUND_HEIGHT * Math.floor(Math.random()*11)}); + + $("#playground").playground({height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, keyTracker: true}); + + $.playground().addGroup("background", {width: PLAYGROUND_WIDTH, height: PLAYGROUND_HEIGHT}) + .addSprite( "background1", + {posx: 0, posy: 0, + height: PLAYGROUND_HEIGHT, width: PLAYGROUND_WIDTH, + animation: background}) + .end() + .addGroup("fighters", {width: PLAYGROUND_WIDTH, height: PLAYGROUND_HEIGHT}) + .end() + .addGroup( "hud", {width: PLAYGROUND_WIDTH, height: PLAYGROUND_HEIGHT}) + .end(); + + $("#hud").append("
"); + $("#hud").append("
"); + + $.playground().registerCallback(function(){ + if( fighter1 ) + updateHealth( $("#player1_health_level"), fighter1.health / fighter1.maxHealth ); + if( fighter2 ) { + updateHealth( $("#player2_health_level"), fighter2.health / fighter2.maxHealth ); + //$("#player2_health_level").css( "margin-left", ( 100 - (fighter2.health / fighter2.maxHealth) * 100) ); + } + loopCount++; + if( loopCount == LOOP_COUNT_REFRESH ) { + loopCount = 0; + var fighter = fighters[ "fighter1" ]; + if( fighter && fighter.isIdle() ) { + fighter.node.width( FIGHTER_STD_WIDTH ); + fighter.node.x( FIGHTER1_POSX ); + } + fighter = fighters[ "fighter2" ]; + if( fighter && fighter.isIdle() ) { + fighter.node.width( FIGHTER_STD_WIDTH ); + fighter.node.x( FIGHTER2_POSX ); + } + } + }, HEALTH_REFRESH_RATE); + + $.playground().startGame( function() {}); + + addFighter = function( fighter) { + $("#fighters").addSprite("fighter1", {animation: fighter.animations["idle"], posx:FIGHTER1_POSX, posy: 15, width: FIGHTER_STD_WIDTH, height: FIGHTER_STD_WIDTH}); + fighter.node = $("#fighter1"); + fighter1 = fighter; + fighters[ "fighter1" ] = fighter; + }; + + addFighter2 = function( fighter ) { + $("#fighters").addSprite("fighter2", {animation: fighter.animations["idle"], posx:FIGHTER2_POSX, posy: 15, width: FIGHTER_STD_WIDTH, height: FIGHTER_STD_WIDTH}); + fighter.node = $("#fighter2"); + $("#fighter2").fliph(true); + fighter2 = fighter; + fighters[ "fighter2" ] = fighter; + }; + + addScoreBoard = function() { + $("#hud").append("
"); + }; + + addHealthBars = function() { + $("#hud").append("
"); + $("#hud").append("
"); + }; + + updateHealth = function( HTMLDiv, health ) { + HTMLDiv.removeClass(); + HTMLDiv.addClass("health_level"); + if( health > 2/3) + HTMLDiv.addClass("good"); + else if( health > 1/3) + HTMLDiv.addClass("middle"); + else + HTMLDiv.addClass("bad"); + HTMLDiv.width( (health * 100) + "%" ); + }; + + display_text = function( text, divId = "#step_title", offset = 1, changePosition = true ) { + var message = text.toLowerCase(); + var divHTML = $(divId); + var html = ""; + var yPos = offset * 16; + + for( var i = 0; i < message.length; i++ ) { + var letter = message[i]; + var x = ((97 - message.charCodeAt(i)) * 16); + if( letter == " " ) + html += "
"; + else if( letter == "!" ) + html += "
"; + else + html += "
"; + } + + divHTML.empty(); + divHTML.width( (text.length * 16) + "px"); + if( changePosition ) { + divHTML.css( "margin-left", "-" + (text.length * 8) + "px"); + } + divHTML.append( html ); + }; + + hide_text = function() { + $("#step_title").empty(); + }; +}); + +//Game objects: +function Fighter(){ + + this.node = null; + this.animations = new Array(); + this.maxHealth = FIGHTER_HEALTH; + this.health = FIGHTER_HEALTH; + this.idle_state = false; + + this.isIdle = function() { + return this.idle_state; + }; + this.setIdle = function( state ) { + this.idle_state = state; + }; + this.start = function() { + this.node.setAnimation(this.animations["start"], + function(node) { + fighters[ node.id ].idle(); + }); + }; + this.idle = function() { + this.node.setAnimation(this.animations["idle"]); + this.setIdle( true ); + }; + this.punch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["punch"], + function(node) { + fighters[ node.id ].idle(); + }); + }; + this.kick = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["kick"], + function(node) { + fighters[ node.id ].idle(); + }); + }; + this.special = function() {}; + this.victory = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["victory"]); + }; + this.loose = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["loose"]); + }; + this.ouch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["ouch"], + function(node) { + fighters[ node.id ].idle(); + }); + }; + this.laught = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + this.node.setAnimation(this.animations["laught"], + function(node) { + fighters[ node.id ].idle(); + }); + }; +}; + +function Ryu(){ + this.animations["start"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 8, offsety: 0, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 7, offsety: 82, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory2"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 4, offsety: 82, offsetx: 246, delta: FIGHTER_STD_WIDTH, rate: 200, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["idle"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 6, offsety: 164, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL}); + this.animations["punch"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 6, offsety: 246, delta: FIGHTER_EXT_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["kick"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 7, offsety: 328, delta: FIGHTER_EXT_WIDTH_2, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["ouch"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 4, offsety: 410, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["laught"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 7, offsety: 492, delta: FIGHTER_EXT_WIDTH_3, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 9, offsety: 574, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose2"] = new $.gameQuery.Animation({imageURL: "images/ryu.png", numberOfFrame: 6, offsety: 656, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE}); +}; +Ryu.prototype = new Fighter(); +Ryu.prototype.punch = function() { + this.node.width( FIGHTER_EXT_WIDTH ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["punch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Ryu.prototype.kick = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_2 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_2 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["kick"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x( FIGHTER_EXT_WIDTH_2 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Ryu.prototype.laught = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_3 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_3 - FIGHTER_STD_WIDTH),true); + } + this.node.setAnimation(this.animations["laught"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH_3 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Ryu.prototype.loose = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["loose"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["loose2"]); + }); +} +Ryu.prototype.victory = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.setAnimation(this.animations["victory"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["victory2"]); + }); +} + +function Sakura(){ + this.animations["start"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 9, offsety: 334, delta: FIGHTER_EXT_WIDTH_3, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 7, offsety: 82, delta: FIGHTER_EXT_WIDTH_5, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory2"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 4, offsety: 82, offsetx: 258, delta: FIGHTER_EXT_WIDTH_5, rate: 200, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["idle"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 5, offsety: 0, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL}); + this.animations["punch"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 5, offsety: 166, delta: FIGHTER_EXT_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["kick"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 6, offsety: 252, delta: FIGHTER_EXT_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["ouch"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 4, offsetx: 492, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); +// this.animations["laught"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 7, offsety: 492, delta: FIGHTER_EXT_WIDTH_3, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 10, offsety: 412, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE }); +// this.animations["loose2"] = new $.gameQuery.Animation({imageURL: "images/sakura.png", numberOfFrame: 6, offsety: 656, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE}); +}; +Sakura.prototype = new Fighter(); +Sakura.prototype.victory = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.setAnimation(this.animations["victory"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["victory2"]); + }); +} +Sakura.prototype.punch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["punch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Sakura.prototype.kick = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["kick"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Sakura.prototype.laught = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_3 ); + if( this.node.fliph() ) { + this.node.x(-(FIGHTER_EXT_WIDTH_3 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["start"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnodex(FIGHTER_EXT_WIDTH_3 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Sakura.prototype.loose = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["loose"]); +} +function Akuma(){ + this.animations["start"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 11, offsety: 82, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 10, offsety: 328, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory2"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 8, offsety: 328, offsetx: 162, delta: FIGHTER_STD_WIDTH, rate: 200, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["idle"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 11, offsety: 0, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL}); + this.animations["punch"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 5, offsety: 164, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["kick"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 7, offsety: 246, delta: FIGHTER_EXT_WIDTH_2, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["ouch"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 7, offsety: 576, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); +// this.animations["laught"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 7, offsety: 492, delta: FIGHTER_EXT_WIDTH_3, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 9, offsety: 412, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose2"] = new $.gameQuery.Animation({imageURL: "images/akuma.png", numberOfFrame: 3, offsety: 494, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE}); +}; +Akuma.prototype = new Fighter(); +Akuma.prototype.punch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["punch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Akuma.prototype.kick = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_2 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_2 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["kick"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH_2 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Akuma.prototype.victory = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.setAnimation(this.animations["victory"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["victory2"]); + }); +} +Akuma.prototype.loose = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["loose"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["loose2"]); + }); +} +Akuma.prototype.ouch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x(-(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["ouch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +function Felicia(){ + this.animations["start"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 10, offsety: 82, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 10, offsety: 328, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["victory2"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 5, offsety: 328, offsetx: 410, delta: FIGHTER_STD_WIDTH, rate: 200, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["idle"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 8, offsety: 0, delta: FIGHTER_STD_WIDTH, rate: 200, type: $.gameQuery.ANIMATION_HORIZONTAL}); + this.animations["punch"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 6, offsety: 164, delta: FIGHTER_EXT_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["kick"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 7, offsety: 246, delta: FIGHTER_EXT_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["ouch"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 5, offsety: 492, delta: FIGHTER_EXT_WIDTH_4, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); +// this.animations["laught"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 7, offsety: 492, delta: FIGHTER_EXT_WIDTH_3, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE | $.gameQuery.ANIMATION_CALLBACK}); + this.animations["loose"] = new $.gameQuery.Animation({imageURL: "images/felicia.png", numberOfFrame: 6, offsety: 410, delta: FIGHTER_STD_WIDTH, rate: 150, type: $.gameQuery.ANIMATION_HORIZONTAL | $.gameQuery.ANIMATION_ONCE }); +}; +Felicia.prototype = new Fighter(); +Felicia.prototype.punch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["punch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Felicia.prototype.kick = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH ); + if( this.node.fliph() ) { + this.node.x(-(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["kick"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} +Felicia.prototype.victory = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.setAnimation(this.animations["victory"], + function(node) { + fighters[ node.id ].node.setAnimation(fighters[ node.id ].animations["victory2"]); + }); +} +Felicia.prototype.ouch = function() { + if( !this.isIdle() ) + return; + this.setIdle( false ); + + this.node.width( FIGHTER_EXT_WIDTH_4 ); + if( this.node.fliph() ) { + this.node.x( -(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH), true); + } + this.node.setAnimation(this.animations["ouch"], + function(node) { + var HTMLnode = fighters[ node.id ].node; + HTMLnode.width( FIGHTER_STD_WIDTH ); + if( HTMLnode.fliph() ) { + HTMLnode.x(FIGHTER_EXT_WIDTH_4 - FIGHTER_STD_WIDTH, true); + } + fighters[ node.id ].idle(); + }); +} \ No newline at end of file diff --git a/js/lexik.js b/js/lexik.js new file mode 100644 index 0000000..e69de29 diff --git a/js/mock.js b/js/mock.js new file mode 100644 index 0000000..d967eab --- /dev/null +++ b/js/mock.js @@ -0,0 +1,207 @@ + var lexik = null; + var enigma = null; + var score = 0; + var time = 0; + + $(document).ready(function() { + var oReq = new XMLHttpRequest(); + oReq.open("GET", "resources/french", true); + oReq.responseType = "arraybuffer"; + + oReq.onload = function(oEvent) { + var arrayBuffer = oReq.response; + + // if you want to access the bytes: + var byteArray = new Uint8Array(arrayBuffer); + var gunzip = new Zlib.Gunzip(new Uint8Array(byteArray)); + var plain = gunzip.decompress(); + lexik = JSON.parse(Utf8ArrayToStr(plain)); + }; + + oReq.send(); +}); + +function generateEnigma(level) { + var min = 3, max = 7; + + switch( level ) { + case 'E' : + min = 3; + max = 7; + break; + case 'M' : + min = 3; + max = 6; + break; + case 'H' : + min = 4; + max = 7; + break; + default : + min = 3; + max = 6; + } + + var mustRun = false; + var letters; + var allWords = {}; + do { + letters = getRandomSet(max); + allWords = getWords2param(letters, min); + + var wordsCount = 0; + for (var i = min; i < max + 1; i++) { + var words = allWords[i]; + if (words != null) { + wordsCount += words.length; + } + } + mustRun = wordsCount < (max + min) * 0.7; + } while (mustRun); + return {letters: letters, words: allWords, minLength: min, maxLength: max}; +} + +function getRandomSet( maxLetter) { + var statistics = lexik.statistics; + var max = 0.0; + for (var i = 0; i < 26; i++) { + max += statistics[i]; + } + var letters = []; + for (var i = 0; i < maxLetter; i++) { + letters[i] = getRandomLetter(max, statistics); + } + return letters.sort(); +} + +function getRandomLetter(max, statistics) { + var r = Math.random() * max; + max = 0.0; + for (var i = 0; i < 26; i++) { + max += statistics[i]; + if (r < max) { + return String.fromCharCode(i + 97); + } + } + return 'z'; +} + +function getWords2param(letters, minimum) { + var words = []; + for (var i = letters.length; i > 2; i--) { + var newWords = getWords(letters, minimum, i); + if (newWords != null && newWords.length > 0 ) { + for( var j = 0; j < newWords.length; j++) { + if( words.indexOf(newWords[j]) == -1 ) { + words.push(newWords[j]); + } + } + } + } + + var lists = {}; + for (var i = 0; i < words.length; i++) { + var word = words[i]; + var list = lists[word.length]; + if (list === undefined) { + list = []; + lists[word.length] = list; + } + list.push(word); + } + for (var i = letters.length; i > 2; i--) { + var list = lists[i]; + if (list !== undefined) { + list = list.sort(); + } + } + return lists; +} + +function getWords(letters, minimum, size) { + if (size < minimum) { + return null; + } + + var setSize = letters.length; + + if (size == setSize) { + var currentNode = lexik.nodes.nodes[letters[0]]; + if (currentNode == null) { + return null; + } + for (var i = 1; i < setSize; i++) { + currentNode = currentNode.nodes[letters[i]]; + if (currentNode == null) { + return null; + } + if (i == setSize - 1) { + return currentNode.words; + } + } + return null; + } + + var results = []; + for (var i = 0; i < setSize - size; i++) { + for (var j = 0; j < setSize; j++) { + var words = getWords(letters.slice(0,j).concat(letters.slice(j+1)), minimum, size - i); + if (words != null && words.length > 0) { + results = results.concat(words); + } + } + } + return results.sort(); +} + +$.mockjax({ + url: "/wordFighter/levelChoice", + status: 200 +}); + +$.mockjax({ + url: "/wordFighter/ready", + status: 200 +}); + +$.mockjax({ + url: "/wordFighter/newEnigma", + contentType: "application/json", + response: function(data) { + enigma = generateEnigma(data.data.level); + if( time != 0 ) { + enigma.remaining_time = 60 - (new Date().getTime() - time) / 1000; + score = 0; + } else { + enigma.remaining_time = 60; + } + time = new Date().getTime(); + this.responseText = JSON.stringify(enigma) + } +}); + +$.mockjax( { + url: '/wordFighter/get_ready', + contentType: 'text/html', + responseText: '
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
' +}) + +$.mockjax( { + url: '/wordFighter/gameOver', + contentType: 'text/html', + responseText: '' +}); \ No newline at end of file diff --git a/js/scoreboard.js b/js/scoreboard.js new file mode 100644 index 0000000..815cfe8 --- /dev/null +++ b/js/scoreboard.js @@ -0,0 +1,44 @@ +var SCOREBOARD = { + score: 0, + scoreLength: 6, + + init: function(size) { + if( typeof size !== "undefined" ) + SCOREBOARD.scoreLength = size; + SCOREBOARD.score = 0; + SCOREBOARD.set_score( 0 ); + }, + + add: function(addToScore, div) { + SCOREBOARD.set_score( SCOREBOARD.score + addToScore, div); + }, + + set_score: function( score, div ) { + var currentScore = ""; + var imageScore = ""; + + SCOREBOARD.score = score; + currentScore = SCOREBOARD.pad(); + + for(i = 0; i < String(currentScore).length; i++) { + imageScore += "
"; + } + + if( typeof div === "undefined" ) + div = $(".subScoreboard"); + div.empty(); + div.append( imageScore ); + }, + + pad: function() { + var str = '' + SCOREBOARD.score; + while (str.length < SCOREBOARD.scoreLength) { + str = '0' + str; + } + return str; + }, + + callback: function() { + console.log( "SCOREBOARD.callback" ); + } +}; \ No newline at end of file diff --git a/js/wordfighters.js b/js/wordfighters.js new file mode 100644 index 0000000..f960cd5 --- /dev/null +++ b/js/wordfighters.js @@ -0,0 +1,440 @@ +var DURATION = 60; + +var WordFighter = { + id: null, + word: "", + started: false, + activeKeypress: false, + level: 'E', + answers: null, + letters: null, + score: 0, + combo: 0, + opponentCombo: 0, + first: true, + opponentLevel: null, + startDate: null, + + toggle_howto: function() { + $('#howto').slideToggle(); + }, + + change_level: function( chosenLevel ) { + WordFighter.level = chosenLevel; + + switch( chosenLevel ) { + case 'E' : + $("#valid3header").show(); + $("#valid3column").show(); + $("#valid7header").show(); + $("#valid7column").show(); + break; + case 'M' : + $("#valid3header").show(); + $("#valid3column").show(); + $("#valid7header").hide(); + $("#valid7column").hide(); + break; + case 'H' : + $("#valid3header").hide(); + $("#valid3column").hide(); + $("#valid7header").show(); + $("#valid7column").show(); + break; + case 'X' : + $("#valid3header").show(); + $("#valid3column").show(); + $("#valid7header").hide(); + $("#valid7column").hide(); + break; + } + }, + + notify_dual: function() { + $.ajax({ + url: '/wordFighter/levelChoice', + data: { level: WordFighter.level }, + success: function(data){ + $("#waitingGame").load('/wordFighter/get_ready', function() { + console.log( "Current opponent : " + WordFighter.opponentLevel ); + console.log( data ); + display_text('versus', '#howToPlay', 1, false); + $("#fighter1portrait").addClass( WordFighter.level ); + $("#fighter1portrait").css( "visibility", "visible"); + addFighter( WordFighter.get_fighter( WordFighter.level) ); + addScoreBoard(); + WordFighter.opponentLevel = WordFighter.get_random_fighter(); + setTimeout( function() { + WordFighter.start_game(); + }, 3000 ); + WordFighter.set_opponent(); + }); + } + }); + }, + + get_fighter : function(level) { + switch( level ) { + case 'E' : + return new Sakura(); + case 'M' : + return new Ryu(); + case 'H' : + return new Felicia(); + case 'X' : + return new Akuma(); + } + }, + + get_random_fighter : function() { + var levels = new Array(); + levels[ 0 ] = 'E'; + levels[ 1 ] = 'M'; + levels[ 2 ] = 'H'; + levels[ 3 ] = 'X'; + return levels[ Math.floor(Math.random() * 4) ]; + }, + + set_opponent: function() { + var fighter2Div = $("#fighter2portrait"); + if( fighter2Div != "undefined" && WordFighter.opponentLevel != null ){ + fighter2Div.addClass(WordFighter.opponentLevel); + fighter2Div.css( "visibility", "visible"); + addFighter2( WordFighter.get_fighter( WordFighter.opponentLevel ) ); + } + }, + + hit_opponent: function( hit ) { + fighter2.ouch(); + fighter2.health = fighter2.health - hit; + }, + + start_game: function() { + + $("#waitingGame").hide(); + $("#gamePanel").show(); + $("#start").attr("disabled","disabled"); + $("#level").attr("disabled","disabled"); + + fighter1.start(); + fighter2.start(); + + display_text(game_waiting_ready); + + WordFighter.activeKeypress = false; + WordFighter.clean(); + WordFighter.first = true; + WordFighter.init_score(); + COUNTDOWN.init(0, DURATION); + SCOREBOARD.init(); + + setTimeout( function() { + WordFighter.new_word(); + COUNTDOWN.callback = function() { + $('#start').removeAttr('disabled'); + $('#level').removeAttr('disabled'); + WordFighter.game_over(); + }; + }, 3000) + }, + + setLetter: function( index, character ) { + $( "#letter" + index ).removeClass(); + $( "#letter" + index ).addClass( "letter" ); + $( "#letter" + index ).addClass( character ); + }, + + keypressedHandler: function( event ) { + if( WordFighter.activeKeypress ) + return false; + + WordFighter.activeKeypress = true; + + if( event.which == 32 && WordFighter.level != 'X' ) { // space + while( WordFighter.erase() ); + WordFighter.started = false; + WordFighter.new_word(); + WordFighter.activeKeypress = false; + return true; + } + + if( event.which == 13 ) { // enter + WordFighter.check_word(); + WordFighter.activeKeypress = false; + return true; + } + + if( event.which == 8 && !$.browser.safari) { // backspace + if( WordFighter.word.length > 0 ) { + WordFighter.erase(); + WordFighter.activeKeypress = false; + } + return false; + } + + var character = String.fromCharCode(event.which); + + for( var index = 1; index < 8; index++ ) + { + if( WordFighter.process( index, character, "hide" ) ) { + $( "#typed" + (WordFighter.word.length + 1) ).show(); + $( "#typed" + (WordFighter.word.length + 1) ).addClass( character ); + WordFighter.word += character; + WordFighter.activeKeypress = false; + return true; + } + } + + WordFighter.activeKeypress = false; + + return true; + }, + // Hack for Chrome + prevent_backspace: function( event ) { + if( event.which == 8 ) { // backspace + if( WordFighter.word.length > 0 ) { + WordFighter.erase(); + WordFighter.activeKeypress = false; + } + return false; + } + }, + + clean: function() { + for( var index = 1; index < 8; index++ ) { + var character = WordFighter.word.charAt( index ); + $( "#typed" + WordFighter.word.length ).removeClass( character ); + $( "#letter" + index ).removeClass(); + $( "#letter" + index ).addClass( "letter" ); + } + }, + + erase: function() { + var character = WordFighter.word.charAt( WordFighter.word.length - 1); + for( var index = 1; index < 8; index++ ) + { + if( WordFighter.process( index, character, "show" ) ) { + $( "#typed" + WordFighter.word.length ).hide(); + $( "#typed" + WordFighter.word.length ).removeClass( character ); + WordFighter.word = WordFighter.word.substring(0, WordFighter.word.length - 1); + return true; + } + } + + return false; + }, + + process: function( index, character, visibility ) { + if( $( "#letter" + index ).hasClass( character ) ) + { + if( ( visibility === "hide" && $( "#letter" + index ).hasClass( "hideLetter" ) ) + || ( visibility === "show" && $( "#letter" + index ).hasClass( "showLetter" ) ) ) { + return false; + } + + $( "#letter" + index ).addClass( visibility + "Letter"); + $( "#letter" + index ).removeClass( visibility === "show" ? "hideLetter" : "showLetter" ); + return true; + } + + return false; + }, + + new_word: function() { + + if( WordFighter.started ) { + return false; + } + + WordFighter.combo = 0; + $.ajax({ + url: '/wordFighter/newEnigma', + data: {level: WordFighter.level}, + success: function(data){ + console.log("Ajax : "); + console.log(data); + WordFighter.letters = data.letters; + + for( i = 1; i < WordFighter.letters.length + 1; i++ ) + { + WordFighter.setLetter( i, data.letters[ i - 1 ] ) + } + + WordFighter.answers = data.words; + + var rest = 0; + var total = 0; + for( var i = 3; i < 8; i++ ) { + total += $( "#valid" + i).length; + rest += $( "#valid" + i).find( ":empty" ).length; + } + + if( !WordFighter.first ) { + if( rest == 0) { + COUNTDOWN.add( total * 5 ); + WordFighter.change_score( WordFighter.score + total * 5 ); + } else { + if( rest / total < 0.5 ) + fighter2.kick(); + else + fighter2.punch(); + fighter1.ouch(); + WordFighter.change_score( Math.max( 0, WordFighter.score -5 * rest ) ); + } + } + + for( i = data.minLength; i < data.maxLength +1; i++ ) + { + $( "#valid" + i ).empty(); + var obj = data.words[i]; + var count = 0; + if( obj != undefined ) + count = obj.length; + + for( j = 0; j < count; j++ ) + { + $( "#valid" + i ).append( "
  • "); + } + } + + + WordFighter.started = true; + + if( WordFighter.first ) { + WordFighter.startDate = new Date(); + COUNTDOWN.start(); + + display_text( game_start ); + setTimeout( function() { + hide_text(); + }, 1500); + WordFighter.first = false; + } + + } + }); + }, + + check_word: function() { + var lAnswers = WordFighter.answers[ WordFighter.word.length ]; + var position = -1; + if( lAnswers ) + position = lAnswers.indexOf( WordFighter.word ); + if( position == -1 ) { + WordFighter.combo = 0; + WordFighter.activeKeypress = true; + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + return false; + } + else { + WordFighter.activeKeypress = true; + if( $("#valid" + WordFighter.word.length + "-" + position).text().length == 0 ) { + WordFighter.combo++; + if( ( WordFighter.combo % 3 ) == 0 ) + fighter1.kick(); + else + fighter1.punch(); + WordFighter.hit_opponent( WordFighter.word.length ); + $("#valid" + WordFighter.word.length + "-" + position).append( WordFighter.word ); + WordFighter.change_score( WordFighter.score + 10 * WordFighter.word.length ); + WordFighter.check_validated(); + } + } + + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + }, + + check_validated: function() { + var rest = 0; + for( var i = 3; i < 8; i++ ) { + rest += $( "#valid" + i).find( ":empty" ).length; + } + + if( rest == 0 ) { + while( WordFighter.erase() ); + WordFighter.started = false; + WordFighter.new_word(); + WordFighter.activeKeypress = false; + } + }, + + game_over: function() { + COUNTDOWN.stop(); + WordFighter.show_game_over(); + WordFighter.activeKeypress = true; + var highscore = true; + var win = WordFighter.score > 0; + + for( i = 3; i < 8; i++ ) + { + var words = WordFighter.answers[i]; + if( words != undefined ) + { + for( j = 0; j < words.length; j++ ) + { + var id = "#valid" + ( words[ j ].length ) + "-" + j; + $( id ).empty(); + $( id ).append( words[ j ] ); + } + } + } + + WordFighter.started = false; + }, + + show_game_over: function() { + $('.button').show(); + /* + $.ajax({ + url: "/wordFighter/gameOver", + data: {level: WordFighter.level}, + success: function(data){ + $("#modalDialog").prepend(data).modal({backdrop: false, show: true}); + + $(".replayButton").bind( "click", function() { + if( WordFighter.mode!="dual") + window.location.href = "/wordFighter/game"; + else + window.location.href = "/wordFighter/invite/" + opponent; + } ); + } + }); + */ + }, + + init_score: function() { + WordFighter.score = 0; + SCOREBOARD.init(); + }, + + change_score: function(score) { + WordFighter.score = score; + SCOREBOARD.set_score( WordFighter.score ); + } +}; + + +function drawText( divHTML, message ) { + var html = ""; + + for( var i = 0; i < message.length; i++ ) { + var letter = message[i]; + var x = ((97 - message.charCodeAt(i)) * 16); + if( letter == " " ) + html += "
    "; + else if( letter == "!" ) + html += "
    "; + else + html += "
    "; + } + + divHTML.css( "width", (message.length * 16) + "px"); + divHTML.css( "margin-left", "-" + (message.length * 8) + "px"); + divHTML.css( "margin-top", "20px"); + divHTML.css( "position", "relative"); + divHTML.css( "left", "50%"); + divHTML.css( "top", "50%"); + divHTML.append( html ); +}; \ No newline at end of file diff --git a/js/wordfighters_multiplayer.js b/js/wordfighters_multiplayer.js new file mode 100644 index 0000000..e681303 --- /dev/null +++ b/js/wordfighters_multiplayer.js @@ -0,0 +1,235 @@ +WordFighter.notify_dual = function() { + $.ajax({ + url: '/wordFighter/levelChoice', + data: { level: WordFighter.level }, + success: function(data){ + $("#waitingGame").load('/wordFighter/ready', function() { + console.log( "Current opponent : " + WordFighter.opponentLevel ); + console.log( data ); + $("#fighter1portrait").addClass( WordFighter.level ); + $("#fighter1portrait").css( "visibility", "visible"); + addFighter( WordFighter.get_fighter( WordFighter.level) ); + if( data.opponentLevel != "undefined" ) { + WordFighter.opponentLevel = data.opponentLevel; + } + WordFighter.set_opponent(); + }); + } + }); +} + +WordFighter.new_word = function() { + + if( WordFighter.started ) { + return false; + } + + WordFighter.combo = 0; + $.ajax({ + url: '/wordFighter/newEnigma', + data: {level: WordFighter.level, mode: WordFighter.mode }, + success: function(data){ + WordFighter.letters = data.letters; + + for( i = 1; i < WordFighter.letters.length + 1; i++ ) + { + WordFighter.setLetter( i, data.letters[ i - 1 ] ) + } + + WordFighter.answers = data.words; + + var rest = 0; + var total = 0; + for( var i = 3; i < 8; i++ ) { + total += $( "#valid" + i).length; + rest += $( "#valid" + i).find( ":empty" ).length; + } + + console.log( data.remaining_time + " seconds" ); + COUNTDOWN.setTime( data.remaining_time); + + for( i = data.minLength; i < data.maxLength +1; i++ ) + { + $( "#valid" + i ).empty(); + var obj = data.words[i]; + var count = 0; + if( obj != undefined ) { + if( WordFighter.mode == "offline" ) + count = obj.length; + else + count = obj; + } + for( j = 0; j < count; j++ ) + { + $( "#valid" + i ).append( "
  • "); + } + } + + WordFighter.started = true; + + if( WordFighter.first ) { + WordFighter.startDate = new Date(); + COUNTDOWN.start(); + + display_text( game_start ); + setTimeout( function() { + hide_text(); + }, 1500); + WordFighter.first = false; + } + + } + }); +} + +WordFighter.check_word = function() { + $.ajax({ + type: "POST", + url: '/wordFighter/check', + data: {suggested: WordFighter.word }, + success: function(data){ + if( data.valid ) + { + WordFighter.combo++; + if( ( WordFighter.combo % 3 ) == 0 ) + fighter1.kick(); + else + fighter1.punch(); + + WordFighter.activeKeypress = true; + $("#valid" + WordFighter.word.length + "-" + data.position).append( WordFighter.word ); + + WordFighter.change_score( data.score ); + fighter1.punch(); + WordFighter.hit_opponent(WordFighter.word.length ); + + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + + WordFighter.check_validated(); + } else { + WordFighter.combo = 0; + WordFighter.activeKeypress = true; + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + } + + fighter1.health = data.fighter1; + fighter2.health = data.fighter2; + + if( fighter1.health == 0 || fighter2.health == 0 ) + WordFighter.game_over(); + + if( data.remaining_time ) + COUNTDOWN.setTime( data.remaining_time ); + } + }); +} + +WordFighter.game_over = function() { + COUNTDOWN.stop(); + WordFighter.activeKeypress = true; + var highscore = true; + var win = WordFighter.score > 0; + + $.ajax({ + url: '/wordFighter/answers', + data: {action: "answers"}, + success: function(data){ + $("#modalDialog").prepend(data.modal).modal({backdrop: false, show: true}); + + $(".replayButton").bind( "click", function() { + if( WordFighter.mode!="dual") + window.location.href = "/wordFighter/game"; + else + window.location.href = "/wordFighter/invite/" + opponent; + } ); + + for( i = data.minLength; i < data.maxLength +1; i++ ) + { + var words = data.answers[i]; + if( words != undefined ) + { + for( j = 0; j < words.length; j++ ) + { + var id = "#valid" + ( words[ j ].length ) + "-" + j; + $( id ).empty(); + $( id ).append( words[ j ] ); + } + } + } + + + WordFighter.answers = null; + + fighter1.health = data.fighter1; + fighter2.health = data.fighter2; + console.log( fighter1.health + " vs " + fighter2.health ); + switch( data.state ) { + case "win" : + fighter1.victory(); + fighter2.loose(); + display_text( game_win ); + break; + case "loose" : + fighter1.loose(); + fighter2.victory(); + display_text( game_loose ); + break; + default : + display_text( game_draw ); + } + } + }); + + WordFighter.started = false; +} + +WordFighter.callback = function(data) { + if( data.id != WordFighter.id && data.action != "replay" ) + return; + + if( data.action != undefined ) { + + if( data.fighter1 != undefined ) + fighter1.health = data.fighter1; + if( data.fighter2 != undefined ) + fighter2.health = data.fighter2; + switch( data.action ) { + case "start" : + addHealthBars(); + $("#waitingGame").show(); + WordFighter.start_game(); + break; + case "join" : + break; + case "opponentLevel" : + WordFighter.opponentLevel = data.level; + WordFighter.set_opponent(); + break; + case "hit" : + case "beat" : + WordFighter.opponentCombo++; + if( (WordFighter.opponentCombo % 3 ) == 0 ) + fighter2.kick(); + else + fighter2.punch(); + fighter1.ouch(); + if( data.action == "beat" ) + WordFighter.game_over(); + break; + case "timeout" : + if( WordFighter.started ) { + var endDate = new Date(); + console.log( WordFighter.startDate.toTimeString() + " - " + endDate.toTimeString() + " = Timeout in " + ( (endDate.getSeconds() - WordFighter.startDate.getSeconds())) + " / " + (endDate.getTime() - WordFighter.startDate.getTime())); + WordFighter.game_over(); + } + break; + case "replay" : + $(".replayButton").bind( "click", function() { + window.location.href = '/wordFighter/game/' + data.id; + }) + break; + } + } +} \ No newline at end of file diff --git a/js/wordfighters_single.js b/js/wordfighters_single.js new file mode 100644 index 0000000..3e2569a --- /dev/null +++ b/js/wordfighters_single.js @@ -0,0 +1,172 @@ +WordFighter.notify_dual = function() { + $.ajax({ + url: '/wordFighter/levelChoice', + data: { level: WordFighter.level }, + success: function(data){ + $("#waitingGame").load('/wordFighter/ready', function() { + console.log( "Current opponent : " + WordFighter.opponentLevel ); + console.log( data ); + $("#fighter1portrait").addClass( WordFighter.level ); + $("#fighter1portrait").css( "visibility", "visible"); + addFighter( WordFighter.get_fighter( WordFighter.level) ); + addScoreBoard(); + WordFighter.opponentLevel = WordFighter.get_random_fighter(); + setTimeout( function() { + WordFighter.start_game(); + }, 3000 ); + WordFighter.set_opponent(); + }); + } + }); +} + +WordFighter.new_word = function() { + + if( WordFighter.started ) { + return false; + } + + WordFighter.combo = 0; + $.ajax({ + url: '/wordFighter/newEnigma', + data: {level: WordFighter.level}, + success: function(data){ + console.log(data); + WordFighter.letters = data.letters; + + for( i = 1; i < WordFighter.letters.length + 1; i++ ) + { + WordFighter.setLetter( i, data.letters[ i - 1 ] ) + } + + WordFighter.answers = data.words; + + var rest = 0; + var total = 0; + for( var i = 3; i < 8; i++ ) { + total += $( "#valid" + i).length; + rest += $( "#valid" + i).find( ":empty" ).length; + } + + console.log( data.remaining_time + " seconds" ); + COUNTDOWN.setTime( data.remaining_time); + + if( rest / total < 0.5 ) + fighter2.kick(); + else + fighter2.punch(); + fighter1.ouch(); + WordFighter.change_score( data.score ); + + for( i = data.minLength; i < data.maxLength +1; i++ ) + { + $( "#valid" + i ).empty(); + var obj = data.words[i]; + var count = 0; + if( obj != undefined ) + count = obj; + + for( j = 0; j < count; j++ ) + { + $( "#valid" + i ).append( "
  • "); + } + } + + WordFighter.started = true; + + if( WordFighter.first ) { + WordFighter.startDate = new Date(); + COUNTDOWN.start(); + + display_text( game_start ); + setTimeout( function() { + hide_text(); + }, 1500); + WordFighter.first = false; + } + + } + }); +} + +WordFighter.check_word = function() { + $.ajax({ + type: "POST", + url: '/wordFighter/check', + data: {suggested: WordFighter.word }, + success: function(data){ + if( data.valid ) + { + WordFighter.combo++; + if( ( WordFighter.combo % 3 ) == 0 ) + fighter1.kick(); + else + fighter1.punch(); + + WordFighter.activeKeypress = true; + $("#valid" + WordFighter.word.length + "-" + data.position).append( WordFighter.word ); + + WordFighter.change_score( data.score ); + fighter1.punch(); + WordFighter.hit_opponent(WordFighter.word.length ); + + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + + WordFighter.check_validated(); + } else { + WordFighter.combo = 0; + WordFighter.activeKeypress = true; + while(WordFighter.erase()); + WordFighter.activeKeypress = false; + } + + if( data.remaining_time ) + COUNTDOWN.setTime( data.remaining_time ); + } + }); +} + +WordFighter.game_over = function() { + COUNTDOWN.stop(); + WordFighter.activeKeypress = true; + var highscore = true; + var win = WordFighter.score > 0; + + $.ajax({ + url: '/wordFighter/answers', + data: {action: "answers"}, + success: function(data){ + console.log(data); + $("#modalDialog").prepend(data.modal).modal({backdrop: false, show: true}); + + $(".replayButton").bind( "click", function() { + if( WordFighter.mode!=="dual") + window.location.href = "/wordFighter/game"; + else + window.location.href = "/wordFighter/invite/" + opponent; + } ); + + for( i = data.minLength; i < data.maxLength +1; i++ ) + { + var words = data.answers[i]; + if( words != undefined ) + { + for( j = 0; j < words.length; j++ ) + { + var id = "#valid" + ( words[ j ].length ) + "-" + j; + $( id ).empty(); + $( id ).append( words[ j ] ); + } + } + } + + + WordFighter.answers = null; + + SCOREBOARD.set_score( data.score ); + } + }); + + WordFighter.started = false; +} \ No newline at end of file diff --git a/lib/gamequery-0.7.1.js b/lib/gamequery-0.7.1.js new file mode 100644 index 0000000..b9f6416 --- /dev/null +++ b/lib/gamequery-0.7.1.js @@ -0,0 +1,1849 @@ +/* + * gameQuery rev. 0.7.1 + * + * Copyright (c) 2012 Selim Arsever (http://gamequeryjs.com) + * licensed under the MIT-License + */ + +// This allows use of the convenient $ notation in a plugin +(function($) { + + // CSS Feature detection from: Craig Buckler (http://www.sitepoint.com/detect-css3-property-browser-support/) + var cssTransform = false; + + var detectElement = document.createElement("detect"), + CSSprefix = "Webkit,Moz,O,ms,Khtml".split(","), + All = ("transform," + CSSprefix.join("Transform,") + "Transform").split(","); + for (var i = 0, l = All.length; i < l; i++) { + if (detectElement.style[All[i]] === "") { + cssTransform = All[i]; + } + } + + // This prefix can be use whenever needed to namespace CSS classes, .data() inputs aso. + var gQprefix = "gQ_"; + + // Those are the possible states of the engine + var STATE_NEW = 0; // Not yet started for the first time + var STATE_RUNNING = 1; // Started and running + var STATE_PAUSED = 2; // Paused + + /** + * Utility function that returns the radius for a geometry. + * + * @param {object} elem DOM element + * @param {float} angle the angle in degrees + * @return {object} .x, .y radius of geometry + */ + var proj = function (elem, angle) { + switch (elem.geometry){ + case $.gameQuery.GEOMETRY_RECTANGLE : + var b = angle*Math.PI*2/360; + var Rx = Math.abs(Math.cos(b)*elem.width/2*elem.factor)+Math.abs(Math.sin(b)*elem.height/2*elem.factor); + var Ry = Math.abs(Math.cos(b)*elem.height/2*elem.factor)+Math.abs(Math.sin(b)*elem.width/2*elem.factor); + + return {x: Rx, y: Ry}; + } + }; + + /** + * Utility function that checks for collision between two elements. + * + * @param {object} elem1 DOM for the first element + * @param {float} offset1 offset of the first element + * @param {object} elem2 DOM for the second element + * @param {float} offset2 offset of the second element + * @return {boolean} if the two elements collide or not + */ + var collide = function(elem1, offset1, elem2, offset2) { + // test real collision (only for two rectangles...) + if((elem1.geometry == $.gameQuery.GEOMETRY_RECTANGLE && elem2.geometry == $.gameQuery.GEOMETRY_RECTANGLE)){ + + var dx = offset2.x + elem2.boundingCircle.x - elem1.boundingCircle.x - offset1.x; + var dy = offset2.y + elem2.boundingCircle.y - elem1.boundingCircle.y - offset1.y; + var a = Math.atan(dy/dx); + + var Dx = Math.abs(Math.cos(a-elem1.angle*Math.PI*2/360)/Math.cos(a)*dx); + var Dy = Math.abs(Math.sin(a-elem1.angle*Math.PI*2/360)/Math.sin(a)*dy); + + var R = proj(elem2, elem2.angle-elem1.angle); + + if((elem1.width/2*elem1.factor+R.x <= Dx) || (elem1.height/2*elem1.factor+R.y <= Dy)) { + return false; + } else { + var Dx = Math.abs(Math.cos(a-elem2.angle*Math.PI*2/360)/Math.cos(a)*-dx); + var Dy = Math.abs(Math.sin(a-elem2.angle*Math.PI*2/360)/Math.sin(a)*-dy); + + var R = proj(elem1, elem1.angle-elem2.angle); + + if((elem2.width/2*elem2.factor+R.x <= Dx) || (elem2.height/2*elem2.factor+R.y <= Dy)) { + return false; + } else { + return true; + } + } + } else { + return false; + } + }; + + /** + * Utility function computes the offset relative to the playground of a gameQuery element without using DOM's position. + * This should be faster than the standand .offset() function. + * + * Warning: No non-gameQuery elements should be present between this element and the playground div! + * + * @param {jQuery} element the jQuery wrapped DOM element representing the gameQuery object. + * @return {object} an object {x:, y: } containing the x and y offset. (Not top and left like jQuery's .offset()) + */ + var offset = function(element) { + // Get the tileSet offset (relative to the playground) + var offset = {x: 0, y: 0}; + var parent = element[0]; + + while(parent !== $.gameQuery.playground[0] && parent.gameQuery !== undefined) { + offset.x += parent.gameQuery.posx; + offset.y += parent.gameQuery.posy; + parent = parent.parentNode; + } + + return offset + } + + /** + * Utility function computes the index range of the tiles for a tilemap. + * + * @param {jQuery} element the jQuery wrapped DOM element representing the tilemap. + * @param {object} offset an object holding the x and y offset of the tilemap, this is optional and will be computed if not provided. + * @return {object} an object {firstColumn: , lastColumn: , fristRow: , lastRow: } + */ + var visibleTilemapIndexes = function (element, elementOffset) { + if (elementOffset === undefined) { + elementOffset = offset(element); + } + + var gameQuery = element[0].gameQuery; + // Activate the visible tiles + return { + firstRow: Math.max(Math.min(Math.floor(-elementOffset.y/gameQuery.height), gameQuery.sizey), 0), + lastRow: Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].height-elementOffset.y)/gameQuery.height), gameQuery.sizey), 0), + firstColumn: Math.max(Math.min(Math.floor(-elementOffset.x/gameQuery.width), gameQuery.sizex), 0), + lastColumn: Math.max(Math.min(Math.ceil(($.gameQuery.playground[0].width-elementOffset.x)/gameQuery.width), gameQuery.sizex), 0) + } + } + + /** + * Utility function thast computes the buffered zone of a tilemap + * + * @param {jQuery} element the jQuery wrapped DOM element representing the tilemap. + * @param {object} visible an object describing the visible zone + * @return {object} an object {firstColumn: , lastColumn: , fristRow: , lastRow: } + */ + var bufferedTilemapIndexes = function (element, visible) { + var gameQuery = element[0].gameQuery; + + return { + firstRow: Math.max(Math.min(visible.firstRow - gameQuery.buffer, gameQuery.sizey), 0), + lastRow: Math.max(Math.min(visible.lastRow + gameQuery.buffer, gameQuery.sizey), 0), + firstColumn: Math.max(Math.min(visible.firstColumn - gameQuery.buffer, gameQuery.sizex), 0), + lastColumn: Math.max(Math.min(visible.lastColumn + gameQuery.buffer, gameQuery.sizex), 0) + } + } + + /** + * Utility function that creates a tile in the given tilemap + * + * @param {jQuery} tileSet the jQuery element representing the tile map + * @param {integer} row the row index of the tile in the tile map + * @param {integer} column the column index of the tile in the tile map + */ + var addTile = function(tileSet, row, column) { + var gameQuery = tileSet[0].gameQuery; + var name = tileSet.attr("id"); + + var tileDescription; + if(gameQuery.func) { + tileDescription = gameQuery.tiles(row,column)-1; + } else { + tileDescription = gameQuery.tiles[row][column]-1; + } + + var animation; + if(gameQuery.multi) { + animation = gameQuery.animations; + } else { + animation = gameQuery.animations[tileDescription]; + } + + if(tileDescription >= 0){ + tileSet.addSprite($.gameQuery.tileIdPrefix+name+"_"+row+"_"+column, + {width: gameQuery.width, + height: gameQuery.height, + posx: column*gameQuery.width, + posy: row*gameQuery.height, + animation: animation}); + + var newTile = tileSet.find("#"+$.gameQuery.tileIdPrefix+name+"_"+row+"_"+column); + if (gameQuery.multi) { + newTile.setAnimation(tileDescription); + } else { + newTile[0].gameQuery.animationNumber = tileDescription; + } + newTile.removeClass($.gameQuery.spriteCssClass); + newTile.addClass($.gameQuery.tileCssClass); + newTile.addClass($.gameQuery.tileTypePrefix+tileDescription); + } + } + + // Define the list of object/function accessible through $. + $.extend({ gameQuery: { + /** + * This is the Animation Object + */ + Animation: function (options, imediateCallback) { + // private default values + var defaults = { + imageURL: "", + numberOfFrame: 1, + delta: 0, + rate: 30, + type: 0, + distance: 0, + offsetx: 0, + offsety: 0 + }; + + // options extends defaults + options = $.extend(defaults, options); + + // "public" attributes: + this.imageURL = options.imageURL; // The url of the image to be used as an animation or sprite + this.numberOfFrame = options.numberOfFrame; // The number of frames to be displayed when playing the animation + this.delta = options.delta; // The distance in pixels between two frames + this.rate = options.rate; // The rate at which the frames change in miliseconds + this.type = options.type; // The type of the animation.This is a bitwise OR of the properties. + this.distance = options.distance; // The distance in pixels between two animations + this.offsetx = options.offsetx; // The x coordinate where the first sprite begins + this.offsety = options.offsety; // The y coordinate where the first sprite begins + + // Whenever a new animation is created we add it to the ResourceManager animation list + $.gameQuery.resourceManager.addAnimation(this, imediateCallback); + + return true; + }, + + /** + * "constants" for the different types of an animation + */ + ANIMATION_VERTICAL: 1, // Generated by a vertical offset of the background + ANIMATION_HORIZONTAL: 2, // Generated by a horizontal offset of the background + ANIMATION_ONCE: 4, // Played only once (else looping indefinitely) + ANIMATION_CALLBACK: 8, // A callback is exectued at the end of a cycle + ANIMATION_MULTI: 16, // The image file contains many animations + ANIMATION_PINGPONG: 32, // At the last frame of the animation it reverses (if used in conjunction with ONCE it will have no effect) + + // "constants" for the different type of geometry for a sprite + GEOMETRY_RECTANGLE: 1, + GEOMETRY_DISC: 2, + + // basic values + refreshRate: 30, + + /** + * An object to manage resource loading + */ + resourceManager: { + animations: [], // List of animations / images used in the game + sounds: [], // List of sounds used in the game + callbacks: [], // List of the functions called at each refresh + loadedAnimationsPointer: 0, // Keep track of the last loaded animation + loadedSoundsPointer: 0, // Keep track of the last loaded sound + + /** + * Load resources before starting the game. + */ + preload: function() { + // Start loading the images + for (var i = this.animations.length-1 ; i >= this.loadedAnimationsPointer; i --){ + this.animations[i].domO = new Image(); + this.animations[i].domO.src = this.animations[i].imageURL; + } + + // Start loading the sounds + for (var i = this.sounds.length-1 ; i >= this.loadedSoundsPointer; i --){ + this.sounds[i].load(); + } + + $.gameQuery.resourceManager.waitForResources(); + }, + + /** + * Wait for all the resources called for in preload() to finish loading. + */ + waitForResources: function() { + // Check the images + var imageCount = 0; + for(var i=this.loadedAnimationsPointer; i < this.animations.length; i++){ + if(this.animations[i].domO.complete){ + imageCount++; + } + } + // Check the sounds + var soundCount = 0; + for(var i=this.loadedSoundsPointer; i < this.sounds.length; i++){ + var temp = this.sounds[i].ready(); + if(temp){ + soundCount++; + } + } + // Call the load callback with the current progress + if($.gameQuery.resourceManager.loadCallback){ + var percent = (imageCount + soundCount)/(this.animations.length + this.sounds.length - this.loadedAnimationsPointer - this.loadedSoundsPointer)*100; + $.gameQuery.resourceManager.loadCallback(percent); + } + if(imageCount + soundCount < (this.animations.length + this.sounds.length - this.loadedAnimationsPointer - this.loadedSoundsPointer)){ + imgWait=setTimeout(function () { + $.gameQuery.resourceManager.waitForResources(); + }, 100); + } else { + this.loadedAnimationsPointer = this.animations.length; + this.loadedSoundsPointer = this.sounds.length; + + // All the resources are loaded! We can now associate the animation's images to their corresponding sprites + $.gameQuery.scenegraph.children().each(function(){ + // recursive call on the children: + $(this).children().each(arguments.callee); + // add the image as a background + if(this.gameQuery && this.gameQuery.animation){ + $(this).css("background-image", "url("+this.gameQuery.animation.imageURL+")"); + // we set the correct kind of repeat + if(this.gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL) { + $(this).css("background-repeat", "repeat-x"); + } else if(this.gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) { + $(this).css("background-repeat", "repeat-y"); + } else { + $(this).css("background-repeat", "no-repeat"); + } + } + }); + + // Launch the refresh loop + if($.gameQuery.state === STATE_NEW){ + setInterval(function () { + $.gameQuery.resourceManager.refresh(); + },($.gameQuery.refreshRate)); + } + $.gameQuery.state = STATE_RUNNING; + if($.gameQuery.startCallback){ + $.gameQuery.startCallback(); + } + // Make the scenegraph visible + $.gameQuery.scenegraph.css("visibility","visible"); + } + }, + + /** + * This function refresh a unique sprite here 'this' represent a dom object + */ + refreshSprite: function() { + // Check if 'this' is a gameQuery element + if(this.gameQuery != undefined){ + var gameQuery = this.gameQuery; + // Does 'this' has an animation ? + if(gameQuery.animation){ + // Do we have anything to do? + if ( (gameQuery.idleCounter == gameQuery.animation.rate-1) && gameQuery.playing){ + + // Does 'this' loops? + if(gameQuery.animation.type & $.gameQuery.ANIMATION_ONCE){ + if(gameQuery.currentFrame < gameQuery.animation.numberOfFrame-1){ + gameQuery.currentFrame += gameQuery.frameIncrement; + } else if(gameQuery.currentFrame == gameQuery.animation.numberOfFrame-1) { + // Does 'this' has a callback ? + if(gameQuery.animation.type & $.gameQuery.ANIMATION_CALLBACK){ + if($.isFunction(gameQuery.callback)){ + gameQuery.callback(this); + gameQuery.callback = false; + } + } + } + } else { + if(gameQuery.animation.type & $.gameQuery.ANIMATION_PINGPONG){ + if(gameQuery.currentFrame == gameQuery.animation.numberOfFrame-1 && gameQuery.frameIncrement == 1) { + gameQuery.frameIncrement = -1; + } else if (gameQuery.currentFrame == 0 && gameQuery.frameIncrement == -1) { + gameQuery.frameIncrement = 1; + } + } + + gameQuery.currentFrame = (gameQuery.currentFrame+gameQuery.frameIncrement)%gameQuery.animation.numberOfFrame; + if(gameQuery.currentFrame == 0){ + // Does 'this' has a callback ? + if(gameQuery.animation.type & $.gameQuery.ANIMATION_CALLBACK){ + if($.isFunction(gameQuery.callback)){ + gameQuery.callback(this); + } + } + } + } + // Update the background + if((gameQuery.animation.type & $.gameQuery.ANIMATION_VERTICAL) && (gameQuery.animation.numberOfFrame > 1)){ + if(gameQuery.multi){ + $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.multi)+"px "+(-gameQuery.animation.offsety-gameQuery.animation.delta*gameQuery.currentFrame)+"px"); + } else { + $(this).css("background-position",""+(-gameQuery.animation.offsetx)+"px "+(-gameQuery.animation.offsety-gameQuery.animation.delta*gameQuery.currentFrame)+"px"); + } + } else if((gameQuery.animation.type & $.gameQuery.ANIMATION_HORIZONTAL) && (gameQuery.animation.numberOfFrame > 1)) { + if(gameQuery.multi){ + $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.animation.delta*gameQuery.currentFrame)+"px "+(-gameQuery.animation.offsety-gameQuery.multi)+"px"); + } else { + $(this).css("background-position",""+(-gameQuery.animation.offsetx-gameQuery.animation.delta*gameQuery.currentFrame)+"px "+(-gameQuery.animation.offsety)+"px"); + } + } + } + gameQuery.idleCounter = (gameQuery.idleCounter+1)%gameQuery.animation.rate; + } + } + return true; + }, + + /** + * This function refresh a unique tile-map, here 'this' represent a dom object + */ + refreshTilemap: function() { + // Check if 'this' is a gameQuery element + if(this.gameQuery != undefined){ + var gameQuery = this.gameQuery; + if($.isArray(gameQuery.frameTracker)){ + for(var i=0; i 1)){ + $(this).css("background-position",""+(-gameQuery.animations[animationNumber].offsetx)+"px "+(-gameQuery.animations[animationNumber].offsety-gameQuery.animations[animationNumber].delta*gameQuery.frameTracker[animationNumber])+"px"); + } else if((gameQuery.animations[animationNumber].type & $.gameQuery.ANIMATION_HORIZONTAL) && (gameQuery.animations[animationNumber].numberOfFrame > 1)) { + $(this).css("background-position",""+(-gameQuery.animations[animationNumber].offsetx-gameQuery.animations[animationNumber].delta*gameQuery.frameTracker[animationNumber])+"px "+(-gameQuery.animations[animationNumber].offsety)+"px"); + } + } else { + if((gameQuery.animations.type & $.gameQuery.ANIMATION_VERTICAL) && (gameQuery.animations.numberOfFrame > 1)){ + $(this).css("background-position",""+(-gameQuery.animations.offsetx-this.gameQuery.multi)+"px "+(-gameQuery.animations.offsety-gameQuery.animations.delta*gameQuery.frameTracker)+"px"); + } else if((gameQuery.animations.type & $.gameQuery.ANIMATION_HORIZONTAL) && (gameQuery.animations.numberOfFrame > 1)) { + $(this).css("background-position",""+(-gameQuery.animations.offsetx-gameQuery.animations.delta*gameQuery.frameTracker)+"px "+(-gameQuery.animations.offsety-this.gameQuery.multi)+"px"); + } + } + }); + } + return true; + }, + + /** + * Called periodically to refresh the state of the game. + */ + refresh: function() { + if($.gameQuery.state === STATE_RUNNING) { + $.gameQuery.playground.find("."+$.gameQuery.spriteCssClass).each(this.refreshSprite); + $.gameQuery.playground.find("."+$.gameQuery.tilemapCssClass).each(this.refreshTilemap); + var deadCallback= new Array(); + for (var i = this.callbacks.length-1; i >= 0; i--){ + if(this.callbacks[i].idleCounter == this.callbacks[i].rate-1){ + var returnedValue = this.callbacks[i].fn(); + if(typeof returnedValue == 'boolean'){ + // If we have a boolean: 'true' means 'no more execution', 'false' means 'keep on executing' + if(returnedValue){ + deadCallback.push(i); + } + } else if(typeof returnedValue == 'number') { + // If we have a number it re-defines the time to the next call + this.callbacks[i].rate = Math.round(returnedValue/$.gameQuery.refreshRate); + this.callbacks[i].idleCounter = 0; + } + } + this.callbacks[i].idleCounter = (this.callbacks[i].idleCounter+1)%this.callbacks[i].rate; + } + for(var i = deadCallback.length-1; i >= 0; i--){ + this.callbacks.splice(deadCallback[i],1); + } + } + }, + + /** + * Add an animation to the resource Manager + */ + addAnimation: function(animation, callback) { + if($.inArray(animation,this.animations)<0){ + //normalize the animation rate: + animation.rate = Math.round(animation.rate/$.gameQuery.refreshRate); + if(animation.rate==0){ + animation.rate = 1; + } + this.animations.push(animation); + switch ($.gameQuery.state){ + case STATE_NEW: + case STATE_PAUSED: + // Nothing to do for now + break; + case STATE_RUNNING: + // immediatly load the animation and call the callback if any + this.animations[this.loadedAnimationsPointer].domO = new Image(); + this.animations[this.loadedAnimationsPointer].domO.src = animation.imageURL; + if (callback !== undefined){ + this.animations[this.loadedAnimationsPointer].domO.onload = callback; + } + this.loadedAnimationsPointer++; + break; + } + } + }, + + /** + * Add a sound to the resource Manager + */ + addSound: function(sound, callback){ + if($.inArray(sound,this.sounds)<0){ + this.sounds.push(sound); + switch ($.gameQuery.state){ + case STATE_NEW: + case STATE_PAUSED: + // Nothing to do for now + break; + case STATE_RUNNING: + // immediatly load the sound and call the callback if any + sound.load(); + // TODO callback.... + this.loadedSoundsPointer++; + break; + } + } + }, + + /** + * Register a callback + * + * @param {function} fn the callback + * @param {integer} rate the rate in ms at which the callback should be called (should be a multiple of the playground rate or will be rounded) + */ + registerCallback: function(fn, rate){ + rate = Math.round(rate/$.gameQuery.refreshRate); + if(rate==0){ + rate = 1; + } + this.callbacks.push({fn: fn, rate: rate, idleCounter: 0}); + }, + + /** + * Clear the animations and sounds + */ + clear: function(callbacksToo){ + this.animations = []; + this.loadedAnimationsPointer = 0; + this.sounds = []; + this.loadedSoundsPointer = 0; + if(callbacksToo) { + this.callbacks = []; + } + } + }, + + /** + * This is a single place to update the underlying data of sprites/groups/tiles after a position or dimesion modification. + */ + update: function(descriptor, transformation) { + // Did we really receive a descriptor or a jQuery object instead? + if(!$.isPlainObject(descriptor)){ + // Then we must get real descriptor + if(descriptor.length > 0){ + var gameQuery = descriptor[0].gameQuery; + } else { + var gameQuery = descriptor.gameQuery; + } + } else { + var gameQuery = descriptor; + } + // If we couldn't find one we return + if(!gameQuery) return; + if(gameQuery.tileSet === true){ + // We have a tilemap + + var visible = visibleTilemapIndexes(descriptor); + var buffered = gameQuery.buffered; + + // Test what kind of transformation we have and react accordingly + for(property in transformation){ + switch(property){ + case "x": + + if(visible.lastColumn > buffered.lastColumn) { + + // Detach the tilemap + var parent = descriptor[0].parentNode; + var tilemap = descriptor.detach(); + + var newBuffered = bufferedTilemapIndexes(descriptor, visible); + for(var i = gameQuery.buffered.firstRow; i < gameQuery.buffered.lastRow; i++){ + // Remove the newly invisible tiles + for(var j = gameQuery.buffered.firstColumn; j < Math.min(newBuffered.firstColumn, gameQuery.buffered.lastColumn); j++) { + tilemap.find("#"+$.gameQuery.tileIdPrefix+descriptor.attr("id")+"_"+i+"_"+j).remove(); + } + // And add the newly visible tiles + for(var j = Math.max(gameQuery.buffered.lastColumn,newBuffered.firstColumn); j < newBuffered.lastColumn ; j++) { + addTile(tilemap,i,j); + } + } + + gameQuery.buffered.firstColumn = newBuffered.firstColumn; + gameQuery.buffered.lastColumn = newBuffered.lastColumn; + + // Attach the tilemap back + tilemap.appendTo(parent); + + } + + if(visible.firstColumn < buffered.firstColumn) { + + // Detach the tilemap + var parent = descriptor[0].parentNode; + var tilemap = descriptor.detach(); + + var newBuffered = bufferedTilemapIndexes(descriptor, visible); + for(var i = gameQuery.buffered.firstRow; i < gameQuery.buffered.lastRow; i++){ + // Remove the newly invisible tiles + for(var j = Math.max(newBuffered.lastColumn,gameQuery.buffered.firstColumn); j < gameQuery.buffered.lastColumn ; j++) { + tilemap.find("#"+$.gameQuery.tileIdPrefix+descriptor.attr("id")+"_"+i+"_"+j).remove(); + } + // And add the newly visible tiles + for(var j = newBuffered.firstColumn; j < Math.min(gameQuery.buffered.firstColumn,newBuffered.lastColumn); j++) { + addTile(tilemap,i,j); + } + } + + gameQuery.buffered.firstColumn = newBuffered.firstColumn; + gameQuery.buffered.lastColumn = newBuffered.lastColumn; + + // Attach the tilemap back + tilemap.appendTo(parent); + } + break; + + case "y": + + if(visible.lastRow > buffered.lastRow) { + + // Detach the tilemap + var parent = descriptor[0].parentNode; + var tilemap = descriptor.detach(); + + var newBuffered = bufferedTilemapIndexes(descriptor, visible); + for(var j = gameQuery.buffered.firstColumn; j < gameQuery.buffered.lastColumn ; j++) { + // Remove the newly invisible tiles + for(var i = gameQuery.buffered.firstRow; i < Math.min(newBuffered.firstRow, gameQuery.buffered.lastRow); i++){ + tilemap.find("#"+$.gameQuery.tileIdPrefix+descriptor.attr("id")+"_"+i+"_"+j).remove(); + } + // And add the newly visible tiles + for(var i = Math.max(gameQuery.buffered.lastRow, newBuffered.firstRow); i < newBuffered.lastRow; i++){ + addTile(tilemap,i,j); + } + } + + gameQuery.buffered.firstRow = newBuffered.firstRow; + gameQuery.buffered.lastRow = newBuffered.lastRow; + + // Attach the tilemap back + tilemap.appendTo(parent); + + } + + if(visible.firstRow < buffered.firstRow) { + + // Detach the tilemap + var parent = descriptor[0].parentNode; + var tilemap = descriptor.detach(); + + var newBuffered = bufferedTilemapIndexes(descriptor, visible); + for(var j = gameQuery.buffered.firstColumn; j < gameQuery.buffered.lastColumn ; j++) { + // Remove the newly invisible tiles + for(var i = Math.max(newBuffered.lastRow, gameQuery.buffered.firstRow); i < gameQuery.buffered.lastRow; i++){ + tilemap.find("#"+$.gameQuery.tileIdPrefix+descriptor.attr("id")+"_"+i+"_"+j).remove(); + } + // And add the newly visible tiles + for(var i = newBuffered.firstRow; i < Math.min(gameQuery.buffered.firstRow, newBuffered.lastRow); i++){ + addTile(tilemap,i,j); + } + } + + gameQuery.buffered.firstRow = newBuffered.firstRow; + gameQuery.buffered.lastRow = newBuffered.lastRow; + + // Attach the tilemap back + tilemap.appendTo(parent); + } + break; + + case "angle": + //TODO + break; + + case "factor": + //TODO + break; + } + } + + } else { + var refreshBoundingCircle = $.gameQuery.playground && !$.gameQuery.playground.disableCollision; + + // Update the descriptor + for(property in transformation){ + switch(property){ + case "x": + if(refreshBoundingCircle){ + gameQuery.boundingCircle.x = gameQuery.posx+gameQuery.width/2; + } + break; + case "y": + if(refreshBoundingCircle){ + gameQuery.boundingCircle.y = gameQuery.posy+gameQuery.height/2; + } + break; + case "w": + case "h": + gameQuery.boundingCircle.originalRadius = Math.sqrt(Math.pow(gameQuery.width,2) + Math.pow(gameQuery.height,2))/2 + gameQuery.boundingCircle.radius = gameQuery.factor*gameQuery.boundingCircle.originalRadius; + break; + case "angle": //(in degrees) + gameQuery.angle = parseFloat(transformation.angle); + break; + case "factor": + gameQuery.factor = parseFloat(transformation.factor); + if(refreshBoundingCircle){ + gameQuery.boundingCircle.radius = gameQuery.factor*gameQuery.boundingCircle.originalRadius; + } + break; + } + } + } + }, + // State of the engine + state: STATE_NEW, + + // CSS classes used to mark game element + spriteCssClass: gQprefix + "sprite", + groupCssClass: gQprefix + "group", + tilemapCssClass: gQprefix + "tilemap", + tileCssClass: gQprefix + "tile", + // Prefix for CSS Ids or Classes + tileTypePrefix: gQprefix + "tileType_", + tileIdPrefix: gQprefix + "tile_" + }, + + /** + * Mute (or unmute) all the sounds. + */ + muteSound: function(muted){ + for (var i = $.gameQuery.resourceManager.sounds.length-1 ; i >= 0; i --) { + $.gameQuery.resourceManager.sounds[i].muted(muted); + } + }, + + /** + * Accessor for the currently defined playground as a jQuery object + */ + playground: function() { + return $.gameQuery.playground + }, + + /** + * Define a callback called during the loading of the game's resources. + * + * The function will recieve as unique parameter + * a number representing the progess percentage. + */ + loadCallback: function(callback){ + $.gameQuery.resourceManager.loadCallback = callback; + } + }); // end of the extensio of $ + + + // fragments used to create DOM element + var spriteFragment = $("
    "); + var groupFragment = $("
    "); + var tilemapFragment = $("
    "); + + + // Define the list of object/function accessible through $("selector"). + $.fn.extend({ + /** + * Defines the currently selected div to which contains the game and initialize it. + * + * This is a non-destructive call + */ + playground: function(options) { + if(this.length == 1){ + if(this[0] == document){ + // Old usage detected, this is not supported anymore + throw "Old playground usage, use $.playground() to retreive the playground and $('mydiv').playground(options) to set the div!"; + } + options = $.extend({ + height: 320, + width: 480, + refreshRate: 30, + position: "absolute", + keyTracker: false, + mouseTracker: false, + disableCollision: false + }, options); + // We save the playground node and set some variable for this node: + $.gameQuery.playground = this; + $.gameQuery.refreshRate = options.refreshRate; + $.gameQuery.playground[0].height = options.height; + $.gameQuery.playground[0].width = options.width; + + // We initialize the display of the div + $.gameQuery.playground.css({ + position: options.position, + display: "block", + overflow: "hidden", + height: options.height+"px", + width: options.width+"px" + }) + .append("