PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 14-07-2012 21:49:57

bly
Membre
Inscription : 21-08-2010
Messages : 15

probleme avec des classes

Bonjours , je m'entraine en ce moment au php , j'ai donc voulu modifier un peu le cript du tp :mini jeu de combats pour ceux qui connaisse, j'ai penser a faire un systeme plus de vie avec notre vie qui diminue en fonction des degats pris , cela je l'ai fait sans probleme car j'ai modifier la valeur de degats en mettant 100 et j'ai mit -5 au lieu de +5 quand on doit recevoir des degats , j'ai voulu faire ensuite faire un systeme ou on regagnait de la vie quand on tuait un personnage , et la viens mon probleme par rapport a la fonction if , car j'arrive a rajouter de la vie au personnage qu'on attaque si sa vie passe en dessous de 50 par exemple mais j'arrive pas a rajouter de la vie a notre propre personnage quan on n'arrive a en tuer un autre .


<?php
    class Personnage
    {
        private $_degats,
                $_id,
                $_nom;
       
        const CEST_MOI = 1; // Constante renvoyée par la méthode `frapper` si on se frappe soit-même
        const PERSONNAGE_TUE = 2; // Constante renvoyée par la méthode `frapper` si on a tué le personnage en le frappant
        const PERSONNAGE_FRAPPE = 3; // Constante renvoyée par la méthode `frapper` si on a bien frappé le personnage
       
       
        public function __construct(array $donnees)
        {
            $this->hydrate($donnees);
        }
       
        public function frapper(Personnage $perso)
        {
            if ($perso->id() == $this->_id)
            {
                return self::CEST_MOI;
            }
           
            // On indique au personnage qu'il doit recevoir des dégâts
            // Puis on retourne la valeur renvoyée par la méthode : self::PERSONNAGE_TUE ou self::PERSONNAGE_FRAPPE
            return $perso->recevoirDegats();
        }
       
        public function hydrate(array $donnees)
        {
            foreach ($donnees as $key => $value)
            {
                $method = 'set'.ucfirst($key);
               
                if (method_exists($this, $method))
                {
                    $this->$method($value);
                }
            }
        }
               
        public function nomValide()
        {
            return !empty($this->_nom);
        }
       
        public function recevoirDegats()
        {
            $this->_degats += -5;
           
           
            if ($this->_degats <= 1)
            {
               $perso->_degats += +10;
           
                         
                        }
                       
                       
                       
                       
                       
                       
           
            // Sinon, on se contente de dire que le personnage a bien été frappé
            return self::PERSONNAGE_FRAPPE;
        }
       
           
     
       

        public function degats()
        {
            return $this->_degats;
        }
       
        public function id()
        {
            return $this->_id;
        }
       
        public function nom()
        {
            return $this->_nom;
        }
       
        public function setDegats($degats)
        {
            $degats = (int) $degats;
           
            if ($degats >= 0 && $degats <= 100)
            {
                $this->_degats = $degats;
            }
       
               
               
                }
               
               
public function setId($id)
        {
            $id = (int) $id;
           
            if ($id > 0)
            {
                $this->_id = $id;
            }
        }
       
               
               
               
               
        public function setNom($nom)
        {
            if (is_string($nom))
            {
                $this->_nom = $nom;
            }
        }
    }

?>

<?php
public function recevoirDegats()
        {
            $this->_degats += -5;
           
           
            if ($this->_degats <= 1)
            {
               $perso->_degats += +10;
           
                         
                        }
?>

je sais pas quoi mettre a la place de $perso pour que sa soit notre degat qui augmente
par contre j'ai pas encore remplacer degats mais a la place c'est plutot la vie.

MK a écrit :

Ce code s'est colorisé comme par magie, MK y est 'cor'assez pour quelque chose

Dernière modification par bly (14-07-2012 21:50:50)

Hors ligne

#2 15-07-2012 02:02:03

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

Bonjour,

il y a un problème d'écriture de vos incrémentations de variables

quand vous écrivez $perso->_degats += +10; il faut écrire $perso->_degats +=10;
quand vous écrivez $this->_degats += -5; il faut écrire $this->_degats -= 5;

corrigez déjà cela, et dites comment vont les choses. La construction de votre classe (la logique de son fonctionnement) est assez bizarre...

++


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#3 15-07-2012 12:00:47

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

merci , j'ai bien modifié donc pour sa il y a pas de probleme sinon pour mon probleme j'ai penser a faire sa mais sa fonctionne pas


<?php
    class Personnage
    {
        private $_degats,
                $_id,
                $_nom;
       
               
       
        const CEST_MOI = 1; // Constante renvoyée par la méthode `frapper` si on se frappe soit-même
        const PERSONNAGE_TUE = 2; // Constante renvoyée par la méthode `frapper` si on a tué le personnage en le frappant
        const PERSONNAGE_FRAPPE = 3; // Constante renvoyée par la méthode `frapper` si on a bien frappé le personnage
       
       
        public function __construct(array $donnees)
        {
            $this->hydrate($donnees);
        }
       
        public function frapper(Personnage $perso)
        {
            if ($perso->id() == $this->_id)
            {
                return self::CEST_MOI;
            }
           
      if ($this->_degats <= 1)
            {
               
          return $perso->gagnerDegats();
       
      }
     
           
            return $perso->recevoirDegats();
     
        }
       
        public function hydrate(array $donnees)
        {
            foreach ($donnees as $key => $value)
            {
                $method = 'set'.ucfirst($key);
               
                if (method_exists($this, $method))
                {
                    $this->$method($value);
                }
            }
        }
               
       public function recevoirDegats()
        {
            $this->_degats -= 5;
           
           
       
            return self::PERSONNAGE_FRAPPE;
        }
       
     
   
    public function gagnerDegats()
   
    {
            $this->_degats += 5;
      }
?>
Colorisé par MK a écrit :

Ce code s'est colorisé comme par magie, MK y est 'cor'assez pour quelque chose

a la place de degats c'est point de ve mais j'ai pas encore modifié de perdre de m'y perdre , sinon c'est vrai que gagner degats sa fait bizarre

Dernière modification par bly (15-07-2012 12:01:33)

Hors ligne

#4 16-07-2012 00:01:14

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

Bonsoir,

Pourrait-on connaître la logique de votre gestion des combats? (Décomposition d'un round, possibilité de chaque adversaire, combien peut-il y en avoir à chaque combat, etc...)

Dernière modification par Jc (16-07-2012 00:01:42)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#5 16-07-2012 12:12:15

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

Je voulais un jeu simple, donc notre perso commence avec 100 de vie , donc 100 de degats vue que j'ai pas modifié , quand on clique sur un autre joueur on l'attaque et on lui enleve -5 de vie , si lorsque qu'on attaque le joueur et que sa vie passe en dessous de 1 il est tué et celui qui l'a tué recupere 5 point de vie .
J'avais eu l'idée de faire une limitation d'attaque mais sa je vais m'y attarder apres.

Hors ligne

#6 16-07-2012 14:10:45

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

si vous lui enlevez -5 points de vie cela reviens à lui en ajouter 5. Vous lui enlevez donc 5 points de vie. (Je comprends mieux maintenant votre problème d'écriture précédent).

Par contre une classe objet représente qu'un seul joueur sauf si votre classe représente une collection de classes, ce qui n'est pas le cas il me semble.
Il vous faut donc écrire une méthode d'attaque qui identifie l'id du joueur ciblé du style  function attaque($id){ } qui elle gère la récupération de la classe objet du joueur cible et qui appele la fonction hit() par exemple et qui lui enlève 5 points de vie et qui teste s'il n'est pas mort.

++

EDIT: Excusez moi pour mes imprécisions, j'ai pris des raccourcis que je ne devrais pas prendre sur ce site. Donc une classe objet joueur gère tout ce qui touche au joueur, et chaque joueur est représenté par une instance de cette classe.

Dernière modification par Jc (16-07-2012 15:00:19)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#7 16-07-2012 14:58:44

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

Sa c'est déjà fait pour sa il y a pas de problème si j'attaque un joueur il lui enleve bien -5 de vie là j'ai pas mit tout le code juste la partie qui me bloque car je pour recevoirDegats sa fonctionne mais c'est gagnerDegats qui ne fonctionne pas ou plutot gagnervie .

Hors ligne

#8 16-07-2012 15:06:45

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

Bonjour,

Il n'y a pas de problème avec votre fonction gagnerDegats(). La seule chose qu'il faut bien prendre en compte avec PHP c'est que c'est un language interprété et par conséquent toutes les informations qui ne sont pas persistées à la fin de l'éxécution d'une page sont perdues lorsque elle est éxecutée à nouveau. Ainsi si vous initialisez votre classe joueur (__construct()) avec 100 pv, à chaque nouvelle éxecution votre joueur aura 100pv, même si lors de l'éxécution précédente il n'en avait plus que 75 suite aux actions menées.

++


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#9 16-07-2012 15:37:23

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

oui mais j'ai enregistrer dans la base de donné la vie qui a pour depart 100 et ainsi les -5 sont enlever pour la vie de la base de donné donc il garde la valeur et ne revient pas a 100

Hors ligne

#10 16-07-2012 16:14:21

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

Le problème c'est que je ne vois pas le code d'enregistrement dans la base de données, ni le code de lecture ni de mise à jour de la base de données, donc permettez moi d'en douter.


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#11 16-07-2012 16:21:20

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

voila tout le code :

<?php
    class Personnage
    {
        private $_degats,
                $_id,
                $_nom;
       
               
       
        const CEST_MOI = 1; // Constante renvoyée par la méthode `frapper` si on se frappe soit-même
        const PERSONNAGE_TUE = 2; // Constante renvoyée par la méthode `frapper` si on a tué le personnage en le frappant
        const PERSONNAGE_FRAPPE = 3; // Constante renvoyée par la méthode `frapper` si on a bien frappé le personnage
       
       
        public function __construct(array $donnees)
        {
            $this->hydrate($donnees);
        }
       
        public function frapper(Personnage $perso)
        {
            if ($perso->id() == $this->_id)
            {
                return self::CEST_MOI;
            }
           
      if ($this->_degats <= 100)
            {
               
          return $perso->gagnerDegats();
       
      }
     
            // On indique au personnage qu'il doit recevoir des dégâts
            // Puis on retourne la valeur renvoyée par la méthode : self::PERSONNAGE_TUE ou self::PERSONNAGE_FRAPPE
            return $perso->recevoirDegats();
     
        }
       
        public function hydrate(array $donnees)
        {
            foreach ($donnees as $key => $value)
            {
                $method = 'set'.ucfirst($key);
               
                if (method_exists($this, $method))
                {
                    $this->$method($value);
                }
            }
        }
               
        public function nomValide()
        {
            return !empty($this->_nom);
        }
       
     public function motdepassevalid()
        {
            return !empty($this->_motdepasse);
        }
   
   
   
        public function recevoirDegats()
        {
            $this->_degats -= 5;
           
           
       
            return self::PERSONNAGE_FRAPPE;
        }
       
     
   
    public function gagnerDegats()
   
    {
            $this->_degats += 5;
      }
           
   
   
 
        public function degats()
        {
            return $this->_degats;
        }
       
        public function id()
        {
            return $this->_id;
        }
       
        public function nom()
        {
            return $this->_nom;
        }
       
    public function motdepasse()
        {
            return $this->_motdepasse;
        }
   
   
   
        public function setDegats($degats)
        {
            $degats = (int) $degats;
           
            if ($degats >= 0 && $degats <= 100)
            {
                $this->_degats = $degats;
            }
       
   
   
    }
   
   
   
       public function setId($id)
        {
            $id = (int) $id;
           
            if ($id > 0)
            {
                $this->_id = $id;
            }
        }
         public function setMotdepasse($motdepasse)
        {
            if (is_string($motdepasse))
            {
                $this->_motdepasse = $motdepasse;
            }
        }
   
   
   
   
        public function setNom($nom)
        {
            if (is_string($nom))
            {
                $this->_nom = $nom;
            }
        }
    }

?>

<?php
    class PersonnagesManager
    {
        private $_db; // Instance de PDO
       
        public function __construct($db)
        {
            $this->setDb($db);
        }
       
        public function add(Personnage $perso)
        {
            $q = $this->_db->prepare('INSERT INTO personnages SET nom = :nom');
            $q->bindValue(':nom', $perso->nom());
            $q->execute();
           
            $perso->hydrate(array(
                'id' => $this->db->lastInsertId(),
                'degats' => 100,
            ));
        }
       
        public function count()
        {
            return $this->_db->query('SELECT COUNT(*) FROM personnages')->fetchColumn();
        }
       
        public function delete(Personnage $perso)
        {
            $this->_db->exec('DELETE FROM personnages WHERE id = '.$perso->id());
        }
       
        public function exists($info)
        {
            if (is_int($info)) // On veut voir si tel personnage ayant pour id $info existe
            {
                return (bool) $this->_db->query('SELECT COUNT(*) FROM personnages WHERE id = '.$info)->fetchColumn();
            }
           
            // Sinon, c'est qu'on veut vérifier que le nom existe ou pas
           
            $q = $this->_db->prepare('SELECT COUNT(*) FROM personnages WHERE nom = :nom');
            $q->execute(array(':nom' => $info));
      $q = $this->_db->prepare('SELECT COUNT(*) FROM personnages WHERE motdepasse = :motdepasse');
            $q->execute(array(':motdepasse' => $info));
           
     
            return (bool) $q->fetchColumn();
        }
       
        public function get($info)
        {
            if (is_int($info))
            {
                $q = $this->_db->query('SELECT id, nom, degats, motdepasse FROM personnages WHERE id = '.$info);
                $donnees = $q->fetch(PDO::FETCH_ASSOC);
               
                return new Personnage($donnees);
            }
            else
            {
                $q = $this->_db->prepare('SELECT id, nom, degats FROM personnages WHERE nom = :nom');
                $q->execute(array(':nom' => $info));
             $q = $this->_db->prepare('SELECT id, nom, degats FROM personnages WHERE motdepasse = :motdepasse');
                $q->execute(array(':motdepasse' => $info));
                return new Personnage($q->fetch(PDO::FETCH_ASSOC));
            }
        }
       
        public function getList($nom)
        {
            $persos = array();
           
            $q = $this->_db->prepare('SELECT id, nom, degats, motdepasse FROM personnages WHERE nom <> :nom ORDER BY nom');
            $q->execute(array(':nom' => $nom));
           
            while ($donnees = $q->fetch(PDO::FETCH_ASSOC))
            {
                $persos[] = new Personnage($donnees);
            }
           
            return $persos;
        }
       
        public function update(Personnage $perso)
        {
            $q = $this->_db->prepare('UPDATE personnages SET degats = :degats WHERE id = :id');
           
            $q->bindValue(':degats', $perso->degats(), PDO::PARAM_INT);
            $q->bindValue(':id', $perso->id(), PDO::PARAM_INT);
           
            $q->execute();
        }
       
        public function setDb(PDO $db)
        {
            $this->_db = $db;
        }
    }
  ?>

<?php
    // On enregistre notre autoload
    function chargerClasse($classname)
    {
        require $classname.'.class.php';
    }
   
    spl_autoload_register('chargerClasse');
   
    session_start(); // On appelle session_start() APRÈS avoir enregistré l'autoload
   
    if (isset($_GET['deconnexion']))
    {
        session_destroy();
        header('Location: .');
        exit();
    }
   
    $db = new PDO('mysql:host=localhost;dbname=personnages', 'root', '');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); // On émet une alerte à chaque fois qu'une requête a échoué
   
    $manager = new PersonnagesManager($db);
 
   
    if (isset($_SESSION['perso'])) // Si la session perso existe, on restaure l'objet
    {
        $perso = $_SESSION['perso'];
    }
   
    if (isset($_POST['creer']) && isset($_POST['nom'])) // Si on a voulu créer un personnage
    {
        $perso = new Personnage(array('nom' => $_POST['nom'])); // On crée un nouveau personnage
       
        if (!$perso->nomValide())
        {
            $message = 'Le nom choisi est invalide.';
            unset($perso);
        }
        elseif ($manager->exists($perso->nom()))
        {
            $message = 'Le nom du personnage est déjà pris.';
            unset($perso);
        }
    if (isset($_POST['creer']) && isset($_POST['motdepasse'])) // Si on a voulu créer un personnage
    {
        $perso = new Personnage(array('motdepasse' => $_POST['motdepasse'])); // On crée un nouveau personnage
       
        if (!$perso->motdepassevalid())
        {
            $message = 'Le mot de passe choisi est invalide.';
            unset($perso);
        }
       
    }
        else
        {
            $manager->add($perso);
        }
    }
   
 
 
       
 
 
 
 
 
 
    elseif (isset($_POST['utiliser']) && isset($_POST['nom'])) // Si on a voulu utiliser un personnage
    {
       
    if ($manager->exists($_POST['nom']) AND $manager->exists($_POST['motdepasse'])  )// Si celui-ci existe
        {
            $perso = $manager->get($_POST['nom']) AND $perso = $manager->get($_POST['motdepasse']);
     
        }
   
    else
        {
            $message = 'mot de passe ou nom invalide'; // S'il n'existe pas, on affichera ce message
        }
   
   
   
   
 
   
   
     
       
    }
 
 
 
   


 
 
 
 
 
   
    elseif (isset($_GET['frapper'])) // Si on a cliqué sur un personnage pour le frapper
    {
        if (!isset($perso))
        {
            $message = 'Merci de créer un personnage ou de vous identifier.';
        }
       
        else
        {
            if (!$manager->exists((int) $_GET['frapper']))
            {
                $message = 'Le personnage que vous voulez frapper n\'existe pas !';
            }
           
            else
            {
                $persoAFrapper = $manager->get((int) $_GET['frapper']);
               
                $retour = $perso->frapper($persoAFrapper); // On stocke dans $retour les éventuelles erreurs ou messages que renvoie la méthode frapper
               
                switch ($retour)
                {
                    case Personnage::CEST_MOI :
                        $message = 'Mais... pourquoi voulez-vous vous frapper ???';
                        break;
                   
                    case Personnage::PERSONNAGE_FRAPPE :
                        $message = 'Le personnage a bien été frappé !';
                       
                        $manager->update($perso);
                        $manager->update($persoAFrapper);
                       
                        break;
                   
                    case Personnage::PERSONNAGE_TUE :
                        $message = 'Vous avez tué ce personnage !';
                       
                        $manager->update($perso);
                        $manager->delete($persoAFrapper);
                       
                        break;
                }
            }
        }
    }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "[url]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd[/url]">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
    <head>
        <title>TP : Mini jeu de combat</title>
       
        <meta http-equiv="Content-type" content="text/html; charset=iso-8859-1" />
    </head>
    <body>
        <p>Nombre de personnages créés : <?php echo $manager->count(); ?></p>
<?php
    if (isset($message)) // On a un message à afficher ?
    {
        echo '<p>', $message, '</p>'; // Si oui, on l'affiche
    }
   
    if (isset($perso)) // Si on utilise un personnage (nouveau ou pas)
    {
?>
        <p><a href="?deconnexion=1">Déconnexion</a></p>
       
        <fieldset>
            <legend>Mes informations</legend>
            <p>
                Nom : <?php echo htmlspecialchars($perso->nom()); ?><br />
                Dégâts : <?php echo $perso->degats(); ?>
       
            </p>  
        </fieldset>
       
        <fieldset>
            <legend>Qui frapper ?</legend>
            <p>
<?php
    $persos = $manager->getList($perso->nom());
   
    if (empty($persos))
    {
        echo 'Personne à frapper !';
    }
   
    else
    {
        foreach ($persos as $unPerso)
        {
            echo '<a href="?frapper=', $unPerso->id(), '">', htmlspecialchars($unPerso->nom()), '</a> (dégâts : ', $unPerso->degats(), ')<br />';
        }
    }
?>
            </p>
        </fieldset>
<?php
    }
    else
    {
?>
        <form action="" method="post">
            <p>
                Nom : <input type="text" name="nom" maxlength="50" />
        mot de passe : <input type="text" name="motdepasse" maxlength="50" />
                <input type="submit" value="Créer ce personnage" name="creer" />
                <input type="submit" value="Utiliser ce personnage" name="utiliser" />
            </p>
        </form>
<?php
    }
?>


<?php
try
{
 
  $bdd = new PDO('mysql:host=localhost;dbname=personnages', 'root', '');
}
catch(Exception $e)
{
 
        die('Erreur : '.$e->getMessage());
}


$reponse = $bdd->query('SELECT * FROM image');


 

while ($donnees = $reponse->fetch())
{

  echo '<img src="'.$donnees['image'].'" />';

}

$reponse->closeCursor();

?>

    </body>
</html>
<?php
    if (isset($perso)) // Si on a créé un personnage, on le stocke dans une variable session afin d'économiser une requête SQL
    {
        $_SESSION['perso'] = $perso;
    }

Dernière modification par bly (16-07-2012 16:24:09)

Hors ligne

#12 16-07-2012 17:10:08

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : probleme avec des classes

Bonjour,

Votre modèle de gestion n'est pas du tout fonctionnel ni opérationnel.
Je vous invite tout d'abord à lire/relire ce post dans lequel la notion d'encapsulation est abordée.

Voici les problèmes de votre modèle actuel
- Chaque classe n'est pas autonome dans ce qu'elle doit gérer.
- Votre classe d'accès aux données, votre classe personnage, votre classe de gestion de connexion sont au même niveau alors que le front controler ne doit pas pouvoir accèder à la couche métier directement. Ainsi les appels vers la base de données ne doivent se faire qu'à partir de la classe personnage.
- La persistance d'une classe en session ne peut pas se faire par affectation mais doit se faire par sérialisation/désérialisation.
- Vous ne devez avoir qu'un seul point d'entrée pour la gestion de vos personnages. Actuellement tout se fait dans l'espace global, ce qui n'est pas viable et est contraire au principe d'encapsulation.
- Vous ne travaillez pas sur les mêmes instances de classe.

Voilà pour l'essentiel même s'il y a encore beaucoup à dire.

++

Dernière modification par Jc (16-07-2012 17:11:09)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#13 16-07-2012 17:32:05

bly
Membre
Inscription : 21-08-2010
Messages : 15

Re : probleme avec des classes

ok merci , je vais tout revoir alors smile .

Hors ligne

Pied de page des forums