Novembre 2023 - When the lead strikes the steel - Jeu RTS
Dans la nostalgie et dans la volonté de continuer ma passion, je décide de reprendre les idées de mon premier projet de Jeu datant de 2016.
Dernière images datant d’octobre 2024 - 16/10/2024 -
OLD links Vidéos illustratives Netcode -
Vidéos illustratives Units and solo
Objectifs :
Jeu en Real Time strategy macroscopique.
Vue orthographique et design retro (inspirations Cossacks:Art of War, Age of Empire 2 et empire earth).
Ne doit pas depasser en taille l’espace de mon disque dur (libre) : 1 Go.
Créer et faire évoluer son camp à travers l’une des époques les plus révolutionnaires au niveau technique et culturel : 16ème à la Fin du 17 ème - Epoque Pikes & Shottes - L’arrivée des européens en Amérique etc.
Utilisation de bibliothèques gratuites et libre de droit.
Traçabilité des exigences et arborescence : réaliser l’exigence “client” jusqu’à la ligne de code.
Multijoueur avec serveur client-side + ressources graphiques côté client + Pre-rendering.
Mode de jeu “scalable” en fonction du nombre de joueur.
Open-source et première version qui sera sur github.
Je souhaite suivre de bout en bout une rigueur de réalisation, que j’ai connu dans le milieu normatif : traçabilité, standardisation et conformité. Organigramme réalisé sous Visio :
Le principe du cycle en V sera mis en place. Cycle en V réalisé sous Visio :
Server client-side. Schéma à revoir, simplement illustratif :
Exigence du cahier de spécification logiciel concernant les interfaces/menus :
Exigence du cahier de spécification logiciel concernant l’architecture de programmation, on définira ici le back-end comme ce qui ne se voit pas et le front-end comme ce qui se voit :
Civilisation Astèque, mindmap
Civilisation Mongole, mindmap
Civilisation Indienne, mindmap
Civilisation Chinoise, mindmap
Civilisation Française, mindmap
Civilisation Espagnole, mindmap
Civilisation Ottomane, mindmap
Civilisation Japonaise, mindmap
Civilisation Anglaise, mindmap
Code pour l’isométrie
Il est possible de choisir, selon la civilisation du joueur ou de la joueuse, des batiments différents. Ils ont des tailles différentes. Ici “chinampas est de taille 2.
A partir d’une matrice 2D et de la position des cases du batiments (de leur position), on détermine si on a de l’eau (case rouge), un arbre (case blanche) ou de la terre (case verte)
Code pour le fog of war
On utilise la librairie : TasharenFogOfWar : https://github.com/insominx/TasharenFogOfWar
Code pour la triangulation de delaunay et la recherche du point le plus proche
On utilise la librairie : Triangle.NET : https://github.com/wo80/Triangle.NET/
Triangulation : Unity n’a pas de support intégré pour la triangulation de Delaunay. Cependant, on peut utiliser des bibliothèques tierces comme Triangle.NET qui peuvent gérer cela. La triangulation de Delaunay est un algorithme qui peut être utilisé pour générer un maillage à partir d’une liste de points Vector3. Il génère des triangles de telle sorte qu’aucun point ne se trouve à l’intérieur du cercle circonscrit d’un triangle.
Trouver les points les plus proches : Après la triangulation de Delaunay, on souhaitez trouver les points les plus proches dans le maillage généré. On utilise la librairie et une recherche linéaire avec un nombre de points limités.
Dessiner des lignes : Le composant LineRenderer de Unity peut être utilisé pour dessiner une ligne entre deux ou plusieurs points dans l’espace 3D. Une fois que l’on a les points les plus proches, on peut utiliser LineRenderer pour dessiner des lignes entre chaque point et son voisin le plus proche.
Résultat de triangulation des points en mouvement:
Résultat de triangulation des points statiques:
Code fonctionnel contenant seulement la triangulation :
using UnityEngine;
using TriangleNet.Meshing;
using TriangleNet.Geometry;
using TriangleNet.Meshing.Algorithm;
using TriangleNet.Meshing;
using TriangleNet.Smoothing;
using TriangleNet.IO;
using System.Collections.Generic;
public class triangulation_code : MonoBehaviour
{
// Unity objects.
List<Transform> All_unit = new List<Transform>();
// Triangle.NET vertices (class instance for better memory performance).
List<Vertex> vertices = new List<Vertex>();
// For better memory performance.
TrianglePool trianglePool = new TrianglePool();
ITriangulator triangulator = new Dwyer();
// To find nearest neighbours.
VertexCirculator vertexCirculator;
LineRenderer lineRenderer;
void Start()
{
// Create a LineRenderer to display on screen
lineRenderer = gameObject.GetComponent<LineRenderer>();
lineRenderer.widthMultiplier = 2f;
}
void Update()
{
if (All_unit == null || All_unit.Count == 0) return;
int count = All_unit.Count;
lineRenderer.positionCount = 0;
vertices.Clear();
if (vertices.Capacity < count)
{
vertices.EnsureCapacity(count);
}
// Copy the position
for (int i = 0; i < count; i++)
{
var pos = All_unit[i].position;
// IMPORTANT: set correct vertex id (corresponding to index in All_unit).
// This will automatically establish the mapping between Unity
// and Triangle.NET objects.
vertices.Add(new Vertex(pos.x, pos.z) { ID = i });
}
// Perform Delaunay triangulation on vertices
var mesh = (Mesh)triangulator.Triangulate(vertices, new Configuration(
() => RobustPredicates.Default,
() => trianglePool.Restart()));
vertexCirculator = new VertexCirculator(mesh);
// GET ALL THE Point from the triangulation in order to display it
var positions_upt = new List<Vector3>();
foreach (var edge in mesh.Edges)
{
positions_upt.Add(All_unit[edge.P0].position);
positions_upt.Add(All_unit[edge.P1].position);
}
lineRenderer.SetPositions(positions_upt.ToArray());
// Find all nearest neighbors
for (int i = 0; i < count; i++)
{
var obj = All_unit[i];
int closedId = FindClosest(vertices[i]);
if (closedId < 0)
{
// Something went wrong
}
else
{
var closest = All_unit[closedId];
}
}
}
int FindClosest(Vertex vertex)
{
if (vertexCirculator == null) return -1;
Vertex closest = null;
double closestDist = double.MaxValue;
foreach (var neighbor in vertexCirculator.EnumerateVertices(vertex))
{
var dx = (vertex.X - neighbor.X);
var dy = (vertex.Y - neighbor.Y);
var squareDist = dx * dx + dy * dy;
if (squareDist < closestDist)
{
closest = neighbor;
closestDist = squareDist;
}
}
return closest == null ? -2 : closest.ID;
}
}
Logiciels / Outils : Unity 3D, Blender, mermaid, jira, confluence.