Moteur multi-objet pour un GTA Clone

papoulai Messages postés 13 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 24 mai 2004 - 23 mai 2004 à 15:09
cs_toniou Messages postés 17 Date d'inscription lundi 11 novembre 2002 Statut Membre Dernière intervention 24 janvier 2005 - 20 janv. 2005 à 22:25
Salut à tous.

Bon je suis un nouveau venu sur Flashkod, alors je me présente tres vite fais, Cyril, 30 ans, fou de Flash...

Bon, en surfant j'ai vu que certains s'etaient essayés à GTA sur Flash, et bien voyez-vous moi aussi, et c'est en cherchant une source pour m'aider à résoudre mon problème que je suis tombé sur FlashKod.

Mon projet est presque fini et je pourrai le mettre à dispo pour ceux que çà interresse, c'est pratiquement le jeu tel qu'il est commercialisé hormis la gestion de la 3D ( à plat ), là c'est de la 2D pure.

Seulement voilà, j'ai un problème :

Je cherche une solution à la gestion de la circulation des voitures.

J'ai volontairement abandonné les solutions suivantes :
- Guide

J'ai choisit de partir sur la base d'une Intelligence artificielle, comme si les voitures avaient chacune un conducteur, donc un "moteur" propre.
Afin de gérer les paramétres du "moteur" il me faut des déclencheurs, des repéres au sol qui vont dire au moteur de la voiture; "tourne à droite, arrétes toi, tourne à gauche, vas tout droit."
La vitesse de la voiture est fixée par défaut.

Celà impose la création et la gestion en permanence d'un grand nombre d'objets interractifs :

Les Voitures ( environs 50 par ville )
Les Carrefours ( plus de 100 par ville, donne les indications de direction )
Les Feux ( plus de 100 par ville, donne les indications de marche/arret )

Rien qu'à partir de cette description on peux s'apperçevoir que si chaque objet comporte un moteur unique le code va être lourd, mais qu'importe si le moteur de chaque objet reste léger, c'est à dire qu'il ne fait pas intervenir à tout moment un grand nombre de calculs mais juste un seul à un instant précis.

On en arrive à mon problème.

Afin de gérer mes objets sans avoir pour chaque chaque objet à nommer la totalité des objets avec lesquels il risque d'interragir ( imaginez un peu la lourdeur du code et le temps qu'il faut pour le taper .....

if (this.hitTest(_root.carrefour1)) {
setProperty(this, _rotation, _rotation += -90);
}
if (this.hitTest(_root.carrefour2)) {
setProperty(this, _rotation, _rotation += -90);
....

), je passes par une astuce.

Prenons l'exemple des voitures entre elles :

Chaque objet 'voiture' est nommée :
'voiture'+chiffre
voiture1
voiture2
voiture...

Pour faire un test de collision entre deux voitures je vais donc exécuter un test en permanence pour savoir si le nom de la voiture existe et si cette voiture est en contact ou pas avec mon objet en cours ( la voiture où se trouve ce code ) :

//
// MOTEUR DE LA VOITURE NON JOUEUR
//
// Déclaration des variables internes au clip à la l'ouverture du clip
//
onClipEvent (load) {
runtest = 600;
}
//
// A la lecture du clip...
//
onClipEvent (enterFrame) {
//
// Arret de la voiture en cas de choc avec une autre voiture
// Hormis de celle-ci
//
for (e= 0; e<50; e++) {
if ((_root['voiture'+e]!= this && _root['voiture'+e].hitTest(this._x, this._y, true)) {
runtest =0;
runtest -=Random(300);
}
}
//
// DEPLACEMENT DE LA VOITURE
//
// L'incrémentation de 'runtest' par pas de 10 de 0 à 600
// Permet de faire redémarer la voiture lentement puis del la laisser accélérer progressivement jusqu'a sa vitesse max
//
if (runtest<600) {
runtest +=10;
}
this = _x+=MATH.cos(_rotation*(math.pi/180))*runtest/100;
this = _y+=MATH.sin(_rotation*(math.pi/180))*runtest/100;
}

Ce code marche très bien, a chaque moment il vérifies toutes les valeurs de 0 à 50, puis vérifies si 'voiture'+valeur correspond bien à une voiture qui existe ( si valeur est comprise entre 0 et 50 ), et enfin il si les conditons sont remplies, il teste si 'voiture'+valeur est différent de cet obhet ( This ) et si 'voiture'+valeur est bien en contact avec cet objet ( This ).
Si toutes les conditions sont remplies et execute le code qui suit à savoir; il met la vitesse à 0.

Tout va donc bien c'est ce que je voulais faire, j'ai remplacé :

if (this.hitTest(_root.voiture1)) {
runtest =0;
}
if (this.hitTest(_root.voiture2)) {
runtest =0;
....

Par

for (e=0; e<50; e++) {
if ((_root['voiture'+e]!= this && _root['voiture'+e].hitTest(this._x, this._y, true)) {
runtest =0;
}
}

PROBLEME :
Imaginez ce code réutilisé pour : les voitures entre elles, les carrefours, les feux et tout le reste....
A chaque fois le code boucle sur 50 + 50 + 50 + ...multiplié par le nombre de voitures qui contient ce code, soit 50 par ville = BEAUCOUP TROP !!!!

Bien evidement le jeu se met à ramer à mort ce qui est logique vu le nombre de boucles qu'il execute au même moment.

J'ai deux pistes pour régler mon problème :

- Créer un moteur unique externe aux objets qui renvoie pour chaque interraction entre deux objets une valeur propre à la cible ( les objets en interractions )

- Créer une sorte de tableau dans mon code pour chaque voiture et trouver une fonction de native de l'ActionScript qui permet de vérifier si une valeur existe à tout moment dans mon tableau sans pour autant tester toutes les valeurs du tableau.

OUF !

Voilà, merci à tous ceux qui ont lu jusqu'ici, et surtout à ceux qui auront ne serait-ce même qu'un début de solution...
Aide de programmeur demandée :-)

Bonne journée.

Papoulai.

4 réponses

Prouprou_Sensei Messages postés 517 Date d'inscription mardi 23 décembre 2003 Statut Membre Dernière intervention 24 octobre 2006 1
23 mai 2004 à 17:27
Ecoute tu peut regarde la methode watch.

Mais je sais pas si ca fonctione avec les hitTest.
Enfin essaye de bidouiller avec ca.

Object.watch()
Disponibilité
Flash Player 6.

Usage
monObjet.watch( prop, rappel [, donnéesUtilisateur] )

Paramètres
prop Une chaîne indiquant le nom de la propriété d'objet à surveiller.

rappel La fonction à invoquer lorsque que la propriété surveillée change. Ce paramètre est un objet de fonction, pas un nom de fonction sous forme de chaîne. La forme de callback est callback(prop, ancienneVal, nouvelleVal, donnéesUtilisateur).

donnéesUtilisateur Une donnée ActionScript arbitraire qui est transmise à la méthode de rappel. Si le paramètre donnéesUtilisateur est omis, undefined est transmis à la méthode de rappel. Ce paramètre est facultatif.

Renvoie
Une valeur true si le point de surveillance est correctement créé ; sinon, renvoie une valeur false.

Description
Enregistre un gestionnaire d'événements à appeler lorsqu'une propriété spécifique ou un objet ActionScript est modifié(e). Lorsque la propriété change, la fonction de rappel est invoquée avec monObjet comme objet contenant. Vous devez renvoyer la nouvelle valeur depuis la méthode object.watch ou bien une valeur undefined est affectée à la propriété d'objet surveillée.

Un point de surveillance peut filtrer (ou annuler) l'affectation de valeur, en renvoyant une nouvelleVal modifiée (ou ancienneVal). Si vous supprimez une propriété pour laquelle un point de surveillance a été défini, ce point de surveillance ne disparaît pas. Si vous recréez ultérieurement la propriété, le point de surveillance est toujours en vigueur. Pour supprimer un point de surveillance, utilisez la méthode Object.unwatch.

Il ne peut exister qu'un seul point de surveillance enregistré sur une propriété. Les appels ultérieurs de Object.watch() sur la même propriété remplacent le point de surveillance original.

La méthode Object.watch() se comporte de façon similaire à la fonction Object.watch() de Netscape JavaScript version 1.2 et ultérieures. La principale différence est le paramètre donnéesUtilisateur, qui est un ajout Flash à Object.watch() non supporté par Netscape Navigator. Vous pouvez passer le paramètre donneesUtilisateur dans le gestionnaire d'événements et l'utiliser dans ce dernier.

La méthode Object.watch() ne peut pas surveiller les propriétés de lecture/définition. Les propriétés de lecture/définition fonctionnent par « évaluation passive » - la valeur de la propriété n'étant pas déterminée tant que la propriété n'est pas interrogée. Une « évaluation passive » est souvent rentable étant donné que la propriété n'est pas constamment mise à jour, mais simplement évaluée lorsqu'il le faut. Cependant, Object.watch() a besoin d'évaluer une propriété pour activer des point de surveillance sur celle-ci. Pour fonctionner avec une propriété de lecture/définition, Object.watch() a besoin d'évaluer constamment la propriété, ce qui n'est pas rentable.

En général, les propriétés ActionScript prédéfinies, telles que _x, _y, _width et _height, sont des propriétés de lecture/définition et ne peuvent donc pas être surveillées avec Object.watch().

Exemple
Cet exemple montre un composant CheckBox avec des méthodes qui définissent l'étiquette ou la valeur de chaque occurrence de case à cocher :

maCaseAcocher1.setValue(true);
maCaseAcocher1.setLabel("nouvelle étiquette");
...

Il est pratique de considérer la valeur et l'étiquette d'une case à cocher comme des propriétés. Il est possible d'utiliser Object.watch() de manière à ce que l'accès à la valeur et à l'étiquette ressemble plus à un accès à une propriété qu'à une invocation de méthode, comme dans l'exemple suivant :

// définir un constructeur pour (et donc définir) la classe CheckBox
function CheckBox() {
...
this.watch('valeur', function (id, ancienneVal, nouvelleVal) {
...
});
this.watch('étiquette', function(id, ancienneVal, nouvelleVal) {
...
});
}

Lorsque la propriété de valeur ou d'étiquette est modifiée, la fonction spécifiée par le composant est invoquée pour accomplir toutes les tâches nécessaires à la mise à jour de l'apparence et de l'état du composant. L'exemple suivant invoque une méthode Object.watch() pour aviser le composant que la variable a changé et lui fait mettre à jour sa représentation graphique.

maCaseAcocher1.value = false;

Cette syntaxe est plus concise que la précédente :

maCaseAcocher1.setValue(false);

Alé a tchao !
0
papoulai Messages postés 13 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 24 mai 2004
23 mai 2004 à 17:39
Ok meci, et merci d'avoir pris le temps de me répondre, je teste avec cette syntaxe pour voir ce que çà donne, je te tient au courrant en cas de réussite ( ou d'echec ) .

Merci.

Papoulai
0
cs_racam Messages postés 1 Date d'inscription samedi 28 août 2004 Statut Membre Dernière intervention 14 novembre 2004
14 nov. 2004 à 11:54
Salut, moi c'est Claudio, 15 ans. Je m'y connait pas du tout en flash mais j'aimerai apprendre, jlaisse mon e-mail pour les gens qui on le tant de m'enseigner un peu lol >> cargento27@hotmail.com <<
Passez sur mon site il y a quelques jeux >> www.founuse-game.tk
Sinon vous ne connaissez pas un gta like en flash très bien fait que je pourrait y placer? Merci
0
cs_toniou Messages postés 17 Date d'inscription lundi 11 novembre 2002 Statut Membre Dernière intervention 24 janvier 2005
20 janv. 2005 à 22:25
n y a t il pas moyen de gérer seulement les clip affiché a l ecran au lieu de gerer toute les voiture de la ville?
0
Rejoignez-nous