Création d'une carte, solution la plus efficace ?

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Création d'une carte, solution la plus efficace ?

par pascaltje » 07 mai 2009, 21:58

exact, soucis sur le début du while.

on corrige :
// on enregistre une ligne de référence bidon, via une valeur impossible
$y_ref = '*';
// affichage debut tableau : TABLE
// ouverture de la ligne TR
// ecriture de la premiere case
// TD ... /TD
while( $r = mysql_fetch_assoc($req) )
{
    if( $r['y'] == $y_ref )
    {  // on est sur la même ligne
        // afficher la case : TD ... /TD
    }else{
        // passer à la ligne suivante :
        // si $y_ref <> '*'
        // alors fermer la ligne /TR 
        // fin si
        // et en ouvrir une nouvelle  TR
        // afficher la case : TD ... / TD
        // enregistrer la nouvelle ligne en référence
        $y_ref = $r['y'];
    }
}
// on ferme la dernière ligne /TR
// on ferme le tableau /TABLE
Pour les perfs, à tester, ça dépend de la taille du tableau. Un benchmark te donnera la réponse :P

A+

Pascal

par Nours312 » 07 mai 2009, 21:15

voilà mon pseudo code :
$r = mysql_fetch_assoc($req);
// on enregistre la ligne en référence
$y_ref = $r['y'];
// affichage debut tableau : TABLE
// ouverture de la ligne TR
// ecriture de la premiere case
// TD ... /TD
while( $r = mysql_fetch_assoc($req) )
{
	if( $r['y'] == $y_ref )
	{  // on est sur la même ligne
		// afficher la case : TD ... /TD
	}else{
		// passer à la ligne suivante :
		// fermer la ligne et en ouvrir une nouvelle /TR  TR
		// afficher la case : TD ... / TD
		// enregistrer la nouvelle ligne en référence
		$y_ref = $r['y'];
	}
}
// on ferme la ligne /TR
// on ferme le tableau /TABLE
A+

Pascal
tu n'aurais pas un problème dans ton while ? mysql_fetch_assoc ayant été préalablement déclenché, il va te manquer une ligne ... ? à moins que tu doubles tes boucles ...

Toutes les clauses if(){}else{] pour les y et les x sont -elles plus rentables (en gamme de performance php) que .... de faire un premier tableau suivit des foreach() ... ?

je ne suis pas pas là pour te faire Ch***, c'est juste que je me pause la question :d ;)

BonCode ;)

par tweak » 07 mai 2009, 20:41

omg les mec merci beaucoup !

Pour le morceau de code que tu propose ici :

Code : Tout sélectionner

echo début du tableau boucle sur les y echo début de ligne <tr> boucle sur les x echo la case : echo <td> contenu </td> fin boucle x echo fin de ligne </tr> fin boucle y echo fin du tableau
Je n'avais pas compris que l'intérêt étais de construire directement le tableau dans la boucle !!

Moi j'avais prévu de le faire après que la boucle est définie toute les variable du genre $tableau="tout mon tableau avec les variable prédéfinie par la boucle !!" ...

Ahah c'est vraiment bon :)

Merci :o

par pascaltje » 07 mai 2009, 19:08

donc, si tu pouvais m'éclairer un peu :idea: au passage, j'ai hâte .. ;)
voilà mon pseudo code :
$r = mysql_fetch_assoc($req);
// on enregistre la ligne en référence
$y_ref = $r['y'];
// affichage debut tableau : TABLE
// ouverture de la ligne TR
// ecriture de la premiere case
// TD ... /TD
while( $r = mysql_fetch_assoc($req) )
{
	if( $r['y'] == $y_ref )
	{  // on est sur la même ligne
		// afficher la case : TD ... /TD
	}else{
		// passer à la ligne suivante :
		// fermer la ligne et en ouvrir une nouvelle /TR  TR
		// afficher la case : TD ... / TD
		// enregistrer la nouvelle ligne en référence
		$y_ref = $r['y'];
	}
}
// on ferme la ligne /TR
// on ferme le tableau /TABLE
A+

Pascal

par Nours312 » 07 mai 2009, 18:35

@pascaltje ...

ma question n'était pas une remarque, mais c'est du au fait que je ne vois pas comment tu montes tes boucles ... ?

j'ai pour habitude de sortir d'une requete avec mysql_fetch_row(), qui te sort les lignes les une aprés les autres ... ainsi, la seule solution que je vois est d'incrémenter des compteurs... ce que je suppose pas plus rapide que de parcourir deux fois un tableau ....

donc, si tu pouvais m'éclairer un peu :idea: au passage, j'ai hâte .. ;)

@+

par pascaltje » 07 mai 2009, 16:37

@Nours321:
Pourquoi parcourir une fois les résultats de la requête pour ensuite parcourir le tableau ?

On peut tout faire en un seul passage.

A+

Pascal

par Nours312 » 07 mai 2009, 15:19

et en sortie de requete tu ne construit pas ta table ... ?
$liste = array();
while($r = mysql_fetch_assoc($req)){
  $liste[$r['y']][$r['x']] = $r['img'];
}

// puis ensuite :

foreach($liste as $y => $t){
  // ligne
  foreach($t as $x =< $img){
    //cellule
  }
  //ligne fin
}

par pascaltje » 07 mai 2009, 11:37

re,

N'hésite pas à t'inscrire sur phpfrance et sur CreaJeu :)

Au niveau du script, pour être plus complet et plus précis :

J'ai changé la requête au niveau de l'ordre des cases :

Code : Tout sélectionner

SELECT x, y, img FROM map WHERE x > position_x_perso - 5 AND x < position_x_perso + 5 AND y > position_y_perso - 5 AND y < position_y_perso + 5 ORDER BY y, x
On a x en horizontal et y en vertical, le coin en haut à gauche est x = 0, y = 0.

La boucle sert ensuite à afficher les cases, par exemple dans un tableau :

Code : Tout sélectionner

echo début du tableau boucle sur les y echo début de ligne <tr> boucle sur les x echo la case : echo <td> contenu </td> fin boucle x echo fin de ligne </tr> fin boucle y echo fin du tableau
A+

Pascal

par tweak » 06 mai 2009, 11:07

Pardonnez mon doublon, je viens de voir ta signature c'est plutôt cool, je pensais pas qu'il existait une tel communauté ! Je dois m'absenter mais je prendrais le temps de consulter le site à mon retour ce soir :o

par tweak » 06 mai 2009, 11:00

Bonjour et merci pour cette réponse matinal :)

Je n'avais pas pensé à faire un SELECT de la sorte, effectivement ça ne listera que les entrée concernée :o

Par contre je ne comprends pas bien le contenue de ta boucle x et y, j'ai l'impression que tu à une solution efficace mais que je n'arrive pas à la trouver :s

Mika.

par pascaltje » 06 mai 2009, 09:51

Hello,

Souvent ce que l'on fait pour charger toutes les données d'une carte, c'est une seule requête, renvoyant :
- ce qu'il y a autour du personnage
- ordonné selon les X
- ordonné selon les Y

Et on parcourt les résultats via 2 boucles imbriquées, une pour X, une pour Y

Concretement pour voir la carte sur +/- 5 cases de chaque coté du perso, on a le SQL :

Code : Tout sélectionner

SELECT x, y, img FROM map WHERE x > position_x_perso - 5 AND x < position_x_perso + 5 AND y > position_y_perso - 5 AND y < position_y_perso + 5 ORDER BY x, y
Puis en php on a :

Code : Tout sélectionner

boucle sur les x boucle sur les y afficher la case fin boucle y fin boucle x
Voilà les grandes lignes.

A+

Pascal

Création d'une carte, solution la plus efficace ?

par tweak » 06 mai 2009, 06:14

Bonjour.

Je suis en train de réaliser une sorte de carte pour un jeux.

Voila comment fonctionne mon code :

Il y à un tableau HTML qui fais 23 colonnes et 17 lignes.
Vous pouvez voir ce tableau ici :
http://burgerkill.fr/temp/edit-map-small.htm

Le centre de cette carte correspond à la position d'un personnage. Par exemple, si ce personnage à dans la base de donnée x5,y5 alors l'image charger au milieux du tableau sera celle qui, dans la base de donnée, à pour x=5 et y=5.
C'est pourquoi on peut voir la variable $p0p0 au centre, qui signifie x plus 0 et y plus 0.

On comprends donc que la case juste au dessus, $p0m1 signifie x plus 0 et y moins 1. Si vous m'avez compris jusque là, passons au chose sérieuse.

Vous comprenez que mon script va devoir charger 23x17 images en fonction de la position initial du personnage. Sois 391 images :s

J'ai pensé à deux méthode et je voudrais savoir laquelle serais la plus légère et surtout si il n'y en à pas une plus efficace ?

/!\ Les codes sont la à titre d'exemples pour illustrer le fonctionnement, je sais qu'ils ne sont pas exacte. /!\

Voici donc la première :

- Un listing de toute la table " map " avec au total 391 if, par exemple :

Code :

if (($x=$x-1) and ($y=$y-1)) { $m1m1=$img; }
if (($x=$x-1) and ($y=$y-2)) { $m1m2=$img; }
if (($x=$x-1) and ($y=$y-3)) { $m1m3=$img; }
etc ...

Le problème avec cette méthode c'est qu'il va faire listing de toute la table, même des entré correspondante à une position x,y qui n'est pas dans le tableau.

La deuxième méthode :

- Un listing colonne par colonne, ce qui veut dire que je ferais plusieurs listing. Par exemple :

Code :

$listing = mysql_query("SELECT img FROM map WHERE x=$x-1");
$listing = mysql_query("SELECT img FROM map WHERE x=$x-2");
$listing = mysql_query("SELECT img FROM map WHERE x=$x-3");

et pour chaque listing de la table, je ferais une série de IF vérifiant la valeur de y, par exemple :

Code :

if ($y=$y-1) { $m1m1=$img; }
if ($y=$y-2) { $m1m2=$img; }
if ($y=$y-3) { $m1m3=$img; }

Donc pour résumé, dans la première méthode j'ai un listing total de la table (donc si la table map contient 1500 entrée, il va toute les vérifier juste pour en sortir 391 !

Avec la deuxième méthode il va faire 23 requettes différente au lieux d'une seul, car il y à 23 colonne, en contre partie il ne va fouiller que les entrée dont le champ x correspond à ceux du tableau html.

Laquelle de ces méthode serais la plus légère et surtout, quelqu'un aurais une idée moins rébarbatif ?