JeuWeb - Crée ton jeu par navigateur
Système de combat - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Système de combat (/showthread.php?tid=4987)



Système de combat - manip - 13-07-2010

Bonjour à tous

Je suis actuellement entrain de développer un jeu par navigateur. J'en suis a coder des actions effectuées par des armées en mouvement à un certain moment : quand elles arrivent sur le terrain cible.

Mon gros problème est de coder un système de combat équilibré et réfléchis.

Mise en situation
Les soldats et les défenses ont chacun une valeur d'attaque.
Les soldats et les défenses ont chacun une valeur de défense (bâtiments) ou d'armure (hommes).
Les soldats et les défenses ont chacun une valeur de structure ou d'unité.
Une armée arrive sur un terrain à l'heure H.
Chaque valeur est différence en fonction de l'unité (son coût, son importance, son rôle...)
La défense absorbe l'attaque.
L'attaque est toujours supérieure à la défense.
Un combat dure 5 tours

A l'heure H je récupère les unités de l'attaquant et les unités du défenseur + les défenses.

Maintenant voici mes problèmes
Comment stocker les unites ?
* Un array pour chaque camp ?
* Une variable pour chaque type d'unité ?
Comment déterminée les unités tuées ?
* Je pensais a faire attaque = attaque - def, ensuite regarde si attaque > structure si oui, unité tuée.....
Comment les soustraires au unité restante ?
Quand est ce que le combat est fini ?
* Je pensais finir un combat dés qu'une armée a perdu tous ses soldats ou alors si après 5 tours il reste des hommes débouts, c'est un match null.
Et l'équilibre du combat la dédans ?

Voilà je pense avoir +/- tout expliqué pour que vous compreniez mon problème...
Merci d'avance pour vos éclaircissements.
Bonne aprem Smile


RE: Système de combat - Foxglove - 13-07-2010

En lisant ton message, je vois deux problèmes différents qui sont mélangés :
- les règles du jeu et l'équilibrage associé,
- des problèmes techniques de structures de données.

Les problèmes que tu as concernant les règles dépendent de ce que tu veux faire du jeu. L'équilibrage sera toujours difficile. Les problèmes techniques, par contre, devraient être décorellés de tout ça. Tu ne devrais pas commencer à programmer sans avoir une idée basique de la manière dont un combat marche.

Concernant les règles du jeu :
(1) Comment déterminée les unités tuées ? attaque = attaque - def, ensuite regarde si attaque > structure si oui, unité tuée.....
(2) Quand est ce que le combat est fini ?

Concernant les problèmes techniques :
(3) Comment les soustraires au unité restante ?
(4) Comment stocker les unites ?
(5) Un array pour chaque camp ?
(6) Une variable pour chaque type d'unité ?

Voici quelques idées.

(1) La règle proposée (que je comprends comme "points de vie = points de vie restants - attaque + défense" (si défense < attaque)) est standard. Il faudrait rajouter un peu d'aléatoire, ça serait plus sympathique (et éviterait des combats ennuyeux). Par contre, j'ai l'impression que tu as mélangé attaque et points de vie, et c'est assez dangereux.

(2) Quand il n'y a plus d'unités ? Mais bon, ça dépend de tes règles ça.

(3) Il te faut un "nombre d'éléments" pour chaque unité. Si tu as une unité "sniper", il te faut au moins l'attaque (par sniper), la défense (par sniper), la vie (par sniper) et le nombre (de snipers). Ca pourrait avoir un impact sur tes règles, exemple :
3 snipers (AT=5, DEF=2, VIE=4) attaquent 5 snipers (AT=5, DEF=2, VIE=4)
attaque : 5*3=15
Le premier sniper défenseur protège de 2 (de déf) + 4 (de vie). Il meurt, et il reste 9 points d'attaque.
Le deuxième sniper défenseur protège de 2 (de déf) + 4 (de vie). Il meurt, et il reste 3 points d'attaque.
Le troisième sniper défenseur protège de 2 (de déf) + 1 (de vie). Il survit (et éventuellement perd des points de vie, que tu peux répercuter aussi sur son attaque et sa défense, ou remettre au max ?)
C'est juste une idée.

(4) Pour stocker les unités, tu as pleins de moyens, ça dépend de ce en quoi tu programmes. Tu peux utiliser une BDD par exemple.

(5) Pourquoi pas un tableau par camp, ou autre chose. Ton problème n'est pas assez détaillé pour qu'on te donne une réponse définitive sur ce point. Bon, mais dans un premier temps, un tableau c'est pas si mal (ou encore la BDD ?).

(6) Plutôt qu'une variable par unité, je dirais plutôt un objet par unité, ou une ligne de ta BDD par unité.

Hésite pas à préciser tes problèmes en tout cas.


RE: Système de combat - manip - 14-07-2010

On va mettre l'équilibre du jeu de côté car je pense que c'est n'est pas l'objet du débat...

Pour éclaircir les points 4,5 et 6, j'ai une table qui contient tous les déplacements, avec le départ, l'arrivée, les temps, la mission et les unites qui sont dans le mouvement. Lorsque le temps d'arrivé est égale ou supérieur au temps actuel, je lance via un script PHP l'action en fonction de la mission.

Donc je récuperer les données du mouvement de la bdd ainsi que celle de l'adversaire (ses soldats & défenses).... Donc tout ça sort de la bdd pour arriver dans mon script PHP... Et c'est la que je cale un peu car je ne sais pas trop comment arranger tout ça pour que ça fonctionne de manière simple et efficace.


RE: Système de combat - wildd - 15-07-2010

>> manière simple et efficace

faire une simulation avec chaque unité séparée c'est sympa quand t'as que quelque unité, batiment; ça devient vite assez lourd pour un script PHP si tu veux que ça reste fluide (pas d'engorgement systématique aux heure de pointes - imagine des armée avec 1 mio d'unités qui se fritent en 1 vs. 1 + X batiments, sur je ne sais combien de round.)

le plus simple et efficace se sont des solutions agrégées. Et là c'est un peu à toi de trouver *ta* formule qui rendra ton jeu différent/intéressant

- éviter d'avoir une unité/batiment ultime; mais au contraire faire que chaque combinaison d'unité ait ses avantages, inconvénients : exemple un cavalier contre un archer ça risque d'être très avantageux; mais pas face à un piquier ; et inversément l'archer sera très efficace face au piquier -- ensuite tu te demande comment tu vas gérer ces facteurs (par exemple utiliser différents types d'att/déf qui justifierons ces variations importante selon le type d'unités qui se combattent)

- ou au contraire faire un système très simple avec "à chaque niveau/grade ou que sais-je comme contrainte de jeu" une nouvelle unité ultime qui devient accessible).

A toi aussi de voir quel facteurs tu vas intégré dans tes formules.
- bonus/malus à lattaquant ou au défenseur (on peut imaginer l'avantage de la surprise pour l'attaquant; tout aussi bien qu'un malus -> parce qu'à du faire le déplacement => donc les troupe sont fatiguée d'une longue marche de plusieurs jours).
- combat qui se déroule en un seul phase, ou plusieurs phases/rounds.
- facteur aléatoire (rand()&cie) ou que des facteurs déterminés.
- ...




les règles que tu utiliseras ensuite, détermineront comment tu vas traiter tes données et les stocker
(normalement c'est pas le contraire, tu n'es pas sensé déjà sortir tes données puis là te poser la question...heu comment je calcul mon combat ?!? c'est cool d'avoir donner une attaque, une def et une résistance à tes unités... mais si tu l'as fait au petit bonheur la chance; ça sert à rien).

si tu n'as pas l'intention de faire dans la simulation (traiter les pv courants propre à chaque unité; etc...) tu ne traite alors les données par lot (une seule ligne en bdd, avec type unité, nb unités, etc... à la limite un état de santé "moyen"/pour la troupe ou pas, ça aussi c'est quelque chose que tes règles te dicteront).

le plus simple du simple (chaque unité n'est caractérisé que par 2 facteurs; une att et une déf - accessoirement un coût d'achat - les unités sont en fait purement esthétiques, elles servent juste à furnir des variation des coûts ratio:att/def qui vienne s'ajouter à l'armée):
- une seule armée/joueur
- un seul round.
- pas de hasard: Somme att attaquant vs. Somme def defenseur => donne le vainqueur
- et tu utilise ensuite un ratio style (Somme att attaquant - Somme def défenseur)/Somme att attaquant pr avoir le % de survivant de l'attaquant (le déf lui y sont tous mort, on fait pas de prisonnier; oui c'est très basique comme règle Tongue)

tu as tes règle et les caractéristique que tu dois stocker => reste plus qu'à créer ta bdd et tes scripts de combats en conséquence.

à toi d'imaginer te règles si tu veux faire moins simple Wink


RE: Système de combat - manip - 19-07-2010

Je pense commencer par un script basique et simple que j'essayerais d'améliorer plus tard....

Donc pour le moment j'ai :
points de structure/points d'unités = vies des défenses/vies des soldats
attaque et armure sur chaque soldats/défenses (attaque > armure)
l'armure diminue l'attaque

Exemple :
1 soldat avec ATK5 DEF2 STRUCTURE 2
1 officier avec ATK6 DEF2 STRUCTURE 3

Si le soldat tape l'officier, l'officier reduit de 2points l'attaque du soldat, qui donc passe a 3 mais l'attaque étant égale à la structure de l'officier il est mort.

J'ai pris tous les unités de l'attaquant et du défenses qui sont dans un array. Je fais le calcule des attaques, défenses et structure mais j'éprouve des difficultées à "tuer" les soldats. En effet quand l'attaque est supérieur à la structure, le soldat est mort. Mais comment savoir quel soldat retirer de mon tableau ?


RE: Système de combat - christouphe - 20-07-2010

Pour tuer les soldat d'un array/d'une structure, j'utilise une méthode "repartiDegats()" qui est appelée par l'objet 'armee' sur les divisions de mon armée (chaque division est composée d'un seul type de combattant).

Pour faire simple, dans la méthode appelante (armée), je parcours mon armée (array) composée de division et je leur donne les dégâts (intégraux ou restant d'une répartition précédente).
Code PHP :
<?php 
/**
* $degats -> les dégâts à répartir venant d'une autre méthode (publique celle-là)
* $adversaire -> l'armée sur laquelle taper ;-)
* &$rapport -> le pointeur référence du rapport
*/
private function repartiDegats($degats,$adversaire,&$rapport) {
$oArmee = $adversaire -> getArmee(); // Composée de divisions
//...du code inutile pour l'exemple (des tests)
foreach ($oArmee AS $oDivision) {
if (
$degats > 0) {
$degats = $oDivision -> repartiDegats($degats);
}
}
//...
}


Et dans la division, même topo avec les unités de cette dernière.

Code PHP :
<?php 
/**
* _listeUnites -> la composition de la division avec des objets Unites
* _unitesMortes -> cqfd pour debug et statistiques de fin de combat
*
*/
public function repartiDegats($degats) {
if (!empty(
$this -> _listeUnites)) {
foreach (
$this -> _listeUnites AS $oUnite) {
if (
$degats >= $oUnite -> getDefense()) {
$degats -= $oUnite -> getDefense(); //dégâts restant à répartir
$oUnite -> setDefense(0); //Plus d'armure pour l'unité
if ($degats >=$oUnite -> getPdv()) {
$this -> _unitesMortes += 1;

//on retranche la vie de l'unité des dégâts
$_degats -= $oUnite -> getPdv();

//Suppression de l'unité détruite
if (sizeof($this -> _listeUnites) == 1) {
unset(
$this -> _listeUnites[0]);
} else {
unset(
$this -> _listeUnites[key($this -> _listeUnites)]);
}

} else {
$oUnite -> setPdv(($oUnite -> getPdv() - $degats));
$degats = 0;
}
} else {
$oUnite -> setDefense(($oUnite -> getDefense() - $degats));
$degats = 0;
break;
//pas besoin de parcourir le reste de la liste
}
}
}
return
$degats;
}

Bon attention aux optimisations possibles. J'ai fait un test avec 2 armées équivalentes de 100 000 ut chacune avec un ordre de bataille/défense particulier, et j'ai de "bons" résultats.

Enfin, juste pour te donner un exemple d'utilisation d'objets et surtout un exemple de répartition de dégâts Wink

++