Avancement partiel.

This commit is contained in:
Georges Dupéron 2011-05-17 20:44:56 +02:00
parent 70eec38a55
commit 5842d02c61
6 changed files with 396 additions and 241 deletions

View File

@ -29,7 +29,7 @@ create table type_relation(name, num, extended_name, info);
create table user(login primary key, mail, hash_passwd, score, ugroup);
create table game(gid integer primary key autoincrement, eid_central_word, relation_1, relation_2, difficulty, author);
create table game_cloud(gid, num, difficulty, eid_word, totalWeight, probaR1, probaR2, probaR0, probaTrash);
create table played_game(pgid integer primary key autoincrement, gid, login, timestamp);
create table played_game(pgid integer primary key autoincrement, gid, nonce, login, timestamp);
create table played_game_cloud(pgid, gid, type, num, relation, weight, score);
create table colon_nodes(eid);
create table random_cloud_node(eid,nbneighbors);

View File

@ -27,18 +27,15 @@
border: medium solid #4a4; background-color:#f0f8d0; border-radius:0.4em;
}
.relationBox { border-width: 3px; border-style: solid; border-radius:1em; padding: 0.5em; width: 95%; margin: 0 auto; }
.relationBox table { border-collapse: collapse; }
.relationBox img { display:block; }
.relationBox td { padding:0; }
.formElement { width:30%; height: 10%; position:absolute; }
.fitFont, .subFitFont { overflow:auto; }
#score { text-align:center; }
.marginBox { width: 90%; height: 90%; top: 5%; left:5%; position:absolute; }
#message { left:5%; top:5%; width:90%; height:10%; position:absolute; border-radius:1em; text-align:center; opacity:0.9; }
#message { left:25%; top:5%; width:50%; height:15%; position:absolute; border-radius:0.5em; text-align:center; opacity:0.9; }
html, body, #splash, #nojs { background-color:black; color: white; }
#splash, #nojs { background-color:black; color: white; }
/* couleurs green */
.screen { background-color:#ffffe0; color: black; }
body, .screen { background-color:#ffffe0; color: black; }
#message { background-color:#f0f8d0; color:black; border:medium solid #4a4; }
#mc-caption { color:#8b4; }
#mn-caption-box { background-color:#f0f8d0; }
@ -49,7 +46,7 @@
.hot { background-color:yellow; }
/* couleurs black */
.black .screen { background-color:black; color: white; }
body.black, .black .screen { background-color:black; color: white; }
.black #message { background-color:#222; color:white; border:medium solid #ccc; }
.black #mc-caption { color:white; }
.black #mn-caption-box { background-color:#222; }
@ -61,7 +58,7 @@
</style>
</head>
<body>
<div id="splash" class="screen" style="display:block">
<div id="splash" class="screen">
<img src="ressources/img/splash.png" class="center" style="width:320px; height: 480px;"/>
</div>
<div id="game" class="screen">
@ -93,12 +90,12 @@
<div class="icon-container"><img class="iconFitParent" alt="" src="ressources/img/72/default.png" /></div>
<div class="icon-label subFitFont"><span class="text center">Configuration</span></div>
</a>
<a href="#connect" style="right:55%; top:66%;">
<a href="#connection" style="right:55%; top:66%;">
<div class="highlight"></div>
<div class="icon-container"><img class="iconFitParent" alt="" src="ressources/img/72/default.png" /></div>
<div class="icon-label subFitFont"><span class="text center">Connexion</span></div>
</a>
<a hred="#info" style="left:55%; top:66%;">
<a href="#info" style="left:55%; top:66%;">
<div class="highlight"></div>
<div class="icon-container"><img class="iconFitParent" alt="" src="ressources/img/72/default.png" /></div>
<div class="icon-label subFitFont"><span class="text center">À propos</span></div>
@ -117,14 +114,14 @@
<div class="marginBox fitFont">
<p>
PtiClic a été conçu et développé par Mathieu Lafourcade
(LIRMM - Université Montpellier 2) et Virginie Zampa
(LIDILEM - Université Stendhal Grenoble 3)
(LIRMM - Université Montpellier 2) et Virginie Zampa
(LIDILEM - Université Stendhal Grenoble 3)
</p>
<p>
La présente version pour SmartPhone sous Android, en cours
de développement a été conçue et réalisée par des
étudiants en Master 1 à l'Université Montpellier II :
Yoann BONAVERO, Bertrand BRUN, John CHARRON et
étudiants en Master 1 à l'Université Montpellier 2 :
Yoann BONAVERO, Bertrand BRUN, John CHARRON et
Georges DUPÉRON.
</p>
<p>
@ -170,17 +167,9 @@
</form>
</div>
<div id="templates" style="display: none;">
<div class="relationBox">
<table style="width:100%; position:relative;">
<tr>
<td>
<img class="icon" alt="" src="ressources/img/72/default.png" style="width:72px; height:72px;" />
</td>
<td>
<div class="text subFitFont"></div>
</td>
</tr>
</table>
<div class="relationBox subFitFont">
<img class="icon" alt="" src="ressources/img/72/default.png" style="width:72px; height:72px; display:inline-block; vertical-align:middle;" />
<span class="text" style="vertical-align:middle;"></span>
</div>
<div class="scoreLine">
<span class="word"></span> (<span class="score"></span>)
@ -188,4 +177,4 @@
</div>
<div id="message" class="fitFont"><span class="text center">PtiClic…</span></div>
</body>
</html>
</html>

View File

@ -15,8 +15,8 @@ require_once("ressources/db.inc");
* randomGameCore();
* randomGame();
* formatWord($word);
* game2json($user, $gameId);
* game2array($user, $gameId);
* game2json($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true);
* game2array($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true);
* createGame($nbParties, $mode);
* createGameCore($cloudSize);
* getGame($user, $nbGames, $mode);
@ -267,17 +267,17 @@ function cgInsert($centerEid, $cloud, $r1, $r2, $totalDifficulty)
$gid = $db->lastInsertRowID();
$t = time();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid1 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid2 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid0 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgidT = $db->lastInsertRowID();
// TODO : R0 et Trash + corrections
@ -347,17 +347,17 @@ function insertCreatedGame($centerEid, $cloud, $r1, $r2, $totalDifficulty,$userN
$gid = $db->lastInsertRowID();
$t = time();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid1 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid2 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgid0 = $db->lastInsertRowID();
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp)
VALUES (null, $gid, null, $t);");
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp)
VALUES (null, $gid, -1, null, $t);");
$pgidT = $db->lastInsertRowID();
// TODO : R0 et Trash + corrections
@ -441,27 +441,31 @@ function formatWord($word) {
/** Formate une partie en JSON en l'imprimant.
* @param user : l'utilisateur.
* @param gameId : L'identifiant d'une partie.
* @param pgidNonce : pgid ou nonce de la partie. Peut être -1 uniquement si $doPlayedGame = true
* @param doPlayedGame : enregistrer un nouveau pgid ?
*/
function game2json($user, $gameId)
function game2json($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true)
{
global $stringRelations;
$db = getDB();
// TODO : factoriser avec game2array() .
// TODO : factoriser avec game2array().
// TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp) VALUES (null, ".$gameId.", '$user', -1);");
$pgid = $db->lastInsertRowID();
if ($doPlayedGame) {
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp) VALUES (null, ".intval($gameId).", ".$pgidNonce.", '".SQLite3::escapeString($user)."', -1);");
$pgidNonce = $db->lastInsertRowID();
}
// TODO Yoann : faire des tests d'erreur pour ces select ?
$game = $db->query("select gid, (select name from node where eid = eid_central_word) as name_central_word, eid_central_word, relation_1, relation_2 from game where gid = ".$gameId.";");
$game = $game->fetchArray();
$retstr = "";
$retstr .= '{"gid":'.$gameId.',"pgid":'.$pgid.',"relations":[';
$retstr .= '{"gid":'.$gameId.',"pgid":'.$pgidNonce.',"relations":[';
$retstr .= '{"id":'.$game['relation_1'].', "name":'.json_encode(''.formatWord($stringRelations[$game['relation_1']])).'}';
$retstr .= ', {"id":'.$game['relation_2'].', "name":'.json_encode(''.formatWord($stringRelations[$game['relation_2']])).'}';
$retstr .= ', {"id":0, "name":'.json_encode(''.formatWord($stringRelations[0])).'}';
$retstr .= ', {"id":-1, "name":'.json_encode(''.formatWord($stringRelations[-1])).'}],';
// $retstr .= '{"gid":'.$gameId.',"pgid":'.$pgid.',"cat1":'.$game['relation_1'].',"cat2":'.$game['relation_2'].',"cat3":0,"cat4":-1,';
// $retstr .= '{"gid":'.$gameId.',"pgid":'.$pgidNonce.',"cat1":'.$game['relation_1'].',"cat2":'.$game['relation_2'].',"cat3":0,"cat4":-1,';
$retstr .= '"center":{"id":'.$game['eid_central_word'].',"name":'.json_encode(''.formatWord($game['name_central_word'])).'},';
$cloudsize = 0;
@ -486,16 +490,19 @@ function game2json($user, $gameId)
}
/** Récupère une partie sous forme de tableau.
* @param db : descripteur de la bdd (obtenu avec getDB()).
* @param user : Login de l'utilisateur demandant la partie.
* @param gameId : L'identifiant d'une partie.
* @param pgidNonce : pgid ou nonce de la partie. Peut être -1 uniquement si $doPlayedGame = true
* @param doPlayedGame : enregistrer un nouveau pgid ?
*/
function game2array($user, $gameId)
function game2array($user, $gameId, $pgidNonce = "-1", $doPlayedGame = true)
{
$db = getDB();
// TODO : planter si la requête suivante échoue pour quelque raison que ce soit.
$db->exec("INSERT INTO played_game(pgid, gid, login, timestamp) VALUES (null, ".$gameId.", '$user', -1);");
$pgid = $db->lastInsertRowID();
if ($doPlayedGame) {
$db->exec("INSERT INTO played_game(pgid, gid, nonce, login, timestamp) VALUES (null, ".intval($gameId).", ".$pgidNonce.", '".SQLite3::escapeString($user)."', -1);");
$pgidNonce = $db->lastInsertRowID();
}
// TODO Yoann : faire des tests d'erreur pour ces select ?
$game = $db->query("select gid, (select name from node where eid = eid_central_word) as name_central_word, eid_central_word, relation_1, relation_2 from game where gid = ".$gameId.";");
@ -503,7 +510,7 @@ function game2array($user, $gameId)
$ret = array();
$ret['gid'] = $gameId;
$ret['pgid'] = $pgid;
$ret['pgid'] = $pgidNonce;
$ret['cat1'] = $game['relation_1'];
$ret['cat2'] = $game['relation_2'];
$ret['cat3'] = 0;
@ -564,9 +571,22 @@ function createGameCore($cloudSize)
* @param nbGames : Le nombre de parties à récupérer.
* @param mode : Le mode de jeu des parties à récupérer.
*/
function getGame($user)
function getGame($user, $pgidNonce = null)
{
echo game2json($user, randomGame());
$nonce = "-1";
if ($pgidNonce !== null) {
if (substr($pgidNonce, 0, 1) == '-') {
$temp = getDB()->querySingle("SELECT gid,pgid FROM played_game WHERE nonce = ".preg_replace('/[^0-9]/', '', $pgidNonce)." and login = '".SQLite3::escapeString($user)."';", true);
$gid = $temp['gid'];
$nonce = $temp['pgid'];
if ($gid == null) { $nonce = preg_replace('/[^0-9]/', '', $pgidNonce); $pgidNonce = null; }
} else {
$nonce = intval($pgidNonce);
$gid = getDB()->querySingle("SELECT gid FROM played_game WHERE pgid = ".$pgidNonce." and login = '".SQLite3::escapeString($user)."';");
if ($gid == null) throw new Exception("Cette partie n'est associée à votre nom d'utilisateur.", 4);
}
}
echo game2json($user, $pgidNonce == null ? randomGame() : $gid, $nonce, $pgidNonce == null);
}
@ -618,11 +638,11 @@ function normalizeProbas($row) {
function setGame($user, $pgid, $gid, $answers)
{
$db = getDB();
if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = $pgid and $gid = $gid and login = '$user' and timestamp = -1;")) {
if ('ok' !== $db->querySingle("SELECT 'ok' FROM played_game WHERE pgid = $pgid and gid = $gid and login = '".SQLite3::escapeString($user)."' and timestamp = -1;")) {
return getGameScores($user, $pgid, $gid);
}
$userReputation = computeUserReputation($db->querySingle("SELECT score FROM user WHERE login='".SQLite3::escapeString($user)."';"));
$userReputation = computeUserReputation($db->querySingle("SELECT score FROM user WHERE login = '".SQLite3::escapeString($user)."';"));
$db->exec("begin transaction;");
$db->exec("update played_game set timestamp = ".time()." where pgid = $pgid;");

View File

@ -8,10 +8,10 @@ Number.prototype.mapInterval = function(a,b,x,y) {
return x + ((this-a) / (b-a) * (y-x));
}
function dichotomy(start, isBigger) {
dichotomyStop = false;
function dichotomy(start, isBigger, debug) {
try {
var i = 0, min = 0, max, half;
for (max = start || 1; ++i < 10 && !isBigger(max); max *= 2);
for (half = start; Math.abs(min-max) > 0.1; half = (min + max) / 2) {
if (!isBigger(half)) min = half;
@ -19,7 +19,7 @@ function dichotomy(start, isBigger) {
}
while (half > 1 && isBigger(half)) { --half; }
return half;
} catch(e) {alert("Error dichotomy");alert(e);}
} catch(e) {alert("Error dichotomy");alert(e);throw(e);}
}
$.fn.fold = function(acc, fn) {
@ -43,13 +43,14 @@ $.fn.fitFont = function() {
try {
var that = this;
var setFont = this.find('.setFont').andSelf();
this.find('.center').css({top:0, left:0}); // Petit hack pour que ça ne déborde pas à cause de l'offset mis par .center().
var size = dichotomy(parseInt(this.css("font-size"), 10), function(x) {
setFont.css("fontSize", x);
return that.$ormap(function(i,e) { return e.hasScroll(); });
});
}, this);
this.css("font-size", Math.max(0, size));
return this;
} catch(e) {alert("Error $.fn.fitFont");alert(e);}
} catch(e) {alert("Error $.fn.fitFont");alert(e);throw(e);}
};
$.fn.swapCSS = function(k,v) {
@ -86,6 +87,7 @@ $.fn.qRemoveClass = queueize("removeClass");
$.fn.qShow = queueize("show");
$.fn.qHide = queueize("hide");
$.fn.qCss = queueize("css");
$.fn.qText = queueize("text");
$.fn.wh = function(w, h) {
try {
@ -159,8 +161,59 @@ var PtiClic = $({});
PtiClic.queueJSON = function(url, data, ok, error) {
};
function decodeHash(hash) {
/* hash.match(/^#([a-z]+(\/[0-9]+(\/-?[0-9]+(,-?[0-9]+)*)?)?)?$/) */
hash = hash.substring(1).split('/');
return {
screen:hash[0] || 'splash',
pgid:hash[1] || -1,
answers:(hash[2] ? hash[2].split(',') : [])
};
}
function encodeHash(data) {
var hash = "#";
if (data.screen == '') return hash;
hash += data.screen
if (data.pgid == -1) return hash;
hash += '/'+data.pgid;
if (data.answers.length == 0) return hash;
hash += '/'+data.answers.join(',');
return hash;
}
function Cache(resolver) {
var cache = [];
var self = this;
this.get = function(k) {
return cache[k] = cache[k] || $.Deferred(function(dfd) { resolver(k, dfd, self); });
};
this.alias = function(alias, k) {
cache[alias] = cache[alias] || $.Deferred();
cache[k].done(function(data) { cache[alias].resolve(data); });
};
}
/* Enchaînement des écrans
Aller sur un écran donné.
*** Utiliser un objet Deferred pour les fonctions qu'on ne veut apeller qu'une fois.
***
- Cache des parties récupérées & scores (key = pgid pour les deux, mais params supplémentaires pour scores)
new Cache(queryFn(k, dfd, cache) { cache.set(k,v); dfd.resolve(data); });
Cache.get(k) returns Promise; // Peut déclencher $.extend(Cache, queryFn(k)).
- Récupérer une partie aléatoire, et la stocker dans le cache à son arrivée
- Afficher $(#game) (et $(#score)) une fois la partie (score) récupéré(e) et le(la) consommer
- Sauf si l'action a été annulée.
$.when(getGame, goGame)
if (runstate.nextScreen == 'game')
- Lorsqu'une requête échoue, on demande le login, on retente la requête avec ce login/mdp. Si ça marche avec ce login/mdp, on .resolve(), sinon on .fail().
***
Aller sur un écran donné (parfois sans changer l'URL, par ex. pour splash→frontpage, et lorsqu'on force le login).
Recevoir des données avant d'entrer dans un écran.
Envoyer des données avant de quiter un écran.
Vérouiller l'écran courant pendant qu'on attend un transfert ou bien des écrans d'«attente».

View File

@ -1,13 +1,269 @@
// ==== URL persistante
var nullFunction = function(){};
var futureHashChange = null;
var runstate = {
screen: 'none',
};
var state = decodeHash("");
var oldstate = decodeHash("");
function State(init) {
$.screen = function (name) {
return $(document.getElementById(name)).filter('.screen');
}
function hashchange() {
oldstate = state;
state = decodeHash(location.hash);
$.screen(state.screen).trigger(state.screen != runstate.screen ? "goto" : "update");
}
function init(fn) {
$(window).queue('init', function(next) {fn(); next();});
}
// ==== Code métier général
$(function() {
$(window).dequeue('init');
$(window).resize(jss);
$(window).hashchange(hashchange);
hashchange();
jss();
runstate.loaded = true;
});
// ==== Nouveau jss
function jss() {
try {
if ($("#splash img").is(':visible')) {
var ratio = Math.min($('#splash').width() / 320, $('#splash').height() / 480);
$('#splash.screen img')
.wh(320 * ratio, 480 * ratio);
}
if ($('#game.screen').is(':visible')) {
var iconSize = 72;
var rel = $('#game.screen .relations');
var rb = rel.find('.relationBox');
rb.css({
borderWidth: ({72:3,48:2,36:1})[iconSize],
padding: 10/72*iconSize,
borderRadius: 20/72*iconSize,
}).height(iconSize);
rb.css({ marginTop: (rel.height() - rb.sumOuterHeight()) / (rb.size() + 1) });
rb.find('.icon').css({paddingRight: 10/72*iconSize});
}
$('.iconFitParent').wh(0,0).each(function(i,e) {
e=$(e);
var p = e.parent();
var size = Math.min(p.width(), p.height());
if (size >= 72) { e.wh(72); }
else if (size >= 48) e.wh(48);
else if (size >= 36) e.wh(36);
else e.wh(0);
});
$('.fitFont:visible').$each(function(i,e) { e.fitFont(); });
$('.fitFontGroup:visible').each(function(i,e) { $(e).find('.subFitFont').fitFont(); });
$('.center:visible').$each(function(i,e) { e.center(e.parent().center()); });
} catch(e) {alert("Error jss");alert(e);}
}
// ==== Passage d'un écran à l'autre
init(function() {
$('.screen').live('goto', function() {
var screen = this.id;
if (screen == '') return;
// Afficher "Chargement…"
/* location.hash = "#" + screen; */
$.screen(runstate.screen).trigger('leave').hide();
runstate.screen = screen;
$(this).trigger('pre-enter');
});
$('.screen').live('pre-enter', function() {
$(this).trigger('enter');
});
$('.screen').live('enter', function() {
$(this).show();
jss();
});
$('.screen').live('leave', function() {
$(this).hide();
});
});
// ==== Bulle pour les messages
init(function() {
$('#message').hide();
});
function message(title, msg) {
try {
$('#message')
.qCss('opacity',0).qShow()
.queue(function(next){ $('#message .text').text(msg); jss(); next(); })
.fadeTo(700, 0.9).delay(5000).fadeOut(700);
} catch(e) {alert("Error UI().info");alert(e);}
}
// ==== Écran splash
init(function() {
$('#splash.screen').click(function(){ $('#frontpage').trigger('goto'); });
$('#splash.screen').bind('goto', function(e){
if (runstate.loaded) {
$('#frontpage').trigger('goto');
return false;
}
});
});
// ==== Écran game
runstate.gameCache = new Cache(function(k, dfd, cache) {
$.getJSON("getGame.php?callback=?", {pgid:k}, function(data) {
if (data.error == 10) {
$('#connection.screen').trigger('goto');
} else if (data.isError) {
location.hash = "#frontpage";
message("Erreur", "Une erreur est survenue, veuillez nous en excuser.");
} else {
cache.alias(data.pgid, k);
dfd.resolve(data);
}
});
});
init(function() {
var game = $('#game.screen');
$('a[href="#game"]').click(function() {
location.hash = '#game/-' + $.now();
return false;
});
game.bind('pre-enter', function() {
runstate.gameCache.get(state.pgid).done(function(data) {
runstate.game = data
if (runstate.screen == 'game') { game.trigger('enter'); }
});
return false;
});
game.bind('enter', function() {
$("#game .relations").empty();
var game = runstate.game;
$.each(game.relations, function(i, relation) {
$('#templates .relationBox')
.clone()
.find(".text").html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>')).end()
.find(".icon").data("image",relation.id).end()
.click(function(e) {
state.pgid = game.pgid;
state.answers.push(relation.id);
location.hash = encodeHash(state);
$(this).addClass("hot").removeClass("hot", 1000);
/* try {
game.nextWord({left:e.pageX, top:e.pageY}, this);
} catch(e) {alert("Error anonymous 2 click in game.buildUi");alert(e);}*/
})
.appendTo("#game .relations");
});
$("#game .mn").text(game.cloud[state.answers.length].name);
$("#game .mc").text(game.center.name);
});
game.bind('update', function(e) {
$("#game .mn").text(runstate.game.cloud[state.answers.length].name);
jss();
console.log('update');
});
});
game = {};
game.leave = function () {
try {
$("#game .relations").empty();
$('#game #mn-caption').stop().clearQueue();
if (runstate.gameFetched) runstate.gameFetched = nullFunction;
} catch(e) {alert("Error game.leave");alert(e);}
};
game.buildUi = function () {
try {
$("#game .relations").empty();
$.each(state.game.relations, function(i, relation) {
try {
} catch(e) {alert("Error anonymous 1 in game.buildUi");alert(e);}
});
game.updateText();
} catch(e) {alert("Error game.buildUi");alert(e);}
}
game.updateText = function() {
try {
$("#game .mn").text(state.game.cloud[state.currentWordNb].name);
$("#game .mc").text(state.game.center.name);
jss();
UI().dismiss();
} catch(e) {alert("Error game.updateText");alert(e);}
}
game.animateNext = function (click, button) {
try {
var duration = 700;
var mn = $("#game #mn-caption");
$(button).addClass("hot").removeClass("hot", duration);
(mn)
.stop() // Attention : stop() et clearQueue() ont aussi un effet
.clearQueue() // sur la 2e utilisation de mn (ci-dessous).
.clone()
.removeClass("mn") // Pour que le texte animé ne soit pas modifié.
.appendTo("body") // Append to body so we can animate the offset (instead of top/left).
.offset(mn.offset())
.animate({left:click.left, top:click.top, fontSize: 0}, duration)
.queue(function() {
try {
$(this).remove();
} catch(e) {alert("Error anonymous 1 in game.animateNext");alert(e);}
});
game.updateText();
var fs = mn.css("fontSize");
var mncbCenter = $("#game #mn-caption-block").center();
(mn)
.css("fontSize", 0)
.animate({fontSize: fs}, {duration:duration, step:function(){
try {
mn.center(mncbCenter);
} catch(e) {alert("Error anonymous 2 in game.animateNext");alert(e);}
}});
} catch(e) {alert("Error game.animateNext");alert(e);}
}
game.nextWord = function(click, button) {
try {
state.game.answers[state.currentWordNb++] = $(button).data("rid");
if (state.currentWordNb < state.game.cloud.length) {
game.animateNext(click, button);
state.commit();
} else {
state.set('screen','score').validate();
}
} catch(e) {alert("Error game.nextWord");alert(e);}
}
/*function State(init) {
try {
$.extend(this, init || {});
if (!this.screen) this.screen = 'splash';
} catch(e) {alert("Error State");alert(e);}
};
var futureHashChange = null;
State.prototype.commit = function() {
try {
futureHashChange = "#"+encodeURI('"'+$.JSON.encode(this));
@ -37,21 +293,13 @@ State.prototype.validate = function () {
if (window[this.screen] && window[this.screen].enter) window[this.screen].enter();
return this;
} catch(e) {alert("Error State.prototype.validate");alert(e);}
};
};*/
var runstate = {};
var state;
var oldScreen = '';
var ui = {};
function hashchange() {
function _hashchange() {
try {
if (futureHashChange === location.hash) {
futureHashChange = null;
} else {
var stateJSON = location.hash.substring(location.hash.indexOf("#") + 1);
if (stateJSON.charAt(0) != '"') { stateJSON = decodeURI(stateJSON); }
stateJSON = stateJSON.substring(1);
state = new State($.parseJSON(stateJSON || '{}')).validate();
if (futureHashChange !== location.hash) {
state = decodeHash(location.hash);
// Appliquer le changement de screen etc.
}
} catch(e) {alert("Error hashchange");alert(e);}
}
@ -85,70 +333,6 @@ function UI () {
} catch(e) {alert("Error UI");alert(e);}
}
function UIInfo(title, msg) {
try {
$('#message')
.qCss('opacity',0)
.qShow()
.queue(function(next){
try {
$('#message .text').text(msg);
jss();
next();
} catch(e) {alert("Error anonymous in UIInfo");alert(e);}
})
.animate({opacity:0.9}, 700)
.delay(5000)
.animate({opacity:0}, 700);
} catch(e) {alert("Error UI().info");alert(e);}
}
// ==== Nouveau jss
function jss() {
try {
if ($("#splash img").is(':visible')) {
var ratio = Math.min($('#splash').width() / 320, $('#splash').height() / 480);
$('#splash.screen img')
.wh(320 * ratio, 480 * ratio);
}
if ($('#game.screen').is(':visible')) {
var iconSize = 72;
var rel = $('#game.screen .relations');
var rb = rel.find('.relationBox');
$('.relationBox').css({
borderWidth: ({72:3,48:2,36:1})[iconSize],
padding: 10/72*iconSize,
borderRadius: 20/72*iconSize,
marginTop: (rel.height() - rb.sumOuterHeight()) / (rb.size() + 1)
});
$('.relationBox .icon').css({paddingRight: 10/72*iconSize});
}
$('.iconFitParent').wh(0,0).each(function(i,e) {
e=$(e);
var p = e.parent();
var size = Math.min(p.width(), p.height());
if (size >= 72) { e.wh(72); }
else if (size >= 48) e.wh(48);
else if (size >= 36) e.wh(36);
else e.wh(0);
});
$('.fitFont:visible').$each(function(i,e) { e.fitFont(); });
$('.fitFontGroup:visible').each(function(i,e) { $(e).find('.subFitFont').fitFont(); });
$('.center').$each(function(i,e) { e.center(e.parent().center()); });
} catch(e) {alert("Error jss");alert(e);}
}
// ==== Code métier général
$(function() {
try {
$(window).resize(jss);
$(window).hashchange(function(){alert("hashchange !");});
//hashchange();
jss();
runstate.loaded = true;
} catch(e) {alert("Error main function");alert(e);}
});
// ==== Asynchronous Javascript And Json.
ajaj = {};
ajaj.request = function(url, data, okFunction, smallErrorFunction, bigErrorFunction) {
@ -306,97 +490,6 @@ game.enter = function () {
} catch(e) {alert("Error game.enter");alert(e);}
};
game.leave = function () {
try {
$("#game .relations").empty();
$('#game #mn-caption').stop().clearQueue();
if (runstate.gameFetched) runstate.gameFetched = nullFunction;
} catch(e) {alert("Error game.leave");alert(e);}
};
game.buildUi = function () {
try {
$("#game .relations").empty();
$.each(state.game.relations, function(i, relation) {
try {
$('#templates .relationBox')
.clone()
.data("rid", relation.id)
.find(".text")
.html(relation.name.replace(/%(m[cn])/g, '<span class="$1"/>'))
.end()
.find(".icon")
.data("image",relation.id)
.end()
.click(function(e) {
try {
game.nextWord({left:e.pageX, top:e.pageY}, this);
} catch(e) {alert("Error anonymous 2 click in game.buildUi");alert(e);}
})
.appendTo("#game .relations");
} catch(e) {alert("Error anonymous 1 in game.buildUi");alert(e);}
});
game.updateText();
} catch(e) {alert("Error game.buildUi");alert(e);}
}
game.updateText = function() {
try {
$("#game .mn").text(state.game.cloud[state.currentWordNb].name);
$("#game .mc").text(state.game.center.name);
jss();
UI().dismiss();
} catch(e) {alert("Error game.updateText");alert(e);}
}
game.animateNext = function (click, button) {
try {
var duration = 700;
var mn = $("#game #mn-caption");
$(button).addClass("hot").removeClass("hot", duration);
(mn)
.stop() // Attention : stop() et clearQueue() ont aussi un effet
.clearQueue() // sur la 2e utilisation de mn (ci-dessous).
.clone()
.removeClass("mn") // Pour que le texte animé ne soit pas modifié.
.appendTo("body") // Append to body so we can animate the offset (instead of top/left).
.offset(mn.offset())
.animate({left:click.left, top:click.top, fontSize: 0}, duration)
.queue(function() {
try {
$(this).remove();
} catch(e) {alert("Error anonymous 1 in game.animateNext");alert(e);}
});
game.updateText();
var fs = mn.css("fontSize");
var mncbCenter = $("#game #mn-caption-block").center();
(mn)
.css("fontSize", 0)
.animate({fontSize: fs}, {duration:duration, step:function(){
try {
mn.center(mncbCenter);
} catch(e) {alert("Error anonymous 2 in game.animateNext");alert(e);}
}});
} catch(e) {alert("Error game.animateNext");alert(e);}
}
game.nextWord = function(click, button) {
try {
state.game.answers[state.currentWordNb++] = $(button).data("rid");
if (state.currentWordNb < state.game.cloud.length) {
game.animateNext(click, button);
state.commit();
} else {
state.set('screen','score').validate();
}
} catch(e) {alert("Error game.nextWord");alert(e);}
}
// ==== Code métier pour les scores
score = {};
@ -526,10 +619,10 @@ connection.connectFetched = function(data) {
try {
if (data && data.theme) {
prefs.loadPrefs();
UIInfo("Connexion", "Vous êtes connecté !");
message("Connexion", "Vous êtes connecté !");
} else if (data && data.isError && data.error == 3) {
prefs.loadPrefs();
UIInfo("Connexion", data.msg);
message("Connexion", data.msg);
} else {
prefs.loadPrefs();
ajaj.smallError(data);
@ -563,10 +656,10 @@ prefs.apply = function(){
}, function(data) {
try {
if (data.theme) {
UIInfo("Préférences", "Les préférences ont été enregistrées.");
message("Préférences", "Les préférences ont été enregistrées.");
prefs.loadPrefs(data);
} else {
UIInfo("Préférences", "Les préférences n'ont pas pu être enregistrées.");
message("Préférences", "Les préférences n'ont pas pu être enregistrées.");
}
} catch(e) {alert("Error anonymous in prefs.apply");alert(e);}
});

View File

@ -75,7 +75,7 @@ function main()
}
else if($action == 0) { // "Get partie"
// Requête POST : http://serveur/server.php?action=0&user=foo&passwd=bar
getGame($user);
getGame($user, isset($_GET['pgid']) ? $_GET['pgid'] : null);
}
else if($action == 1) { // "Set partie"
// Requête POST : http://serveur/server.php?action=1&mode=normal&user=foo&passwd=bar&gid=1234&pgid=12357&0=0&1=-1&2=22&3=13&9=-1