JeuWeb - Crée ton jeu par navigateur
[PHP] Programmation événementielle - Scripter les actions - 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 : [PHP] Programmation événementielle - Scripter les actions (/showthread.php?tid=127)



[PHP] Programmation événementielle - Scripter les actions - Sephi-Chan - 11-05-2008

Salut à tous,

Depuis quelques temps, je travaille sur un système permettant de scripter des tas de choses pour Seelies , du système de combats aux réactions des créatures, en passant par la gestion des ressources ou même des constructions.

Je commence donc à développer le concept pour le système de combat. L'idée est de modéliser une capacité par un objet JSON, avec différents paramètres et événements.

Voici par exemple la façon dont est codé la capacité Attack : Pastebin.

Le but est donc de créer une fonction PHP du genre resolve($action, $settings) qui prend donc le nom de l'action et les paramètres sous forme de tableau :

Code PHP :
<?php 
$charOne
->resolve('Attack', array(
"castingUnit" => "Sephi-Chan",
"targetedUnit" => "Dryops"
)
);

Le système gérerai la récursivité (sur l'évenement onCounter, le personnage qui a contré lance à son tour une attaque).

Je finirai mon post de retour chez moi. J'attends vos suggestions sur l'idée et éventuellement des pistes de réalisations.


Sephi-Chan


RE: Scripter les actions - naholyr - 11-05-2008

Ton "resolve" fait furieusement penser à un "notify" qu'on retrouve dans l'orienté évènement Wink

Tu dois certainement avoir des objets qui "écoutent" en attente de l'action "Attack", puis renvoient l'évènement à d'autres objets, etc... On est vraiment dans du Event, et si tu regardes dE ce coté tu trouveras beaucoup de matériau Wink


RE: Scripter les actions - Sephi-Chan - 12-05-2008

Je ne sais pas vraiment de quoi tu parles. Les rares fois où j'ai concrètement entendu parler de programmation événementielle, c'est au sujet de Visual Basic, que j'ai commencé à pratiquer à l'école récemment.

Pourrais-tu m'en dire un peu plus, s'il te plaît ? Où bien me donner quelques pistes supplémentaires (des recherches Google sur l'orienté événement ou sur l'événementiel n'ont pas été très fructueuses), que je cherche de mon côté.

L'idée est d'interpréter ce fichier pour remplacer les substituts par leur valeur (première difficulté) puis ensuite de provoquer les actions en conséquences (seconde difficulté) et de gérer la récursivité (troisième difficulté).


Sephi-Chan, qui a dû booter sur sa partition Vista pour faire du VB.NET…


RE: Scripter les actions - naholyr - 12-05-2008

En fait c'est assez simple :
- 1 objet "écoute" un évènement donné
- 1 autre objet "provoque" l'évènement, et à ce moment tous les objets qui sont en train d'écouter l'évènement (ou juste la cible de l'évènement si c'est un évènement ciblé, comme un click sur un bouton) le reçoivent.

L'idée c'est d'avoir un registre global qui contient l'information "qui écoute quoi". Chacun des objets "écouteur" a associé un évènement à une fonction de callback.
Ensuite on lance l'évènement :
- soit de manière globale, et là tous les objets enregistrés comme écouteurs pour cet évènements sont notifiés
- soit de manière ciblée, et seul l'objet en question est notifié
Un objet écouteur qui reçoit une notification d'évènement agit en conséquence, en exécutant sa fonction de callback.

Dans ton cas ça donnerait quelque chose comme ça :
Code PHP :
<?php 
class Seelie extends EventListener
{

public function
__construct()
{
// on écoute l'évènement "attack" et "attack.counter" (contre-attaque)
$this->registerEvent('attack', array($this, 'onAttack'));
$this->registerEvent('attack.counter', array($this, 'onAttack'));
// on écoute l'évènement "attacked" et "attacked.counter" (contre-attaque)
$this->registerEvent('attacked', array($this, 'onAttacked'));
$this->registerEvent('attacked.counter', array($this, 'onAttacked'));
}

public function
onAttack(Event $event)
{
$jetAttaque = mt_rand(1,100); // mon jet pour toucher
$jetDegats = mt_randt(1,30); // mon jet de dégats, en fonction de mon arme
// On construit l'évènement
$settings = array('attacker' => $this, 'attack' => array('touch' => $jetAttaque, 'damages' => $jetDegats));
$event_name = $event->getName() == 'attack.counter' ? 'attacked.counter' : 'attacked';
// On lance l'évènement "attacked" ou "attacked.counter" sur la cible de l'attaque
$event = Events::notify($event->get('target'), $event_name, $settings);
}

public function
onAttacked(Event $event)
{
$jetEsquive = mt_rand(1, 100); // mon esquive
$jetArmure = mt_rand(1, 10); // ma réduction de dégats
if ($event->get('attack.touch') > $jetEsquive) {
// Argh ! je suis touché !
$degats = max(0, $event->get('attack.damages') - $jetArmure);
// perdre de la vie, etc... etc...
}
// Je contre-attaque, seulement si j'étais la cible d'une attaque normale
if ($event->getName() == 'attacked') {
// Je lance une contre-attaque, en me notifiant de l'évènement "attack.counter" avec pour cible mon attaquant
Events::notify($this, 'attack.counter', array('target' => $event->get('attacker')));
}
}

}

Voir le code du gestionnaire d'évènement

C'est un peu "brut de décoffrage" mais le concept est là, et une implémentation simpliste (enfin pas si simpliste que ça, mais il y a pas mal de chose qui ne sont pas gérées comme les règles de propagation d'évènements).


RE: Scripter les actions - Sephi-Chan - 12-05-2008

J'essaye de déchiffrer tout ça et je dois reconnaître que j'ai bien du mal ! Je n'arrête pas de faire des sauts dans le code.

L'une des choses qui me perturbe, c'est le passage en argument d'objets. Le systèmes que tu proposes (c'est toi qui l'a mis au point ?) y recourt beaucoup. Il faut que je m'y fasse.

En tout cas, c'est très enrichissant. Merci beaucoup de partager ça, Naholyr. Smile


Sephi-Chan, qui continue son exploration du code source…


RE: Scripter les actions - naholyr - 12-05-2008

Le set de classes que je t'ai mis en pastebin j'en suis l'auteur oui, mais je n'ai pas inventé la programmation évènementielle :lol:

Le concept de base est celui que je t'ai énoncé : un registre qui enregistre les déclarations d'écoute et qui se charge de distribuer les évènements, et des écouteurs (qui s'enregistrent auprès du registre) qui agissent à la notification d'évènement.
Là où les implémentations diffèrent, c'est au niveau de la façon dont on va traiter les infos supplémentaires, ce que va véhiculer l'évènement, la façon dont l'évènement se propage ou non, la façon dont on gère les valeurs de retour, etc... Là il y a mille façons de faire Wink

Deux petits liens pour aller plus loin :
- un autre set de classes, plus complet : http://www.phpclasses.org/browse/package/2783.html
- le chapitre "events" de Symfony : http://www.symfony-project.org/book/1_1/17-Extending-Symfony#Events


RE: [PHP] Programmation événementielle - Scripter les actions - Hakushi - 18-12-2008

Si tu veux un bon exemple de langage evenementiel, je te conseille de jeter un coup d'oeil a la facon dont ActionScript 3 marche, ca me paraitrait etre une tres bonne base pour construire quelque chose d'evenementiel en php.


RE: [PHP] Programmation événementielle - Scripter les actions - Maxime - 20-12-2008

Si je ne me trompe pas c'est le principe du design Pattern Observer ce que naholyr te dit.
Donc au pire si tu ne comprends pas son explication regarde de ce côté là.

Ca me fait penser que ça peut toujours servir ça, faut que je vois ça.


RE: [PHP] Programmation événementielle - Scripter les actions - Sephi-Chan - 20-12-2008

La discussion n'est plus vraiment d'actualité… Wink


Sephi-Chan