Celà fait longtemps que je veux réaliser un jeu du royaume, c'est à dire un jeu où l'on gère un domaine quelconque (oui, c'est le nom originel de ce genre de jeux). Eh bon, après environ 25 ans, me voilà à l'ouvrage.

samedi 16 juin 2012

Mise à jour d'après examens

- Meilleur affichage des cases.
- Multi-joueurs en local.
- Affichage de la liste des constructions possibles dans les villes.
- Affichage approché de la population des villes sur la carte (option).


Changement de la formule du calcul de hauteur des cases (et autres éléments de terrain) :

var taille_case_vertical = (taille_case/2)+(taille_case/8);


La formule précédente était en fait fausse. Je l'avais donc mise en commentaires, et bien sûr il n'y avait donc plus de "height" dans le tag d'image, ce qui ralentissait évidemment le navigateur (quand on ne met pas les tags de taille, le navigateur doit le rechercher DANS le fichier d'image lui-même. C'est plus lent).


Il a aussi fallu que je redimensionne mes images, afin de les faire tomber toutes sur un compte juste, genre 320*200 pixels (rapport 1/6, en fait, car il faut compter la hauteur du sous-sol dans le lot).
Ça c'est lourd, mais c'est l'expérience qui rentre, et la preuve qu'il vaut mieux TOUT préparer lorsqu'on se lance dans un projet quelconque.


Autre amélioration, le jeu supporte à présent le multi-joueurs (en local. Comme je l'ai dit, je ne connais rien au multi par internet).
L'appui sur le bouton de passage de tour ne fait avancer au tour suivant que si tous les joueurs sont passés, sinon il fait simplement passer au joueur suivant.
Pour l'instant, chaque joueur (humain) peut tout faire.


Dans le panneau de ville, la liste des batiments s'affiche.


Toujours dans le panneau de ville, le nom des armées constructibles s'affiche (le combat est basé sur des armées composées de bataillons).


J'ignore si je l'avais déjà mis en place avant les examens, mais l'affichage de la population des villes sur la carte peut aussi se faire de manière approchée :

if (carte_ville_pop_type == 1) {var b = ville_population[a];} else {var b = Math.floor(Math.log(ville_population[a]/carte_ville_pop_desc[0])/Math.log(carte_ville_pop_desc[1]));}

La valeur approchée consiste, grosso-modo, à afficher la population non sous sa valeur exacte, mais avec un nombre symbolique (comme dans les "civilization"). J'utilise les logarithmes, pour ça.




mercredi 6 juin 2012

Examens terminés !

Oh mon dieu, c'est terminé !

J'ai trouvé la dernière épreuve la plus stressante de toutes, bizarrement. En informatique, une matière où j'ai 20 de moyenne et 19,5 aux "partielles" (à cause d'une étourderie. Grr).

Mais je ne sais pas : Je me suis retrouvé bloqué sur une histoire de logique bête. J'avais oublié que non(x)=faux peut se simplifier en x=vrai (pour les opérateurs logiques).

Oui, c'est bête, mais ça s'appelle le stress, les enfants. C'est le truc en octobre on avait déjà vu.

Heureusement, comme j'ai fini le reste avec un quart d'heure de rab (prog de tableur, requêtes SQL, tout ça...), je suis revenu dessus : Ça me désespérait vraiment trop de perdre 3 pts sur 20 alors que je pensais avoir fait un sans faute pour le reste (j'ai quand même un doute sur deux points, alors mettons 18/20, sauf étourderie ?).

Et puis là, la lumière : Bon sang, mais c'est bien sûr !
Ou, dit autrement : 'tain, y'a sûrement une loi qui interdit d'être con comme ça...

Et j'ai résolu la question.


N'empêche, c'était stressant.

Mine de rien, maintenant que c'est terminé, je trouve que c'était même agréable de stresser comme ça.


----


Allez, encore un jour ou deux pour se remettre, et on va se remettre à Ratsodie (demain, moi y'en a fêter ça avec d'autres camarades de classe).

jeudi 10 mai 2012

Préparation d'examens

Salut,

Je pense mettre une mise à jour dimanche prochain. Le jeu a encore bien avancé, mais je veux finir le passage des joueurs avant ça.
Ce qui m'a permis d'ajouter, finalement, le multijoueurs. C'était assez simple : Il suffisait de mettre une variable pour l'IA (0 = pas d'IA = joueur humain) pour chaque joueur, et ça roule.


Au passage, j'ai été voter à l'élection. J'ai voté Marine le Pen.

Pas honte. Fier d'avoir assumé.
Et pas de leçons de morale à recevoir des nostalgiques d'une idéologie qui a assassiné plus de 150 millions de personnes au XXe siècle et à ceux qui les considèrent malgré celà comme de bons représentants de la démocratie.

jeudi 19 avril 2012

Garder les données en mémoire

Ayant multiplié les scripts comme d'autres les pains, je me suis retrouvé face à un autre problème : Comme on garde les variables, en fait ?

La solution que j'ai trouvée, est toute simple : Je les mets en attribut des images présentes sur l'écran.

En effet, on peut donner n'importe quel attribut à un élément HTML (au moins les images). Il faut juste éviter de donner un nom "réservé" (c'est à dire qui à un sens pour le navigateur lorsqu'il le trouve comme attribut).

Un navigateur qui ne reconnaît pas un attribut se contente de l'ignorer.
J'ai donc placé comme attribut aux villes des choses comme leur nom, le joueur auxquelles elles appartiennent, leur population, etc.

Sur le bouton de passage de tour, j'ai mis des données plus générales (comme le tour en cours, bien sûr).

Ensuite, comme je sais évidemment où je place quoi, il suffit à un script en ayant besoin d'aller chercher l'attribut voulu.

Par exemple :

    document.getElementById('case8[2]').setAttribute('bloquer','1');

Au début du script se chargeant d'afficher la "fenêtre" de ville, cette commande change l'attribut "bloquer" du bouton de passage de tours ('case8[2]', c'est son nom, pour le moment).

Quand le joueur clique sur le bouton de sortie de cette fenêtre, le script commence par :

    document.getElementById('case8[2]').setAttribute('bloquer','0');

En clair, il remet l'attribut "bloquer" du bouton de passage de tour à 0.

À quoi ça sert ?

Eh bien quand le joueur clique sur le bouton de passage de tour, son script fait ça :

    var bloquer = document.getElementById('case8[2]').getAttribute('bloquer');
    if (bloquer =='0')
    { reste du script }

Il lit la valeur de l'attribut "bloquer", toujours au même endroit, et la place dans une variable, simplement appelée "bloquer" aussi.

Puis il vérifie si "bloquer" vaut 0. Si tel est le cas, il exécute le reste du script, sinon ben il va tout de suite à la fin du "if", et là il n'y a plus rien, donc le script s'arrête.

En pratique, du point de vue du joueur tout au moins, celà désactive le bouton de passage de tour lorsque la fenêtre des villes est affichée.


mardi 17 avril 2012

Gloire à la Nuée !

Quand j'ai voulu écrire le code pour le passage des tours, j'ai naturellement écrit ça à la suite du code précédent, dans le même script.

Au début, ça marchait bien : Les tours passaient, une "alert box" suffisant à arrêter le jeu entre chaque tour.

Et puis j'ai ajouté du code pour remplacer l' "alert box" par une pause automatique entre les tours, le jeu passant au tour suivant par clic sur une image directement sur la page.

Et c'est là que ça s'est compliqué : Javascript n'a pas de système de pause intégré.
J'ai donc mis un pause "infinie" (un while avec une condition fausse par défaut).

Une interception d'évènement étant sensée changer la condition en "vrai" si le joueur appuyait sur le bouton de passage de tour.

Ah ouais mais non... Ça ne marche pas comme ça, finalement : Non seulement, apparemment, un script en cours ne lit pas les évènements, ce qui veut dire qu'on ne peut pas lui faire prendre en compte un clic, mais en plus les navigateurs ne supportent pas les scripts qui durent trop longtemps, à commencer par les boucles "infinies".

Moi y'en a être bien embêté.

Alors j'ai fini par me résoudre à ne pas faire un seul script monolitique, mais un par action désirée.
Finalement, ça marche aussi bien : Le script originel (et non "original", bande d'anglomanes !) se charge de créer la carte et de mettre en place tous les éléments du jeu, un autre script intercepte les clics sur le bouton de passage de tour et... fait passer le tour, un troisième script ouvre une "fenêtre" spéciale lorsqu'on clique sur une ville, et voilà.

Finalement, c'est même probablement plus simple.

lundi 16 avril 2012

Tours et fenêtre de ville


Ratsodie a bien avancé. C'était dur. En particulier, j'ai eu des surprises avec les CSS.

Figurez-vous que le positionnement des éléments (via CSS, donc) dépend de l'élément dans lequel ils se trouvent. Par exemple, une image placée dans un "div" dépend du positionnement du div.

Jusqu'ici, rien d'incompréhensible.

Ouais... Sauf que ça veut dire que si l'élément parent (ici le "div") ne possède pas de position déclarée comme telle, il y a des chances qu'un ou plusieurs éléments "enfants" (ici l'image) ne se positionne pas correctement.
Par exemple, dans mon cas, alors que toute la carte s'était correctement installée, les deux derniers éléments affichés par le script (une image et un texte) ne s'empilaient pas correctement : Le texte apparaissait en dessous de l'image, alors que leur z-index spécifiait clairement le contraire.

Et le plus drôle : Quelque soit le z-index spécifié, les deux éléments en question s'empilaient correctement avec les autres éléments.
En clair, je pouvais avoir la carte par dessus l'image, elle-même par dessus le texte, et ce dernier par dessus la carte (ce qu'on pouvait constater en les faisant déborder les uns des autres)...

J'ai eu la réponse sur le même forum que la dernière fois (merci Rtrethewey et Eye for Video) : Il me fallait préciser dans le DIV qui contenait mes deux derniers éléments (bref, leur parent) un posisitionnement, z-index compris.

Tu parles d'une chierie...



Enfin, quoi qu'il en soit, voilà l'évolution du moment :

Passage des tours
- En appuyant sur le gros bouton vert (piqué sur OpenCliparts, pour le moment), on fait avancer le tour, qui est lui indiqué en haut à droite.
- On peut spécifier le premier tour.
- Ainsi que le dernier.
- L'incrément.
- S'il y a un tour 0 (sinon, le jeu ajoute l'incrément).
- S'il y a un numéro d'ère (avant et après le "point zéro" du "calendrier"), et ce que c'est (genre "av. JC" et "ap. JC").
- Le bouton de tour peut se placer où le veut le moddeur.

Population
- En dessous du numéro de tour, est indiquée la population totale de l'empire du joueur. Ce nombre n'est pas recalculé à chaque tour, mais seulement lorsque quelque chose change (ce qui signifie que, pour le moment, il ne change pas du tout...)

Villes
- En cliquant sur une ville, on ouvre une fenêtre : Celles des villes.
- Pour le moment, cette fenêtre n'indique que le nom de la ville.
- En bas à droite (également plaçable ou le souhaite le moddeur), un bouton de sortie (tout aussi également piqué sur Openclipart, avant que je crée les miens). En cliquant dessus, on ferme la fenêtre (en fait, on appelle une fonction qui détruit le DIV de la fenêtre de ville).



La prochaine fois, j'espère avoir ajouté les premiers aménagements de ville (les constructions, quoi).

dimanche 1 avril 2012

Villes, population et civilisation

Voici les mises à jour du moment :

- Les villes ont à présent un nom.

Ce nom s'affiche au dessus de l'image de la ville, dans un cadre coloré.

À côté, certaines villes ont une étoile. C'est le symbole de capitale.

En dessous de la ville, un autre cadre, qui indique la quantité de population présente.

Je n'ai pas réellement cherché à centrer ces cadres ; on verra plus tard.


Pendant que j'y étais, j'ai introduit le principe des races (des camps, des civilisations, etc.).

En clair, j'ai ajouté une section "civilisations" à la partie "mod" du script. Pour le moment, cette section n'indique que la couleur de chaque civilisation, comme ça :

// Civ1
civ_couleur[1] = "00FFFF";

// Civ2
civ_couleur[2] = "FFFF00";

Ensuite, chaque joueur (humain ou machine) possède une civilisation :

joueur_civ[1] = 1;
joueur_civ[2] = 2;

Celà signifie, ici, que le joueur 1 joue une civilisation de numéro 1, et le joueur 2 une civilisation numéro 2.
Comme vous vous en doutez, plusieurs joueurs peuvent jouer la même civilisation, mais je ne me suis pas encore penché sur le moyen de les différencier sur la carte.

Ensuite, pour les villes :

ville_position[1] = "5*3";
ville_nom[1] = "Ville 1";
ville_joueur[1] = 1;
ville_capitale[1] = 1;
ville_population[1] = 10000;

Pour le moment, donc, une ville est définie par sa position sur la carte, son nom, le joueur à qui elle appartient, si elle est une capitale (1 = oui), et sa population.



Je tiens à remercier Padonak (et Trethewey), du forum "webdeveloper", pour leur aide au sujet de l'affichage de texte via javascript : innerHTML permet d'ajouter du text dans un "createElement".

mercredi 21 mars 2012

Afficher les villes

Bon. Il est temps de passer à la vitesse supérieure : Les villes.

Pour commencer, j'ai créé une image de ville toute simple, faite de petits cubes avec des portes : Ça peut représenter assez facilement une ville antique sous les pays chauds, genre mésopotamie, ce qui est très pratique puisque c'est là qu'elles sont sensé être apparues.

J'appelle cette image "ville.svg".

Maintenant, dans la partie "mod" du script, j'ajoute deux villes :

Eeeeeeet... le couper_coller via la souris n'est pas pris en compte par google-blogger. Ça fait rien, ils feront comme Apple et diront que c'est une inovation quand ils l'ajouteront). Heureusement, reste  CTRL+C (j'ai eu peur que ça ne fonctionne pas, après tout on est sous Linux).


// Ville préplacées
var ville_position = new Array();
var ville_nom = new Array();

ville_position[1] = "5*3";
ville_nom[1] = "Ville 1";

ville_position[2] = "6*13";
ville_nom[2] = "Ville 2";


Dans la variable "ville_position", je mets la position comme pour les rivières, c'est le plus simple.
Dans "ville_nom", je mets le nom de la ville.

Pour l'afficher sur la carte, un petit coup de

// Afficher les villes préplacée.

if (ville_position.indexOf(fleuve_element) != -1)
{
var ncase = "ville.svg";
case4[i3+"*"+j3] = document.createElement("img");
case4[i3+"*"+j3].src=mod+"/terrain/"+ncase;
case4[i3+"*"+j3].setAttribute('width',taille_case);
//case4[i3+"*"+j3].setAttribute('height',taille_case_vertical);
case4[i3+"*"+j3].setAttribute('id','case4['+i3+'*'+j3+']');
document.getElementById('ratsodie').appendChild(case4[i3+"*"+j3]);
case4[i3+"*"+j3].style.position = 'absolute';
case4[i3+"*"+j3].style.bottom = i2 + 'px';
case4[i3+"*"+j3].style.left = j2 + 'px';
case4[i3+"*"+j3].style.zIndex = j4+1;
}


Bref, même chose que d'habitude.

Jusque là, ça baigne, même si j'avais commencé par mélanger les case2, 3 et 4 (sinon, ça ne serait pas drôle), et bien sûr j'avais oublié de créer un tableau vide "case4" d'abord. Grr.


Prochains grands travaux : Afficher le nom de la ville au dessus de l'image.

Vous les voyez, les deux petites villes ?
Bon, ben j'ai réussi à télécharger l'image via Firefox (c'est vexant, mais quand ça veut...)


samedi 17 mars 2012

Optimisation des images

Plus j'avance, plus je me dis que l'utilisation de graphismes vectoriels pour les images lourdes et fréquentes (par exemple, les forêts) est une mauvaise idée.

Celà ne semble apporter qu'une bonne réaction au zoom, mais pour le reste les navigateurs souffrent comme c'est pas permis. Et comme il semble impossible à un javascript de modifier quoi que ce soit dans l'affichage d'une image SVG externe (genre, les couleurs), ça me fait une carte de plus en plus lourde, qui me fait planter la plupart des navigateurs.
Quand Firefox est le meilleur navigateur, c'est qu'il y a vraiment un problème...

Avant de voir s'il y a lieu de passer au bitmap (et l'absence de programme capable de gérer convenablement la transparence des PNG), j'ai commencé à voir si je ne pouvais pas améliorer l'affichage.

J'ai commencé par optimiser les scripts SVG. Une simple image peut ainsi passer de près de 500 ko à moins de 5 en virant le verbiage d'écureuil sous acide d'Inkscape. Le seul problème est qu'il faut penser à chaque fois à l'empêcher de sauvegarder en "svg inkscape" après toute nouvelle image.

'sont fous ces mecs là.

Ensuite, j'irai jeter un oeil à la transformation svg->bitmap avec mise en cache directement par le navigateur, dont j'ai entendu parler. Si ça marche vraiment, celà pourraît résoudre mon problème.

samedi 3 mars 2012

Ordre d'affichage des arbres

Ratsodie, pour afficher les forêts, divise chaque case en neuf, et met, nous l'avons vu, quelques arbres dans chaque case s'il y a lieu.

J'ai donc réalisé neuf images de forêts, chacune équipée d'arbres au niveau d'un neuvième de la taille d'une case de terrain. Ensuite, dans le code, une boucle de 1 à 9 affichait chaque morceau de forêt.

Mon problème est que je n'ai pas trop réfléchi, et j'ai fait s'afficher les morceaux de forêt dans cet ordre :

 1 - 4 - 7
 2 - 5 - 8
 3 - 6 - 9

Si vous avez lu ma dernière bafouille, vous pouvez vous rendre compte : Les arbres situés à l'est s'affichent par dessus ceux à l'ouest, C'est assez peu visible sur les images du blog, mais celles du jeu sont plus grandes, et là ça saute aux yeux.

Pour réparer, j'ai été au plus simple : Plutôt que modifier le code afin de lui faire afficher les images dans un autre ordre, ce qui s'avérait pour moi assez compliqué (contrairement au terrain, il n'y a qu'une seule boucle pour les forêts), j'ai simplement renommé les images de forêts afin de les faires coïncider avec l'ordre d'affichage souhaité.

En clair, les images ouest sont passées à l'est et vice-versa : 1, 2 et 3 sont devenues 7, 8 et 9, et inversement.