RECHERCHER :
COMMUNAUTE MP
Identifiez vous ...
Devenir Membre
J'ai oublié mon MDP
DOMAINE MP
Bavardages
Langages Généraux
Langages Web
Langages DotNet
Autres langages
Dev. Jeux Video
Sécurité
Sys. Exploitation
Graphismes
Logiciels
Réseaux
Bases de données
Méthodologies
Emplois High-tech
Aide juridique
Articles juridiques
FORUM
Index des forums
Ajouter un sujet
Rechercher sujet
Contact Responsable
Devenir modérateur
CHAT MP IRC
Votre pseudo ...
Srv: irc.moteurprog.com
Chan: #MoteurProg
PARTICIPER
Plus de 3500 emplois.
Rechercher un job
Déposez votre CV
Emplois High-tech

Visiteur MP

 Donjons POO

Forum : POO
Sous Catégorie : Aucune
Type du sujet : Sujet Normale
FAQ : FAQ POO

SUIVI DES SUJETS PAR MAIL

SUIVI PAR MAIL INACTIF

RESOLUTION DU SUJET SUJET RESOLU
BLOQUAGE DU SUJET SUJET ACTIF
APPARTENANCE A LA FAQ N'APPARTIENT PAS A LA FAQ


PAGES : [1] [2] [3] [4]

POSTER UN NOUVEAU SUJET REPONDRE A CE SUJET

FORUM POO

PREMIERE PAGE

PAGE PRECEDENTE

Page précedente

Page suivante

PAGE SUIVANTE

DERNIERE PAGE
doustij
Nouveau membre
Inscrit : 20/03/2006
Messages : 18
Message
#92947
Posté le 06/04/06 à 07:42
Merci pour tout, A bientôt, Jacques

HAUT DE PAGE

PROFIL MEMBRE LUI ECRIRE 

Publicité
Inscrit : X
Messages : X
Message
#Aucun

HAUT DE PAGE

  

KySeEtH
Nouveau membre
Avatar de KySeEtH
Inscrit : 28/07/2008
Messages : 2
Message
#155486
Posté le 28/07/08 à 15:17
Bonjour,
Je viens de survoler le sujet et je pense qu'il y a un défaut de conception à la base :S
Tu es en train de connecter tous tes objets (au sens POO pas jeu hein^^) entre eux car, à chaque fois que tu veux faire interagir deux objets il faut que tu crées un lien entre ces deux objets. En continuant comme ça, tu vas créer une super classe qui connaîtra tout et qui gêrera tout et tu vas vite craquer car ça va devenir ingérable (des IF dans tous les sens, la 54ème méthode à modifier que tu as oublié car l'anneau que le personnage vient de trouver agit comme clef de la 5ème porte du donjon si le monstre à 2 têtes est mort il y a moins d'une heure (car il se régénère et l'objet (au sens du jeu là :P) pour le tuer définitivement se trouve derrière cette 5ème porte...).
Ce que vous décrivez (prendre le talissement, frapper un monstre, perdre des points de vie...) sont une suite d'actions qui déclenche des événements. Il est donc plus naturel d'utiliser un modèle de programmation événementielle. De plus une architecture à couplage faible (i.e. chaque entité de l'application est faiblement engagée par rapport aux autres, c'est à dire ne connait pas grand chose de ce qui l'entoure. Et chaque entité se gêre de façon la plus autonome possible et interagit avec l'"extérieur" par des événements) est à mon sens la mieux adaptée à ce type de projet ; car tu ne sais pas quand quelque chose va se produire et tu ne veux pas connaitre toute la série d'actions qui a fait que le joueur peut faire ceci ou celà...
Je te donne un petit exemple dans mon prochain post histoire que tu puisses comparer.

A+
Jérôme
__________________________
MS attitude, Linux spirit

HAUT DE PAGE

PROFIL MEMBRE LUI ECRIRE 

KySeEtH
Nouveau membre
Avatar de KySeEtH
Inscrit : 28/07/2008
Messages : 2
Message
#155487
Posté le 28/07/08 à 15:17
OMG oO
Je viens de me rendre compte que j'ai déterré un post vieux de 2 ans :S
Mais je poste quand même l'exemple au cas où...

Exemple :
Prenons un joueur qui ne sait que se déplacer sur des points (pas de matrice, pas de donjon, rien ! Juste histoire de voir les interactions grâce aux événements). Il a des points de vie et quand ils sont à 0 ou moins le personnage meurt et la partie se termine.
Il y a aussi un monstre qui se déplace aléatoirement et qui frappe le joueur s'ils sont sur le même point.
Il existe ensuite un piège qui, quand le joueur passe dessus (i.e. sur ce point), explose et déchenche une alarme.
Quand l'alarme se déclenche, le monstre se déplace (téléporte^^) à l'endroit du piège et, par conséquent; frappe le joueur.
Règles :
1 - le joueur se déplace une fois par tour de la distance qu'il souhaite (superman ? :P).
2 - le monstre se déplace une seule fois par tour.
3 - le piège ne fonctionne qu'une seule fois.

Remarque : le source est en C# avec le Framework .NET

Commençons par la classe du joueur "CCharacter"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CCharacter { public CCharacter(Point TheLocation) { _Location = TheLocation; _Life = 20; } public Point Location { get { return _Location; } set { SetLocation(value); } } public int Life { get { return _Life; } } public event EventHandler OnLocationChanged; public event EventHandler OnLifeChanged; public void TakeDamages(int TheDamages) { if (TheDamages > 0) { _Life -= TheDamages; Console.WriteLine("Player: Ouch, That hurts!"); if (OnLifeChanged != null) OnLifeChanged(this, null); } } private void SetLocation(Point TheValue) { if (_Location != TheValue) { _Location = TheValue; Console.WriteLine("Player: Let's go to point: " + _Location.X + ", " + _Location.Y); if (OnLocationChanged != null) OnLocationChanged(this, null); } } private Point _Location; private int _Life; } }


Elle possède deux membres privés :
- _Location qui définit le point où se trouve le joueur ;
- _Life qui définit le nombre de point de vie restant.

Quand le joueur se déplace l'événement OnLocationChanged est lancé.
Le joueur ne peut que perdre des points de vie via la méthode publique TakeDamages. Quand cela se produit l'événement OnLifeChanged est lancé.

Maintenant regardons la classe piège: "CTrap"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CTrap { public CTrap(Point TheLocation) { _Location = TheLocation; _Damages = 10; _IsArmed = true; } public event EventHandler OnTrapExplode; public Point Location { get { return _Location; } } public int Explode() { int TheDamages = 0; if (_IsArmed) { TheDamages = _Damages; _IsArmed = false; Console.WriteLine("Trap: tic tac, tic t... BOOM!"); if (OnTrapExplode != null) OnTrapExplode(this, null); } return TheDamages; } private Point _Location; private int _Damages; private bool _IsArmed; } }


Le piège est défini à un endroit (ici le point (2, 2)) et fait X (ici 10) points de dommages à la cible une seule fois via la méthode publique Explode.
Quand elle explose l'événement OnTrapExplode est lancé.

Regardons la classe d'alarme "CAlarm"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CAlarm { public CAlarm() { _Trap = new CTrap(new Point(2, 2)); AttachEvents(); } ~CAlarm() { DetachEvents(); } public event EventHandler OnAlarmStarted; public CTrap Trap { get { return _Trap; } } public void AttachEvents() { _Trap.OnTrapExplode += new EventHandler(TheBoomFunction); } public void DetachEvents() { _Trap.OnTrapExplode -= new EventHandler(TheBoomFunction); } private void TheBoomFunction(object sender, EventArgs e) { // Do something like close a door... Console.WriteLine("Alarm: Warning ! Alarm Started"); if (OnAlarmStarted != null) OnAlarmStarted(this, null); } private CTrap _Trap; } }


L'alarme est associée à un piège (il ne faut pas établir une relation d'appartenance comme je l'ai fait mais créer une classe gérant cette relation car nous pouvons avoir n alarmes qui se déclenchent au contact de m pièges. Mais ce n'est pas le but de l'exemple).
L'alarme s'est abonnée sur l'événement d'explosion du piège. Quand il explose, l'alarme exécute la méthode TheBoomFunction. Elle fait quelque chose (ici elle dit juste "Warning") et lance l'événement OnAlarmStarted.

La classe monstre "CMonster"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CMonster { public CMonster(Point TheLocation) { _Alarm = new CAlarm(); _Location = TheLocation; _Damages = 5; AttachEvents(); } ~CMonster() { } public event EventHandler OnLocationChanged; public Point Location { get { return _Location; } set { SetLocation(value); } } public CAlarm Alarm { get { return _Alarm; } } public bool HasMovedThisTurn { get { return _HasMovedThisTurn; } set { _HasMovedThisTurn = value; } } public int Hit() { Console.WriteLine("Monster: taste that human!"); return _Damages; } public void Move() { if (!_HasMovedThisTurn) { Random rnd = new Random((int)DateTime.Now.Ticks); int newX = _Location.X + (rnd.Next() % 3) - 1; int newY = _Location.Y + (rnd.Next() % 3) - 1; if (newX < 0) newX = 0; if (newY < 0) newY = 0; Location = new Point(newX, newY); } } private void AttachEvents() { _Alarm.OnAlarmStarted += new EventHandler(GoGoGo); } private void DetachEvents() { _Alarm.OnAlarmStarted -= new EventHandler(GoGoGo); } private void SetLocation(Point TheValue) { if (!_HasMovedThisTurn && (_Location != TheValue)) { _Location = TheValue; _HasMovedThisTurn = true; Console.WriteLine("Monster: Hu hu hu, I move to point: " + _Location.X + ", " + _Location.Y); if (OnLocationChanged != null) OnLocationChanged(this, null); } } private void GoGoGo(object sender, EventArgs e) { CAlarm TheAlarm = sender as CAlarm; if (TheAlarm != null) { Console.WriteLine("Monster: Alarm ? let's do it!"); Location = TheAlarm.Trap.Location; // My monsters have blink^^ } } private bool _HasMovedThisTurn; private int _Damages; private Point _Location; private CAlarm _Alarm; } }


Un monstre est associé à une ou plusieurs alarmes (qui doit être géré par un classe de gestion des alarmes (par exemple en fonction de la distance entre l'alarme et le monstre) et non pas comme je viens de le définir (cf classe CAlarm)). Quand le monstre entend une alarme il se déplace (téléporte...) sur le point où se trouve le piège qui a déclenché l'alarme. Pour ce faire, la classe est abonnée à l'événement de l'alarme OnAlarmStarted et exécute la méthode GoGoGo. Dans cette méthode il tente de se déplacer (s'il n'a pas bougé ce tour) à l'endroit du piège.
Le monstre se déplace une seule fois par tour (cf le membre _HasMovedThisTurn) et tape le joueur qui a le malheur de croiser son chemin) : méthodes plubiques Move() et Hit().
Quand le monstre se déplace il lance l'événement OnLocationChanged.

Comment controler les movements ? "CMoveControler"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CMoveControler { public CMoveControler() { _Player = new CCharacter(new Point(0, 0)); _Monster = new CMonster(new Point(3, 3)); _Trap = _Monster.Alarm.Trap; AttachEvents(); } ~CMoveControler() { DetachEvents(); } public CCharacter Player { get { return _Player; } } public CMonster Monster { get { return _Monster; } } public CTrap Trap { get { return _Trap; } } public void AttachEvents() { _Player.OnLocationChanged += new EventHandler(OnPlayerMove); _Player.OnLifeChanged += new EventHandler(OnPlayerLifeChanged); _Monster.OnLocationChanged += new EventHandler(OnMonsterMove); } public void DetachEvents() { _Player.OnLocationChanged -= new EventHandler(OnPlayerMove); _Player.OnLifeChanged -= new EventHandler(OnPlayerLifeChanged); _Monster.OnLocationChanged -= new EventHandler(OnMonsterMove); } public event EventHandler OnGameOver; private void OnPlayerMove(object sender, EventArgs e) { if (_Player.Location == _Monster.Location) { if (_Player.Life <= 0) Console.WriteLine("Monster: Hu hu hu, a dead human!"); else _Player.TakeDamages(_Monster.Hit()); } if (_Player.Location == _Trap.Location) { _Player.TakeDamages(_Trap.Explode()); } } private void OnPlayerLifeChanged(object sender, EventArgs e) { if ((_Player.Life <= 0) && (OnGameOver != null)) OnGameOver(this, null); } private void OnMonsterMove(object sender, EventArgs e) { if (_Player.Location == _Monster.Location) { if (_Player.Life <= 0) Console.WriteLine("Monster: Hu hu hu, a dead human!"); else _Player.TakeDamages(_Monster.Hit()); } } private CCharacter _Player; private CMonster _Monster; private CTrap _Trap; } }

Cette classe contrôle les protagonistes (i.e. le joueur, le piège et le monstre). Elle gère aussi ce qu'il doit se passer quand ils se rencontrent.
Elle est abonnée sur les changement de position du joueur (OnPlayerMove) et du monstre (OnMonsterMove) :
- OnPlayerMove : vérifie si le joueur entre en collision avec le monstre (dommage, il s'en prend une^^) ou s'il tombe dans un piège (dommage il explose, l'alarme sonne et le monstre arrive... Redommage, il s'en reprend une... Dur la vie d'aventurier^^).
- OnMonsterMove: vérifie si le monstre entre en collision avec le joueur (dommage pour le joueur car il s'en prend (encore ?) une... C'est pas une vie aventurier :P).
De plus cette classe s'est abonnée sur l'événement OnPlayerLifeChanged (qui devrait être dans une autre classe... Celle de gestion de la vie par exemple...). Elle lance l'événement OnGameOver si la vie du joueur atteint 0...

La classe de jeu "CMain"

using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace TheTest.Donjon { public class CMain { public CMain() { _Moves = new CMoveControler(); _InGame = true; AttachEvents(); } ~CMain() { DetachEvents(); } public CMoveControler Moves { get { return _Moves; } } public void AttachEvents() { _Moves.OnGameOver += new EventHandler(GameOver); } public void DetachEvents() { _Moves.OnGameOver -= new EventHandler(GameOver); } public void Play() { while (_InGame) { int x, y; _Moves.Monster.HasMovedThisTurn = false; Console.WriteLine("Player move?"); Console.WriteLine("X?"); x = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Y?"); y = Convert.ToInt32(Console.ReadLine()); _Moves.Player.Location = new Point(x, y); if (!_Moves.Monster.HasMovedThisTurn) _Moves.Monster.Move(); } } private void GameOver(object sender, EventArgs e) { Console.WriteLine("Game Over..."); _InGame = false; } private bool _InGame; private CMoveControler _Moves; } }


Cette classe demande une nouvelle position de déplacement au joueur jusqu'à ce qu'il soit mort.
Pour savoir s'il est mort, elle s'abonne sur l'événement OnGameOver de la classe CMoveControler.
Il suffit juste de lancer le jeu avec la méthode publique Play.

CMain TheGame = new CMain(); TheGame.Play(); Console.ReadKey();


J'espère que mes explications sont claires. Si vous avez des questions ou des remarques, n'ésitez pas.

PS: l'architecture est fausse ! Il faut prendre ici seulement l'idée d'interaction entre des entités grâce aux événements...
__________________________
MS attitude, Linux spirit

HAUT DE PAGE

PROFIL MEMBRE LUI ECRIRE 
POSTER UN NOUVEAU SUJET REPONDRE A CE SUJET

PREMIERE PAGE

PAGE PRECEDENTE Page précédente

Page suivante

PAGE SUIVANTE DERNIERE PAGE

FORUM POO



    PAGES : [1] [2] [3] [4]



.: Site Web développé par Julien Pichot et l'équipe MPWG avec www.evolvia-web.com :.