JeuWeb - Crée ton jeu par navigateur
demi-terrains? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Gameplay, gamedesign (https://jeuweb.org/forumdisplay.php?fid=48)
+--- Sujet : demi-terrains? (/showthread.php?tid=5186)

Pages : 1 2


demi-terrains? - Argorate - 20-01-2011

Bonsoir,

J'aurais aimé aborder avec ceux que ça intéresse, une chose assez absente dans la plus part des jeux amateurs (voir pro), qui concerne avant tout l'apparence/le design du plateau de jeu et en partie le GP.

En effet généralement le joueur a une map découpé en case (peut importe leur forme), qui ont chacune une image de fond d'un terrain. Jusque là tout vas bien, mais généralement là où ça devient plutôt moche c'est au changement de terrain, la séparation est net et il n'y a pas de "demi-terrain". Exemple il y a de la plaine et de la foret cote à cote, il faudrait sur les cases frontalière aux deux terrains avoir une case qui serait un hybride de foret et de plaine.
Il faudrait donc à la fois, de manière graphique (l'image du demi-terrain doit s'ajuster et faire une jolie transition et ce dans toute les combinaisons/directions possible) et d'autre part la case doit avoir un mixte des propriétés des deux terrains qui le compose.
Après je ne parle même pas des terrains qui sont un hybride de 3 ou 4 terrains en même temps... (même s'il faudrait pouvoir le gérer également)


Tout ça c'est super, mais ce qui m'intéresse c'est au niveau de la conception.
Quel méthode utiliseriez-vous pour créer ce genre de chose?

La solution de faire à la main, case après case (même via un éditeur de map fait maison) semble être une tache assez titanesque (enfin tout dépend de la taille de la map, mais en général c'est pas juste 10*5 cases^^)

Donc si vous avez des idées astuces a ce propos, j'écoute Smile


RE: demi-terrains? - Anthor - 20-01-2011

Y'a longtemps j'utilisais une div avec plusieurs couches à l'intérieur.

[Image: maquette_carte-html_m.jpg]


RE: demi-terrains? - Argorate - 21-01-2011

Oui, le problème n'est pas au niveau technique mais au niveau conception.

Comment tu créé t'as map? tu l'as met en bdd? et après comment tu lui dis où il y a des bi-terrains? et quel angle adopter? (comme on le vois sur ton image, selon la position, l'image de bi-terrain n'est pas orienté pareil...)


RE: demi-terrains? - Holy - 21-01-2011

Moi j'ai une solution qui fonctionne terriblement bien mais qui demande beaucoup d'abstraction avant conception. C'est directement inspiré de la manière dont les "autotiles" de RPG Maker fonctionnent, en un peu plus poussé pour certaines fonction (notamment pour gérer la hauteur).

J'explique l'idée des autotiles de RPG maker avec une petite illustration ça sera plus simple :
[Image: Auto_tile_example.gif]

Depuis cette image, il est possible de faire toutes les possibilités de bordure grâce aux cases C et D. La A ne sert qu'à être sélectionné dans l'éditeur et la B est ignoré.

A partir de cet autotile, le gestionnaire de rendu va déterminer les bordures à sortir en fonction des cases voisines. Si c'est une tuile différente de celle où le curseur se trouve, alors on met une bordure orientée vers elle.

Cette technique est pratique pour faire des bordures automatiques mais y a un obstacle majeur, il faut pouvoir gérer facilement la création d'images de toutes les possibilités (y en a une quarantaine au total si je ne me trompe pas) et donc ça peut bouffer de la bande passante sacrément vite et il faut pouvoir les générer automatiquement avec une librairie d'image, sinon c'est la misère (faites pas ça à la main quoi ^^).

J'ai pendant longtemps utilisé un script PHP perso qui prenait l'image montrée plus haut et qui créait automatiquement les 46 possibilités différentes de case (32px sur 32px) de ce type. C'était pas trop difficile à maintenir, mais c'est quand même pas l'idéal, surtout niveau bande passante et fluidité du coup.

Je suis passé depuis deux semaines à un autre système, beaucoup plus puissant qui me permet de faire ceci :

<div class="water">
<div class="n-o"></div><div class="n-e"></div>
<div class="s-o"></div><div class="s-e"></div>
</div>
Donc en gros, j'ai un div supérieur qui constitue ma case et qui précise le type de tuile (ici water) et à l'intérieur j'ai 4 sous-calques (16px sur 16px) qui constituent chacun le quart de l'image. Chaque quart affiche la bonne bordure (c'est un script php qui lui indique quelle mini image afficher) ^^

Ca me permet de n'avoir plus que 20 images par type de tuile, mais surtout des images quatre fois plus petites, ce qui me permet de gagner en qualité (16 x 16 = 256 couleurs, donc je suis sûr de ne pas perdre de qualité, tout en pouvant compresser à fond), en bande passante (les images sont moins nombreuses et de plus petite taille). J'ai juste un fichier Css qui est foutu en cache et qui fait 1ko par tuile, donc rien de bien énorme.

Le tout est automatisé désormais, j'ai juste à ajouté une tile dans mon dossier spécial autotiles et hop il m'ajoute un dossier avec les 20 parties d'images dont j'ai besoin et il génère automatiquement un fichier Css qui me permet d'afficher les quarts de case en background des sous-calques. Quand je lance la carte, j'ai un préloader qui charge toutes les mini-images des tuiles, comme ça après le reste n'est plus qu'une question de Css

Je suis vraaaaiment pas sûr d'avoir été clair, le sujet étant particulièrement chaud à expliquer. Je pense que le plus simple serait que je fasse une petite vidéo de mon éditeur et de mes modules de génération automatique.

Dans tous les cas, ça demande pas mal d'efforts de conceptualisation, mais quand on arrive au bout, c'est un bonheur à tout point de vue (j'ai passé la nuit passée à coder un algorythme de compression JSon pour ma carte, c'était sport mais j'économise plus des trois quarts de mes ressources). J'arrive à générer de belles cartes dynamiques, complexes qui me prennent pas plus de 1.5.ko par requête ajax de cette manière. Ma carte est diablement plus fluide depuis que je suis passé sous ce système.

Edition : J'ai fait une vidéo super rapide, je suis sur mon eeePc, donc ça lag un peu >_< Mais je pense qu'on voit l'essentiel : http://www.youtube.com/watch?v=NXwjewFHAxQ (désolé pour le son bizarre)

Chaque case est en fait divisé en quatre sous cases. Et chaque fois que je pose une tuile, les 9 cases au tour sont actualisées en fonction de la nouvelle tuile.


RE: demi-terrains? - Colmea - 21-01-2011

Je ne comprends pas trop ?

Ca doit se faire au niveau de l'éditeur de map non ?
Dans ce cas, voici ce que je ferais:

A chaque fois qu'on applique une texture à une case (du sable, par exemple), l'éditeur va automatiquement ajouter les 8 "textures de transitions" aux 8 cases adjacentes.
Et évidemment, avant qu'il mette la texture de transition sur une des 8 case adjacente, il vérifie que celle-ci n'a pas déjà une texture sable. Si c'est le cas, il la laisse évidemment.


Je doute avoir répondu à la question, mais sait-on jamais Smile

EDIT: Déso, pas vu le post précédent de Holy. Je répète ce qu'il a dit Smile


RE: demi-terrains? - Argorate - 21-01-2011

J'avoue Holy, ne pas avoir tout compris à ton explication^^
Mais après avoir vu la vidéo, je comprend un peu mieux, mais ça m'amène à une autre question. Parce que là tu parles et travailles avec un éditeur de carte mais comment tu fais ensuite pour stocker ta map? une fois que tu as fini avec l'éditeur, tu enregistres via une moulinette php qui fait des requêtes SQL pour chaque case?
Si c'est le cas, comment tu stock l'information? parce que terrain eau qui a des bords de sable en haut, a gauche et a droite, c'est différent du terrain eau avec des bords de sable qu'a gauche par exemple...

Donc si je comprend bien, tout est basé sur ton éditeur de map? C'est a dire comme le dit colmea, quand tu rajoutes un terrain, cela détecte où tu as cliqué et applique aux 8 cases alentours des transitions?

Mais je n'ai pas bien saisie ton histoire de découpage en 4 (pourquoi 4 et pas 8? puisqu'il y a 8 directions possible)?


PS: ton éditeur est vachement classe! Smile


RE: demi-terrains? - Holy - 21-01-2011

(21-01-2011, 11:58 AM)Argorate a écrit : J'avoue Holy, ne pas avoir tout compris à ton explication^^
Mais après avoir vu la vidéo, je comprend un peu mieux, mais ça m'amène à une autre question. Parce que là tu parles et travailles avec un éditeur de carte mais comment tu fais ensuite pour stocker ta map? une fois que tu as fini avec l'éditeur, tu enregistres via une moulinette php qui fait des requêtes SQL pour chaque case?
Si c'est le cas, comment tu stock l'information? parce que terrain eau qui a des bords de sable en haut, a gauche et a droite, c'est différent du terrain eau avec des bords de sable qu'a gauche par exemple...
Alors, je suis un "fada" (hem) des fichiers et de la sérialisation. Donc mes cartes sont découpées par zone (ce qu'on voit sur la vidéo est une zone, de 18 sur 18) et enregistrées par zone. Ce qui me permet, quand je charge une partie de carte, de ne charger que le fichier de la zone (il fait approximativement 10ko pour 324 cases sur 8 couches différentes pour l'éditeur).
C'est vraiment pratique et performant (c'est un bête tableau à dérouler quoi et y a moyen de mettre en cache pas mal de données fixes une fois qu'on est en jeu), à un obstacle près : les maintenances globales sur l'ensemble de la carte. J'ai une fonction qui me permet de charger l'ensemble de mes cartes, mais vu que je travaille sur un continent entier (énorme : 1092 zones au total), ça carbure sévère au niveau de la mémoire allouée. Heureusement, ce type de maintenance ne concerne que l'éditeur car mes parties se jouent que sur une partie de carte (en général pas plus de 30 zones).

Ensuite, je ne stocke dans l'éditeur que le type de la case : eau, continent, sable, désert, etc. Après quand je charge ma carte, mon moteur de rendu calcule le type de bords à placer. Donc, en ce qui concerne l'éditeur, je ne stocke pas le rendu des bordure, je le recalcule à chaque fois (c'est jamais que des comparaisons ^^). Quand on est en partie en revanche, vu qu'à priori le décor ne change pas, je mets en cache le rendu des bordures sous la forme de lettres (qui correspondent de toute façon à mon css).

Il est tout à fait possible de stocker le tout dans une base de données, quitte à mettre des données sérialisées (json_encode/decode ou serialise/unserialise) dans des lignes de tableau. Le truc c'est qu'il faut avoir un serveur qui puisse répondre rapidement en lecture, mais ça c'est la même partout ^^

(21-01-2011, 11:58 AM)Argorate a écrit : Donc si je comprend bien, tout est basé sur ton éditeur de map? C'est a dire comme le dit colmea, quand tu rajoutes un terrain, cela détecte où tu as cliqué et applique aux 8 cases alentours des transitions?
C'est exactement ça Wink J'ai une bête réponse ajax (XML, mais je vais passer en JSon d'ici peu) qui dit : change le contenu des 8 divs environnantes avec telle et telle bordures, ainsi que celle où tu viens de cliquer

(21-01-2011, 11:58 AM)Argorate a écrit : Mais je n'ai pas bien saisie ton histoire de découpage en 4 (pourquoi 4 et pas 8? puisqu'il y a 8 directions possible)?
C'est difficile à expliquer, mais pour commencer : c'est possible de le faire avec 8, mais ça veut dire, sauf si je me trompe, que tous tes calques ne sont pas de la même taille ^^ Enfin, ça dépend comment tu le conçois en fait.

En gros, si tu découpes en quatre ta case de 32 sur 32, tu as pour chaque quart 5 possibilités :
- coin interieur
- coin extérieur
- bordure verticale
- bordure horizontale
- ni bordure, ni coin

Quand je rentre, je filerai un zip avec un de mes autotiles et les 20 images, ça sera plus limpide.
(21-01-2011, 11:58 AM)Argorate a écrit : PS: ton éditeur est vachement classe! Smile
Merci ^^

Ca représente pas mal de taff et je suis plutôt fier du rendu final, surtout qu'on navigue très rapidement entre les zones de la carte.


RE: demi-terrains? - Argorate - 21-01-2011

Bon, alors là je pense avoir un peu plus cerné la chose.
Le truc c'est que je pensais pas à ce cas de figure particulier : tu part d'une map par zone comme tu dis, c'est a dire une map définit et qui est fixe (en taille), à la rpgmaker en gros. Système différent du mien, où la carte est un monde continue comme dans la réalité. Du coup, dans ton cas, tu pourrais même ne plus te faire chier a faire tes map avec l'éditeur, tu pourrais mettre un fond qui est une seul image pour chaque zone et c'est terminer, mais bon on perd la possibilité de changer dynamiquement les terrains in game (après ça dépend de se qu'il est possible de faire ou non dans ton jeu, mais si les terrains ne peuvent être modifié dans le GP, ça peut être une solution).

Sinon effectivement ton découpage en 4 avec plusieurs possibilités pour les 4 quart me plait bien, je trouve que c'est judicieux.
Mais du coup, en résumé, ta méthode c'est le calcul : tu as un algo qui regarde pour chaque case ce qu'il y a autour et qui met les bords en conséquence (tu me dit si je me trompe Smile).
J'avoue que je chercher justement un moyen de substitution à cette méthode qui dois être fastidieuse à coder - mais qui une fois fait doit être un vrai régal, je l'avoue ^^
Faut coder tous les cas de figure, c'est assez chian non? Et de point de vue performance, ça n'alourdir pas trop le rendu, quand la map s'affiche si a chaque case il faut faire une moulinette pour regarder autour?

En tout cas y a de l'idée, mais j'avoue clairement que devoir coder un éditeur en sachant déjà tout ce qui me reste a coder m'enchante guère, limite me décourage pour l'instant. Sad


RE: demi-terrains? - Holy - 21-01-2011

(21-01-2011, 03:19 PM)Argorate a écrit : Bon, alors là je pense avoir un peu plus cerné la chose.
Le truc c'est que je pensais pas à ce cas de figure particulier : tu part d'une map par zone comme tu dis, c'est a dire une map définit et qui est fixe (en taille), à la rpgmaker en gros. Système différent du mien, où la carte est un monde continue comme dans la réalité. Du coup, dans ton cas, tu pourrais même ne plus te faire chier a faire tes map avec l'éditeur, tu pourrais mettre un fond qui est une seul image pour chaque zone et c'est terminer, mais bon on perd la possibilité de changer dynamiquement les terrains in game (après ça dépend de se qu'il est possible de faire ou non dans ton jeu, mais si les terrains ne peuvent être modifié dans le GP, ça peut être une solution).

Sinon effectivement ton découpage en 4 avec plusieurs possibilités pour les 4 quart me plait bien, je trouve que c'est judicieux.
Mais du coup, en résumé, ta méthode c'est le calcul : tu as un algo qui regarde pour chaque case ce qu'il y a autour et qui met les bords en conséquence (tu me dit si je me trompe Smile).
J'avoue que je chercher justement un moyen de substitution à cette méthode qui dois être fastidieuse à coder - mais qui une fois fait doit être un vrai régal, je l'avoue ^^
Faut coder tous les cas de figure, c'est assez chian non? Et de point de vue performance, ça n'alourdir pas trop le rendu, quand la map s'affiche si a chaque case il faut faire une moulinette pour regarder autour?

En tout cas y a de l'idée, mais j'avoue clairement que devoir coder un éditeur en sachant déjà tout ce qui me reste a coder m'enchante guère, limite me décourage pour l'instant. Sad
Ben niveau perf, au pire tu peux placer le rendu de tes bordures en cache (fichier, bdd, ...) ce qui permettrait de ne plus devoir refaire le calcul à chaque fois, mais dis toi que c'est jamais que des comparaisons, pour être tout à fait complet, j'ai 4 groupes de 5 comparaisons pour chaque case. Je doute que ça bouffe considérablement plus de mémoire que tout autre moteur de rendu et il est prévu, une fois qu'on est in game, d'avoir un champ de mon tableau qui comprenne directement le rendu, comme ça plus besoin de faire de comparaison ^^

Voilà exactement le passage avec les comparaisons :
if($content == $sN && $content != $sW) {
$aReturn[] = 'i';
}
elseif($content != $sN && $content != $sW) {
$aReturn[] = 'a';
}
elseif($content != $sN && $content == $sW) {
$aReturn[] = 'c';
}
elseif($content == $sN && $content == $sW && $content != $sNW) {
$aReturn[] = 'q';
}
elseif($content == $sN && $content == $sW && $content == $sNW) {
$aReturn[] = 'k';
}

if($content == $sN && $content != $sE) {
$aReturn[] = 'l';
}
elseif($content != $sN && $content != $sE) {
$aReturn[] = 'd';
}
elseif($content != $sN && $content == $sE) {
$aReturn[] = 'b';
}
elseif($content == $sN && $content == $sE && $content == $sNE) {
$aReturn[] = 'j';
}
elseif($content == $sN && $content == $sE && $content != $sNE) {
$aReturn[] = 'r';
}

if($content == $sS && $content != $sW) {
$aReturn[] = 'e';
}
elseif($content == $sS && $content == $sW && $content == $sSW) {
$aReturn[] = 'g';
}
elseif($content != $sS && $content != $sW) {
$aReturn[] = 'm';
}
elseif($content != $sS && $content == $sW) {
$aReturn[] = 'o';
}
elseif($content == $sS && $content == $sW && $content != $sSW) {
$aReturn[] = 's';
}

if($content == $sS && $content == $sE && $content != $sSE) {
$aReturn[] = 't';
}
elseif($content == $sS && $content != $sE) {
$aReturn[] = 'h';
}
elseif($content != $sS && $content != $sE) {
$aReturn[] = 'p';
}
elseif($content != $sS && $content == $sE) {
$aReturn[] = 'n';
}
elseif($content == $sS && $content == $sE && $content == $sSE) {
$aReturn[] = 'f';
}
Et dans aReturn j'ai le code bordure (les lettres correspondent aux classes générées dans le fichier css ^^).

Sinon, j'utilise sur ma carte actuelle un système avec des images en fond sur toute une zone, alors certes c'est pratique, mais c'est lourd à modifier (dépendance externe) et ça rend le contenu du jeu très statique. Sans parler du poids des images qui peut être handicapant ou alors faut compresser et appauvrir les couleurs (ce que je fais). Avec le système actuel, je conserve qualité et rapidité. Mes 20 images par tuile font 10k, donc si j'ai 20 tuiles différentes, ça me fait 200k à charger "une" fois (avec un petit loader javascript pour faire pro xD), pour avoir une carte plutôt sympa et qui se charge rapidement. Les interfaces de Motion Twin, et notamment leurs applications flash, font souvent plus de 1Mo ^^

Concernant le fait que c'est une carte infinie, ça n'est problématique que si tu n'as pas de mapping des zones. On pourrait imaginer que tu aies une sorte de "cartographie des zones" qui indique à ton script quel zone il doit charger si il se trouve à tel endroit de la carte. Moi j'ai pas besoin de mapping vu qu'un bête calcul en fonction de la largeur et de la hauteur de map me permet de savoir qu'en [39-10] on est en zone 10 (par exemple). Enfin, de toute façon, les fichiers ne sont pas la seule solution et comprennent quelques soucis, notamment niveau de l'exclusivité en écriture, mais ça c'est pour plus loin, quand y a beaucoup de modifications successives.

Faut aussi faire le rapport entre investissement et intérêt ludique. Etant donné que je voulais recentrer la v1 de Terres de Cy autour de la carte, je m'y suis consacré à fond, avec gestion des niveaux, possibilité de placer des villes, des routes, etc. Mais je pense que ça vaut le coup "in fine".
Je suis revenu globalement trois fois en profondeur sur mon module de carte et là je pense que je tiens le bon bout niveau qualité, automatisation et compression du retour ajax.


RE: demi-terrains? - Holy - 22-01-2011

Voilà le zip avec la découpe type Wink