JeuWeb - Crée ton jeu par navigateur
Ajouter des méthodes dynamiquement - 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 : Ajouter des méthodes dynamiquement (/showthread.php?tid=4789)

Pages : 1 2 3 4


RE: Ajouter des méthodes dynamiquement - QuentinC - 05-05-2010

En bonus pour la solution de Ter Rowan, tu peux utiliser la méthode magique __call...


RE: Ajouter des méthodes dynamiquement - Ter Rowan - 05-05-2010

oui je me suis dit ça en me levant ^^

les inconvénients que j'y vois sont

-maitriser l'ordre des arguments que t'envoies car il n'y a plus de 'target', 'how', ... qui sont pris si besoin par la stratégie concernée, enfin je ne sais pas le faire

- être sûr que le __call ne gère que des actions et pas autre chose (mais bon qu'à moitié, tout dépend de la gestion du __call)



sinon en anglais je suis pas sûr qu'on 'launch' une action

==> je conseille de remplacer par justDoIt($action, $params)


RE: Ajouter des méthodes dynamiquement - Roworll - 05-05-2010

Ça me semble une bonne alternative.
Je vais voir ce que je peux faire avec.


RE: Ajouter des méthodes dynamiquement - Zamentur - 05-05-2010

(04-05-2010, 11:03 AM)Roworll a écrit : Au final, je peux donc ajouter des méthodes (capacités spéciales) sur mes classes (unités) à la volée. Personnellement, je trouve que ce n'est pas très propre, notamment à cause de l'Eval dans la classe dynamique. Voila pourquoi je me tourne vers la communauté.

Ben moi j'aurais fait pareil que toi, enfin j'ai pas lu précisément mais je pense que c'est ce que je crois.
Par contre j'aurais pas fait de eval, car il y a une autre solution beaucoup plus classe pour appeler une méthode de classe...
http://us.php.net/manual/fr/function.call-user-func-array.php
cf exemple numéro 2


RE: Ajouter des méthodes dynamiquement - NicoMSEvent - 05-05-2010

et pourquoi pas autrement :

une unité utilise une arme (d'un certain type) soit vers une autre unité, soit vers un emplacement, soit l'utilise (sans paramètre, ex : dégoupiller une grenade, ou placer une mine -> sous entendu à l'endroit ou elle se trouve)

La méthode d'attaque ne fait plus partie de la personne, mais de l'arme (ou de tout autre objet)

Je ne sais pas si c'est une bonne idée, mais je pense que ça vaut la peine d'y réfléchir Smile

L'appel se ferait comme ça :
Code :
$troupe->Utilise($fusil,$troupe_ennemie);//tire sur l'ennemi
$troupe->Utilise($grenade); //dégoupille
$troupe->Utilise($grenade,$troupe_ennemie); //lance la grenade vers l'ennemi
...
classe Troupe{
  function Utilise(){
/*utiliser argc et arg_v pour reprendre les paramètres*/
switch($argc)
case 0:
arg_v[0]->EstUtilisé($this);
break;
case 1:
arg_v[0]->EstUtilisé($this,$arg_v[1]);
break;
case 2:
arg_v[0]->EstUtilisé($this,$arg_v[1],$arg_v[2]);
break;
  }

}



RE: Ajouter des méthodes dynamiquement - QuentinC - 05-05-2010

Citation :-maitriser l'ordre des arguments que t'envoies car il n'y a plus de 'target', 'how', ... qui sont pris si besoin par la stratégie concernée, enfin je ne sais pas le faire
C'est pas un problème, parce que quand tu lances une action tu sais quand même laquelle tu lances. Donc tu connais les paramètres.

Citation :- être sûr que le __call ne gère que des actions et pas autre chose (mais bon qu'à moitié, tout dépend de la gestion du __call)
__call permet une liberté absolue. Je trouve que c'est un avantage. ET puis ça permet éventuellement de stocker plusieurs actions dans la même stratégie. C'est pratique pour les capacités qui vont logiquement ensemble, par exemple avec une hache de nain on peut attaquer des ennemis mais aussi couper du bois.
Par exemple avec ça :

class Unit {
private $abilities = array();
//...
public function __call ($func, $args) {
foreach ($this->abilities as $a) {
if (method_exists($a, $func)) {
call_user_func_array(array($a,$func), $args);
break;
}}
throw new Exception("$func is unavailable");
}
}
ET si on a deux actions qui se recouvrent (i.e. deux méthodes du même nom dans deux stratégies différentes), il suffit de modifier l'ordre des objets dans le tableau pour sélectionner l'autre comportement, puisque l'algorythme naïf ci-dessus prend la première qu'il trouve. L'utilisateur pourrait donc en plus choisir ses stratégies préférées, p.ex. je peux attaquer avec la hache ou l'épée, je préfère l'épée donc je la mets en priorité / plus haut dans la liste.


RE: Ajouter des méthodes dynamiquement - NicoMSEvent - 06-05-2010

en effet, ta solution est plus sexy Wink

merci de l'avoir partagée Smile

ici un lien que j'ai trouvé tres instructif, qui permet de voir toute la puissance du __call
http://www.apprendre-php.com/tutoriels/tutoriel-48-methodes-magiques-call.html


RE: Ajouter des méthodes dynamiquement - Roworll - 06-05-2010

Que du bon dans tout ça.
Quand j'aurai un moment (surcharge IRL), j'essayerai de concrétiser tout ça.

Je reviens juste sur une petite chose
(05-05-2010, 01:19 PM)NicoMSEvent a écrit : et pourquoi pas autrement :

une unité utilise une arme (d'un certain type) soit vers une autre unité, soit vers un emplacement, soit l'utilise (sans paramètre, ex : dégoupiller une grenade, ou placer une mine -> sous entendu à l'endroit ou elle se trouve)

La méthode d'attaque ne fait plus partie de la personne, mais de l'arme (ou de tout autre objet)

Je ne sais pas si c'est une bonne idée, mais je pense que ça vaut la peine d'y réfléchir Smile

Ces capacités spéciales ne sont pas attachées à une arme quelconque mais bien et bien à l'unité.
Camouflage, Marche forcée, Régénération sont autant d'actions complètement indépendantes des armes.

Je trouve cependant un peu lourd et dommage de devoir de passer par des classes externes pour ajouter les méthodes à l'Unité.
Je dois ajouter la classe "Camouflage" à l'unité "Eclaireur" pour qu'elle puisse utiliser la méthode Se_Camoufler().
Pas super intuitif.

De plus, pour rester dans l'exemple, ma méthode un peu particulière que j'utilisais dans mon premier exemple permet d'utiliser directement $this pour référencer l'objet "Eclaireur" à l'intérieur de la classe "Camouflage".
Dans la méthode Se_Camoufler(), je peux mettre echo $this->get_Name().' se camoufle';

Avec les méthodes proposées ici, je doute que cela soit possible.
Ca va m'obliger à passer la référence de l'objet "Eclaireur" à l'objet "Camouflage" et donc transformer l'appel en echo $this->Unite->get_Name().' se camoufle';

Vous voyez une solution pour pouvoir continuer à utiliser $this ?


RE: Ajouter des méthodes dynamiquement - Ter Rowan - 06-05-2010

à mon sens, si tu utilises les stratégies,ce ne sont pas elles qui font l'echo "se camoufle"

Ca devrait plutôt être le résultat de la stratégie qui, envoyé à ton unité, permet à l'unité de dire si elle se camoufle ou non


le principe étant, de ce que j'ai compris, que la stratégie renvoie un résultat (réussi/échec, niveau, etc...) et que c'est le "possesseur" de la stratégie qui réagit à ce résultat.

Exemple
les gobelins sont peureux, donc ils essaient de se camoufler (stratégie camouflage), le résultat est un échec, stratégie suivante la fuite

echo $this(gobelins)->getName()." essaient de se camoufler mais n'y arrivant pas fuient";

à l'inverse les vickings montent une embuscades (on est dans les poncifs là ^^) ils essaient donc de se camoufler (la même stratégie camouflage), le résultat est un échec, frustré ils s'énervent, stratégie suivante berserk

echo $this(vickings)->getName()." enssaient de se camoufler mais n'y arrivant pas rentrent dans une colère noire ";

Dans ma vision ça ne peut donc pas être la strategie qui définit le "écho" (sans parler de mvc que je ne maitrise pas totalement)


RE: Ajouter des méthodes dynamiquement - Roworll - 06-05-2010

Evidemment, je ne fais aucun Echo dans mes classes métier. Je renvoie juste une information. C'était ici un exemple. Ca me permet en autre de tracer en mode débug ce qui se passe exactement, les appels effectués, etc.

Les capacité spéciales / stratégies sont déclenchées par le joueur. On est ici dans le cadre d'un wargame tactique au tour par tour.
Un camouflage réussira toujours par exemple.
Une unité détectant les ennemis camouflés les repérera à coup sur.
Une charge donnera des bonus substantiels pré définis.

La seule partie aléatoire se situe au niveau de la résolution des combats (et encore, même ce point a été soumis à rude discussion).