dimanche 11 mars 2007

Petit module pour le moteur réseau

Voila un petit bout du moteur réseau que j'ai rapidement griffonné ce soir.
Il s'agit de la partie qui va gérer la fréquence de rafraîchissements des autres joueurs en fonction de la distance qui les sépare du joueur.

Le système est plutôt simple, du moment que l'on a les coordonnées des joueurs. On assimile le terrain à un repère. Et on applique la formule :

AB = V((Xb-Xa)²+(Yb-Ya)²)

V() = racine carré.
X et Y coordonnées.

Ici on a la classe PersoPosition pour le joueur, qui contient les coordonnées x et y sous la forme :
PersoPosition.x
PersoPosition.y

On a aussi la classe Player (qui représente les peers) :

public class SPlayer{

protected static int counterid=0; //Le counter id commun à tous les
player
protected string login=""; //Le nom du peerpublic
public float x = 0;
public float y = 0;
public float z = 0;

Id=counterid++; //Défini son ID unique
public float d = 0;
}

d représente la distance.
Ici on obtient la hauteur (y) par rapport à la heigtmap.
Donc la formule va concerner x et z mais ca ne change rien.

On calcul la distance de notre joueur avec les autres peers par une fonction du type (la syntaxe n'est pas respectée.) :
For 1 to idcount. + calcul et stockage
On stocke le tout dans la classe Splayer de tel ou tel id.
Et en fonction de ça lors de notre fonction qui met à jour les positions, certains peers ne seront mis à jour que 1 fois sur 4 ce qui permet d'économiser, une fois de plus, beaucoup de bande passante dans les grandes zones.

Il est évident que ce genre de technique ne s'applique pas à tout le jeux. Un jeu de sniper ne peut pas se permettre ceci et c'est pour cela, que pour le cas d'avalon, j'inclus une conditions de plus (mais qui n'est aucunement indispensable.).


Certains flous/incohérences persistent car je n'ai pas encore mis en relation le moteur réseau et le jeu. Donc je créé l'exemple en même temps que l'écriture de ce post.



De son côté le jeu n'a pas bougé.

Voila c'est tout pour ce soir.

jeudi 8 mars 2007

Quelques nouvelles

Salut à tous,
je n'ai pas beaucoup avancé depuis le dernier post, mais je vous tiens tout de même au courant.

Partie Jeu :

J'ai intégré une ébauche d'éclairage et d'ombrage, bien que de nombreux bugs persistent, il est effectif sur le model du joueur en lui même (il ne projète pas d'ombre sur le terrain, mais les lumières s'applique sur lui.)
-> Screenshot et tutorial à venir.

Je suis en ce moment en train de changer le système de caméra car j'ai tenté de faire un système de caméra dynamique avec toutes ces données manuelle. Mais quelques bugs persistaient (les mouvements étaient très saccadés). J'ai donc décidé de refaire la caméra et le système de suivi en entier (et oui première refonte...)
-> Vidéo à venir et explication pour faire une caméra dynamique.

Partie Moteur réseau

Toujours aucune avancée, sachant que je fais un site pour une association, je suis plutôt pris.
-> j'espère d'ici la fin du mois la reprise du dev. du moteur réseau. (une fois les bases d'avalon posée.)



L'idée :


Bon maintenant je vais vous parler un peu plus du projet que j'ai entrepris; nommé Avalon.
Je me base sur un univers que j'affectionne particulièrement, celui du film avalon.
Pour ceux ne connaissant pas voici un court résumé (made in Wikipedia):


Dans un futur proche, le jeu de guerre illégal Avalon est un jeu vidéo sur lequel les joueurs branchent directement leur cerveau, et qui provoque des comportements addictifs. Certains joueurs sont tellement plongés dans le jeu que leur esprit y reste bloqué, leur corps demeure inerte, dans un état végétatif dont ils ne sortent plus : ce sont les non-revenus. Le nom « Avalon » provient de l'île de légende où vont les âmes des guerriers.

Comme dans tout jeu de tir subjectif, les personnages du jeu commencent avec des possibilités réduites et armés uniquement d'un pistolet et d'un chargeur, dans la classe C ; au fur et à mesure qu'ils remplissent des missions, ils accumulent des points qui leur permettent soit d'améliorer les capacités de leur personnage, soit d'acquérir du nouveau matériel, mais qui peuvent aussi être convertis en argent que touche le joueur dans le monde réel. En progressant, ils accèdent à des missions de plus en plus difficiles, avec plus de contraintes (par exemple un temps limité pour réaliser la mission), dans la classe B puis la classe A. Certains joueurs montent des équipes pour réaliser des missions en commun.


Voila qui pose les bases de l'univers.

Concrètement, j'aimerais reproduire un espace en extérieur si possible assez vaste (pour info le terrain montré lors de la vidéo fait 20Km*20Km en taille), où les joueurs évolueraient, seuls ou en équipes, dans le but de gagner des points, de monter en classe, et de survivre le plus longtemps possible.

Pas trop de contenu, quelques maisons/ruines/immeubles, des arbres, quelques armes et gadgets. Juste de quoi s'entretuer.

Voila pour l'idée principale.

ps : Le tout serait supporté par le moteur réseau dans la mesure du possible. (une persistance du serveur n'est pas nécessaire, un serveur annexe (Mysql) se chargera de conserver les informations des joueurs.)

C'est tout pour ce soir, je retourne à mon C# !

Edit : Finalement je garde la structure de base pour le systeme de caméra. J'ai tenté un système ou la caméra se place par rapport au joueurs, mais la caméra est soit trop "molle" , soit trop rapide et le système n'a plus aucune intêret.
Ainsi je vais continuer mes essais (non concluant pour le moment) pour faire trembler la caméra au rythmes des pas.

mardi 6 mars 2007

Intégration model 3D

L'intégration d'un model 3D pour remplacer le cube est faite.
Je m'attaque maintenant à plus dur, une gestion de caméra dynamique (à la gears of wars), afin que la caméra tremble lorsque l'on avance (comme des pas) et tout le tralala afin de dynamiser la caméra.


Je posterais l'explication pour l'intégration d'un model en *.3ds plus tard. Je vais pour le moment me pencher sur le système de caméra.


De son côté le moteur réseau n'a toujours pas avancé.

Voila pour les nouvelles du front. Rien d'exceptionnel, mais ça avance !

lundi 5 mars 2007

Création d'une entité qui suit la caméra (vue 3eme personne)

Partie Jeu :

J'ai consacré une partie de ma soirée à essayer de faire apparaitre une entité qui suivrait les mouvements de caméra. Tout d'abord rien ne vaut une vidéo afin d'illustrer mes propos.



Et donc l'explication pour arriver à ses fins :

Tout d'abord, il faut reprendre les anciennes sources (cf ancien post). A partir de là l'incorporation va être rapide car toutes les initialisations sont faites (et la caméra aussi normalement. Dans le cas présent on partira du systeme de coordonnées présent dans le tutorial (pour la caméra) ce qui permettra d'avoir une base commune).

En premier lieu il faut déclarer l'entité :
// On declare le perso
TrueVision3D.TVMeshClass Perso;
Avec ses coordonnées :
//Varialbe DirectX pour position/vecteur and coe (évite de tout gérer à la main)
DxVBLibA.D3DVECTOR PersoPosition;
Voici un raccourci assez appréciable pour ce qui est des coordonnées, angles, ... (nous verrons les différentes applications possibles dans la suite du post).
Cette technique évite les longueurs telles :
float sngPositionX;
float sngPositionY;
float sngPositionZ;
float sngLookatX;
float sngLookatY;
float sngLookatZ;
float sngAngleX;
float sngAngleY;


Par la suite on passe le système d'angle en degré (en même temps que la déclaration pour l'affichage des FPS) :
//On passe en degré
TV.SetAngleSystem(CONST_TV_ANGLE.TV_ANGLE_DEGREE);
En même temps créé l'entité Perso :
Perso = new TVMeshClass();
Perso = (TVMeshClass)Scene.CreateMeshBuilder("perso");
Perso.CreateBox(2, 1, 1, false);
Il y a certainement moultes manières plus rapide mais celle-ci marche.

On texture ce cube :
TextureFactory.LoadTexture("Resources\\hmap.bmp", "PersoTex", -1, -1, CONST_TV_COLORKEY.TV_COLORKEY_NO, true, true);
Perso.SetTexture(Globals.GetTex("PersoTex"), -1);


Maintenant que le cube est créé (existe dans le code) il faut s'occuper de son positionnement afin qu'il s'affiche correctement.

A la suite on met :
//Position de départ du perso
PersoPosition.x = sngPositionX + 5;
PersoPosition.z = sngPositionZ + 5;
PersoPosition.y = sngPositionY;
Ici, sngPosition désigne la position de la caméra (comme définit dans le tutorial).

Dans la fonction Check_movement il faut rajouter :
PersoPosition.x = sngPositionX + (float)(System.Math.Cos((double)sngAngleY) * 7);
PersoPosition.z = sngPositionZ + (float)(System.Math.Sin((double)sngAngleY) * 7);
PersoPosition.y = Land.GetHeight(PersoPosition.x, PersoPosition.z) + 3;
Afin de calculer la position du cube par rapport à la caméra.

Et enfin il faut mettre à jour (toujours dans check_movement) :
Perso.SetPosition(PersoPosition.x, PersoPosition.y, PersoPosition.z);
Perso.SetRotation(-90f + ((float)sngStrafe * 10f), ((float)sngAngleY * -57.295f), 0f);
Comme vous pouvez le voir le raccourci utilisé au depart ( DxVBLibA.D3DVECTOR PersoPosition) permet de gérer les postions et rotations, ce qui est amplement suffisant pour garder notre entité en vue.

Si vous souhaitez voir le code dans sa totalité rendez-vous ICI


Partie programmation réseau :
Je n'ai malheureusement pas avancé dans la programmation du moteur réseau, je suis pour le moment occupé par divers travaux.

Prochainement le chargement d'un model pour remplacer le cube.

dimanche 4 mars 2007

Affichage d'un terrain dans TV3D : Méthode détaillée

La méthode détaillée pour l'affichage d'un terrain sous TV3D arrive.

Je vais ici vous détailler pas à pas la démarche à suivre afin d'obtenir un résultat tel celui présenté dans le post précèdent que j'ai obtenue en m'inspirant moi-même de différents tutoriaux.
Premièrement il vous faut bien sûr TV3D (j'utilise la démo de la version 6.2), distribuée gratuitement sur le site officiel. Par la suite procurez vous L3DT un logiciel qui permet de générer des Heightmap et texture/Lightmap assez facilement. L3DT est disponible à cette adresse.

Nous allons tout d'abord créer les deux textures nécessaires à la création du terrain.

Pour la Heightmap :

  • File → New map → Design/inflate
  • Choisissez la résolution maximale pour la version standard (2048*2048) afin d'obtenir un résultat potable.
  • Validez afin d'arriver à la preview de la Heightmap.
  • Vous pouvez alors modifier à votre guise grâce aux outils Tools → DM paint tool.
  • Une fois satisfait de vos reliefs, Operations → Heightfield → Generate map. Vous obtiendrez alors après quelques minutes de calculs (plus la map est grande, plus c'est long) votre Heightmap.
  • File → Export → Active map. Exportez en BMP pour une meilleure qualité ou optez pour le jpeg pour un fichier plus léger.
Voila votre heigtmap est prête à être utilisé, il ne manque plus que la texture.



Pour la Texture :

  • Operations → Attributes map → Generate map, première étape, ne sauvez pas le résultat.
  • Operations → Terrain normals → Generate map, seconde étape, les reliefs, ne sauvez pas le résultat.
  • Operations → Light map → Generate map, comme son nom l'indique, réglez à votre guise les différents paramètres.
  • Operations → Texture map → Generate map, étape finale, sauvegardez le résultat de la même manière que précèdemment.




Voila, vous avez créé vos 2 textures, passons maintenant au codage.

Note : Le code est en C#.

Il faut tout d'abord charger TV3D et lancer les modules suivants :
TVEngine
TVTextureFactory
TVScene
TVLandscape
TVInputEngine
2 Options s'offrent à vous :
Soit pour vous faciliter la tâche vous pouvez partir de l'exemple A07 qui instancie ces modules et charge déjà un terrain. Le code est très bien documenté, je vous invite donc à en prendre connaissance si vous n'avez pas les connaissances requises pour lancer ces modules. (je me suis embêté au départ à tout faire à la main quand j'ai découvert cet exemple.)
Soit vous partez de 0.


A partir de ce code nous n'avons plus qu'à modifier quelques lignes de codes afin d'adapter nos textures et le tour est joué.

Il suffit de se rendre à la ligne 193 et de modifier par ceci :


Land.GenerateHugeTerrain("location de votre Heightmap", CONST_TV_LANDSCAPE_PRECISION.TV_PRECISION_BEST, 8, 8, 0, 0, true);
Land.ExpandTexture(Globals.GetTex("LandTexture"), 0, 0, 8, 8, false);


TextureFactory.LoadTexture("Resources\\cmap.bmp", "LandTexture",2048,2048,CONST_TV_COLORKEY.TV_COLORKEY_NO,true,true );


Land.SetTexture (Globals.GetTex("LandTexture"),-1);

Explication de ces modifications (si elle ne vous sont pas transparentes) :

Land.GenerateHugeTerrain("location de votre Heightmap", CONST_TV_LANDSCAPE_PRECISION.TV_PRECISION_BEST, 8, 8, 0, 0, true);
Ici, on créé le terrain à partir de votre Heightmap, et on précise que l'on veux la meilleure qualité. (si vous rencontrez des problèmes de performances remplacez BEST par AVERAGE.

Land.ExpandTexture(Globals.GetTex("LandTexture"), 0, 0, 8, 8, false);
Là on précise au moteur que la texture doit prendre tout le terrain (On modifie la taille).

TextureFactory.LoadTexture("Resources\\cmap.bmp", "LandTexture",2048,2048,CONST_TV_COLORKEY.TV_COLORKEY_NO,true,true );


Land.SetTexture (Globals.GetTex("LandTexture"),-1);
Et enfin on charge et on applique la texture dont on à précèdemment définit la taille.


Voila, votre terrain est prêt à être parcouru.

Prochainement la création d'une entité représentant le joueur sur ce même monde.

Affichage d'un terrain dans TV3D

Voila, après une dure soirée de galère, j'ai réussi à obtenir un résultat convenable et non buggé.

Une image vaut bien un grand discours :
(Cliquez sur l'image pour zoomer)

Bon la technique est plutôt simple une fois les bases de TV3D acquises.
Le terrain est composé d'une Heightmap, et d'une texture. Le travail des ombrages est directement fait sur la texture par un logiciel tiers.



La fatigue prenant le dessus (il est 3heures), je posterais la méthode complète et détaillée Dimanche dans la journée.

samedi 3 mars 2007

Peu d'intêret

Je me doute que ce Devlog n'a que peu d'intêret, sachant qu'il n'y a aucun travail graphique, ni aucune application pour le moment, ainsi, je vais continuer le dev. de ce projet à l'ombre, en parallèle à un projet qui me tient à coeur (basé sur cette technologie) : Avalon.

Je vais commencer le dévellopement des bases du jeu que je dévoilerai au fur et à mesure de l'avancement.
Désolé si l'explication du moteur réseau intéressait quelqu'un, dans ce cas qu'il se manifeste. (mais j'en doute)

A venir, l'affichage d'un monde sous TV3D.