12-05-2008, 01:55 PM
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 :
- 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).