Forums Développement Multimédia

Aller au contenu

Création d'un jeu avec flash

CODE

64 réponses à ce sujet

#1 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 11 August 2013 - 13:25 PM

Bonjour


Je travaille sur un jeux, comme c'est une première, je peut avoir pas mal d'interrogation, merci à ceux qui prendront le temps de m'aider et plaisir à partager leur savoir.

#2 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 11 August 2013 - 13:36 PM

Salut,

C'est bien d'ouvrir un sujet dédié, par contre il n'est pas au bon endroit, donc je le déplace dans la section jeux du forum.

D'autre part , peux-tu nous en dire un peu plus, tracer les grandes lignes, nous dire quels sont les points qui te bloquent pour le moment, quelles sont tes interrogations, ce que tu souhaites apprendre ou savoir avant de te lancer dans telle ou telle partie, etc...

#3 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 11 August 2013 - 14:03 PM

Salut Spi,


Il s'agit d'un jeux au gameplay relativement varié, dans un style shoot them up.


Je poste uniquement si je n'arrive pas à trouver la solution à un problème, le but n’étant pas de vous demander de faire le boulot à ma place :D

Une des choses qui ne marche pas bien pour le moment est le gameover. Je posterai très bientôt à ce sujet !

#4 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 14 August 2013 - 14:34 PM

Bonjour,

J'ai un problème avec ma classe "redballon". Voici le code :


package  {

import flash.display.MovieClip;
import flash.events.*;
import flash.media.*;
import flash.display.*;


public class redballon extends MovieClip {
//private var TD1:uint = getTimer ();
var bird1 = new Birds();
var nbdebirds:int = 2;

public function redballon(){                                  //Constructeur

this.addEventListener(Event.ADDED_TO_STAGE, initialise);  
}

public function initialise(e:Event){

//TD = getTimer ();
removeEventListener(Event.ADDED_TO_STAGE, initialise);
this.addEventListener(Event.ENTER_FRAME, moveandhittest);  
               

}




public function moveandhittest(e:Event){
//if (TD1 > 26000)       //temporise l'execution de la suite de la fonction
//{
this.x = this.x - 1 * (bird1.x / 40)      //Bouge "this" en fonction de la position de "controlbird1"

if (this.hitTestObject(this.parent.getChildByName("bird1")))  //si "this" touche "bird1" alors :
{
this.visible = false;
//removeChild(this);                                              //L'occurence "this" disparaît
nbdebirds --                                                    //On perd une vie  
this.removeEventListener(Event.ENTER_FRAME, moveandhittest);             //Arrête l'ecouteur d'evenement.
}


}





}
}


Première question, l’occurrence "bird1" est un clip importer directement depuis la bibliothèque :


var bird1 = new Birds();
addChild(bird1);
bird1.x = 255,75;
bird1.y = 414,95;
Est il juste d'ajouter cette ligne dans la classe : var bird1 = new Birds(); ?

Ensuite j'ai le message d'erreur suivant :

TypeError: Error #2007: Parameter hitTestObject must be non-null.

J'ai essayer plusieurs variante sans faire marcher le hit test.
Pourquoi ça ne marche pas ?

merci pour vos explications.(et solutions xD)

#5 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 14 August 2013 - 15:26 PM

Salut,

Je réitère en disant que partir sur des classes tout de suite n'est pas une bonne idée tant que tu n'as pas les bases du fonctionnement de Flash. Il vaut mieux faire tout ton jeu en posant ton code sur des calques de la timeline dans un premier temps, puis quand tout marche réfléchir pour utiliser des classes.

Là dans ta classe tu crée une occurrence de "Birds" que tu nomme "bird1".
Puis dans la fonction "moveandhittest" tu dis :


this.x = this.x - 1 * (bird1.x / 40)
 

Autrement dit, "this" est le conteneur (redballon) qui contient "bird1", et tu demande au conteneur de bouger en fonction de son contenu.

Puis plus loin :

if (this.hitTestObject(this.parent.getChildByName("bird1")))

Si on traduit cette ligne on obtient : "Si le conteneur touche le clip nommé "bird1" qui se trouve dans le parent du conteneur."

Déjà as-tu ajouté une occurrence de "redballon" dans ton code principal ?

D'autre part "bird1" est dans le conteneur et tu va le chercher dans le parent du conteneur, et si tu tente de tester la collision entre simplement "bird1" et le conteneur ça va planter puisque "bird1" est dans le conteneur.

C'est un gros méli mélo à mon avis, tout dépend de ton objectif, c'est à dire créer un jeu ou apprendre la POO en utilisant un jeu comme exercice, mais je te recommande vraiment de commencer par créer ton programme en procédural sur un calque de la timeline, tu verra plus tard pour la construction avec des classes, lorsque tu sera sur que ton programme marche correctement.

#6 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 14 August 2013 - 16:30 PM

Bonjour,

Merci pour ta réponse Spi, mais tu ne répond pas à ma question.

Est il juste d'ajouter cette ligne dans la classe : var bird1 = new Birds(); en plus de l'avoir dans le code de la première image clé ?
Faut 'il déclarer à nouveau les variables dans une classe qui les utilisent ?

j'ai essayer d'autre variante de hitTest sans succès.

Citation

Là dans ta classe tu crée une occurrence de "Birds" que tu nomme "bird1".

je n'ai pas été assez clair excuse moi, bird1 est crée dans le code principal et non dans la classe.



Déjà as-tu ajouté une occurrence de "redballon" dans ton code principal ?

Oui , elle bouge etc... seul le hit test ne marche pas.



L'objectif ici est d'apprendre à utiliser les classes avec un hit test. Bien sur comme tu le suggère je peut faire autrement.
(ce que je ne me gêne pas de faire en parallèle)
Mais ce sera moins pratique pour crée une multitude d'objet qui doivent fonctionner de la même manière.

#7 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 14 August 2013 - 17:17 PM

Citation

Est il juste d'ajouter cette ligne dans la classe : var bird1 = new Birds(); en plus de l'avoir dans le code de la première image clé ?

Cette ligne : var bird1 = new Birds();
Veut dire : créer une nouvelle occurence de "Birds" nommée "bird1" au sein de la classe "redballon".

Or cette occurrence est totalement indépendante de ce que tu as pu écrire en dehors de la classe "redballon"
Donc est-ce que cela a un sens d'avoir une occurrence de "Birds" dans "redballon" ?
Tes oiseaux sont à l'intérieur des ballons rouges ?

Le seul endroit où tu semble t'en servir c'est ici :

this.x = this.x - 1 * (bird1.x / 40)

Où tu dis à ton ballon rouge de se déplacer en fonction de l'oiseau, oui mais lequel ?
Celui qui est déclaré dans la classe "redballon" ou celui qui se trouve déjà sur ta scène dans ton code principal ?
Que se passe t'il si tu supprime l’occurrence de "Birds" qui se trouve dans "redballon" ?

if (this.hitTestObject(this.parent.getChildByName("bird1")))

Cette ligne comporte pour moi des erreurs, je dis "pour moi" car elle utilise des choses que je n'utilise pas dans mes codes, déjà "hitTestObject" je le proscrit, je préfères toujours utiliser une formule de collision entre deux HitBox (AABB), ensuite "getChildByName" est également proscrit dans mes codes, aller chercher un objet par son nom est lent car le programme va devoir parcourir toute la liste d'affichage et vérifier le nom de chaque objet jusqu'à ce qu'il trouve celui qui porte le bon nom, et veut en plus dire que tu connait le nom de tes objets, quand tu as des centaines d'objets à gérer ça devient ingérable, de plus pour que ça marche il faut lui donner spécifiquement un nom, ce que tu ne fais pas à première vue.

Dans un nouveau projet vierge, tapes juste ces lignes et regarde ce que renvoie la console :

var bird1:MovieClip = new MovieClip();
addChild(bird1)

trace(this.getChildByName("bird1"));

Maintenant ajoutes un nom à ton objet et réessayes :


var bird1:MovieClip = new MovieClip();
bird1.name = "bird1";
addChild(bird1)

trace(this.getChildByName("bird1"));
 

Donc tu dois spécifiquement ajouter un nom à chaque objet que tu crée, c'est une horreur dès que tu as beaucoup d'objets à gérer. Imagine que tu as 100 oiseaux, dans ta classe tu va écrire 100 fois le test de collision avec à chaque fois le nom de l'oiseau que tu veux tester ? Et si tu veux ajouter des oiseaux, tu va devoir modifier la classe des ballons en conséquence ?


Pour moi la logique serait :

Créer une classe "oiseaux" qui sert à définir chaque oiseau (taille, position, couleur, .... ) et le faire bouger (c'est un objet indépendant comme dans la vie).

Créer une classe "ballons" qui sert à définir chaque ballon (taille, position, couleur, .... ) et le faire bouger (là aussi c'est un objet indépendant).

Dans le code principal, créer deux tableaux de stockage, un pour les oiseaux et un pour les ballons.
A chaque fois que je crée un oiseau je le range dans son tableau de stockage.
A chaque fois que je crée un ballon je le range dans son tableau de stockage.

Toujours dans le code principal, pour tester la collision entre tous les ballons et tous les oiseaux, je parcours les deux tableaux de stockage et je teste la collision entre chaque objet.

Donc à mon sens ce n'est pas dans la classe des ballons que tu teste la collision, mais dans une partie du programme principal qui est dédiée à vérifier les collisions entre les objets. Dans la vraie vie ce n'est pas un ballon ou un oiseau qui décide si il doit y avoir une collision ou pas, lui il ne fait que se déplacer, si un objet se trouve sur son chemin il y a collision mais ça c'est le monde physique où il se trouve qui le détermine, ton ballon ou ton oiseau ne font que réagir en conséquence de la collision.

Tu peux très bien gérer une multitude d'objets via des tableaux, pas besoin d'une classe pour ça, sauf bien sur si tu veux "industrialiser" la création de plein d'objets de même type, et dans ce cas une classe est utile mais elle ne fait que définir l'objet (couleur, taille, vitesse, déplacement, etc.....).

#8 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 14 August 2013 - 18:29 PM

Bonjour,

Merci Spi pour la réponse,
Petite précision il ni à qu'un oiseaux !

Ton idée est intéressante,je vais essayer comme ça !
Par contre je n'ai encore jamais travailler avec les tableaux....

#9 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 14 August 2013 - 18:34 PM

Citation

Par contre je n'ai encore jamais travailler avec les tableaux....

D'où mon conseil de commencer par faire un programme complet et fonctionnel pour avoir bien toutes les bases avant de t'attaquer aux classes ;-)

Les tableaux sont aussi essentiels que les variables, tu va en utiliser tout le temps.

Si tu veux t'entrainer et voir comment c'est utilisé dans les jeux regarde les tutos qui sont dans ma signature, commence par lire Pong, Taquin et Snake, puis le reste si tu veux.

#10 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 14 August 2013 - 18:42 PM

Ok je vais voir. J'ai des bouquins aussi.

Donc ma classe ballon ressemble à ça :


package  {

import flash.display.MovieClip;
import flash.events.*;
import flash.media.*;
import flash.display.*;


public class redballon extends MovieClip {


public function redballon(){                                  //Constructeur

this.addEventListener(Event.ADDED_TO_STAGE, initialise);  
}

public function initialise(e:Event){


removeEventListener(Event.ADDED_TO_STAGE, initialise);
this.addEventListener(Event.ENTER_FRAME, moveballon);  
               

}




public function moveballon(e:Event){

this.x = this.x - 1 * (bird1.x / 40)      //Bouge "this" en fonction de la position de "bird1"




}





}
}

Le problème c'est que j'ai un message d'erreur à cause de bird1, et je souhaite que les instances de cette classe redballon bouge en fonction de bird1.

Comment régler ça ?

#11 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 14 August 2013 - 20:22 PM

Salut,

L'interet des classes, c'est de separer les choses en fonction de leur comportement.

Tu devrait donc avoir une classe Ballon qui defini le comportement des ballons, et une classe Oiseau qui definit le comportement des oiseaux. Ensuite, les ballons et les oiseaux evoluent dans un ciel, on aurait donc une classe Ciel.

Dans cette configuration, le ciel pourrait être ce qu'on appelle le Contexte, cela veut dire que le Ciel a connaissance des ballons et des oiseaux, les ballons et les oiseaux eux sont des classes "idiotes", elles n'ont conscience que d'elles-meme.

Tu aurais donc quelque chose de ce style (j'ecris ca a la volee, juste pour te donner une idee):


public class Ciel extends MovieClip
{
// ici tu declare les instances de tes ballons et de tes oiseaux
private var ballon:Ballon;
private var oiseau:Oiseau;


public function Ciel ()
{                                                        
// constructeur
ballon = new Ballon();
oiseau = new Oiseau()
addChild(ballon);
addChld(oiseau);
addEventListener(Event.EnterFrame, onEnterFrame);
}

private function onEnterFrame (e:Event)
{
// ici tu deplace ton ballon et ton oiseau et tu verifie le hit test
ballon.x += 1;
ballon.y += 1;
oiseau.x += 2;
oiseau.y += 2;
if (ballon.hitTestObject(oiseau) == true)
{
// le ballon explose
}
 

J'espere que ca t'aidera.


PS: Tu devrais suivre les conseils de Mr.Spi, il a beaucoup d'experience et tu apprendra très vite en suivant ses dires.

#12 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 15 August 2013 - 11:37 AM

Merci Draad,

En effet je suis partie sur l'idée de Spi.
J'ai donc crée un tableau :

var balls:Array = new Array("bal17","bal18");

bal17 et bal18 sont deux occurrence d'un symbole clip poser sur la scène par glisser déposer.

Ensuite j'ai crée ça pour parcourir le tableau et faire le hitTest:


addEventListener(Event.ENTER_FRAME, ballonShoot17);      //arriver sur la scene ballon shootable

function ballonShoot17(evt:Event)

{
for(var i:int=0; i<balls.length;i++){
if(balls[i].hitTestObject(controlbird1)){
trace("yes")
}
}
}


Mais j'ai un message d'erreur : TypeError: Error #1006: value is not a function.



Que faire ?

#13 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 15 August 2013 - 16:36 PM

Salut,

Quels sont les supports que tu utilise pour apprendre ?
Personnellement je te recommande ces lectures :

http://forums.mediab...latform/debuter
http://forums.mediab...ion/generalites
http://forums.mediab...m/programmation

Et surtout : http://forums.mediab...on/pratique_as3

Revenons à ton problème :

var balls:Array = new Array("bal17","bal18");
Avec ce code tu crée effectivement un tableau, mais tu le remplis avec deux textes (String) et non avec deux objets...

Citation

bal17 et bal18 sont deux occurrence d'un symbole clip poser sur la scène par glisser déposer.
Ce n'est pas de cette manière qu'il faut créer des objets que tu manipulera avec le code.

Citation

TypeError: Error #1006: value is not a function.

C'est normal, puisque ton tableau est rempli avec une valeur (ici une String) et non un objet, et que tu essayes de tester la collision entre du texte et un objet, du coup le programme te dit que "une valeur n'est pas une fonction".

Prenons un exemple de programme simple pour te mettre sur la voie.

1 - créer des objets
Dessiner un rectangle sur la scène.
Sélectionner ce rectangle et appuyer sur la touche F8 pour le transformer en "Clip".
Le clip nouvellement créé apparaît dans la bibliothèque.
Supprimer le clip de la scène (il reste dans la bibliothèque).
Cliquer avec le bouton droit de la souris sur le clip qui se trouve en bibliothèque.
Aller dans "Propriétés", choisir un nom avec une majuscule, par exemple "Birds" et cocher "Exporter pour AS".

Tu va remarquer que deux champs se remplissent automatiquement, il s'agit des champs "Classe" et "Classe de base", en faisant cette manipulation tu as donc créé une classe "Birds" dont la classe de base est "MovieClip".

En faisant ceci tu crée donc un "moule" (sous entendu une classe) dont le nom est "Birds" et qui peut être utilisé avec un code ActionScript.

2 - créer des occurrences utilisables dans un programme
Sur le premier calque du projet, ouvrir la fenêtre de code et écrire le code suivant :

var bird1:Birds = new Birds();

Je crée une occurrence de la classe "Birds" (l'objet qui est en bibliothèque) nommée "bird1".
A partir de là je peux utiliser ce nouvel objet dans mon code.
Je peux créer autant d'occurences que je le souhaite à partir du même objet.
A la suite du code écrire :


var bird1:Birds = new Birds();
var bird2:Birds = new Birds();
var bird3:Birds = new Birds();
var bird4:Birds = new Birds();
var bird5:Birds = new Birds();
 

Je crée 5 occurrences indépendantes du même objet.

3 - créer un tableau pour stocker mes objets
A la suite du programme écrire :

var stockBirds:Array = [];

Je crée un nouveau tableau vide.

4 - ajouter des objets à mon tableau
A la suite du programme écrire :


stockBirds.push(bird1);
stockBirds.push(bird2);
stockBirds.push(bird3);
stockBirds.push(bird4);
stockBirds.push(bird5);
 


Je viens de pousser mes 5 objets dans mon tableau, ils se rangent les uns à la suite des autres.

5 - ajouter mes objets sur la scène
A la suite du programme écrire :


addChild(bird1);
addChild(bird2);
addChild(bird3);
addChild(bird4);
addChild(bird5);
 


J'ajoute mes 5 objets sur la scène, ils s'empilent dans la liste d'affichage, "bird1" se retrouve donc affiché en dessous de "bird2", etc...

6 - simplifier son programme
Pour le moment le programme ressemble à ça :


var bird1:Birds = new Birds();
var bird2:Birds = new Birds();
var bird3:Birds = new Birds();
var bird4:Birds = new Birds();
var bird5:Birds = new Birds();

var stockBirds:Array = [];

stockBirds.push(bird1);
stockBirds.push(bird2);
stockBirds.push(bird3);
stockBirds.push(bird4);
stockBirds.push(bird5);

addChild(bird1);
addChild(bird2);
addChild(bird3);
addChild(bird4);
addChild(bird5);
 


C'est lourd et répétitif, il est donc possible d'utiliser des boucles pour simplifier l'écriture, surtout si on a beaucoup d'objets à créer.
Modifier le programme de la sorte :


// déclaration des variables globales
var i:int;
var bird:Birds;
var stockBirds:Array = [];

// lance la fonction d'initialisation
init();

// initialisation du jeu
function init():void{
        for(i=0; i<5; i++){
                bird = new Birds();
                stockBirds.push(bird);
                addChild(bird);
        }
}
 


Ce programme fait exactement la même chose que le précédent, mais permet, grâce à la boucle, de créer autant d’occurrence du même objet que je le souhaite. J'utilise une fonction pour créer mes objets car cela me permet par la suite de réutiliser cette fonction, par exemple lorsque le jeu est terminé et qu'on souhaite relancer une partie.

7 - tester la collision entre plusieurs objets
Il faut ajouter un objet différent qui va nous servir de test, par exemple un ballon.
Déplacer tous les oiseaux sur la scène, puis tester la collision entre le ballon et tous les oiseaux.
Pour cela il faut modifier le programme de la sorte :


// déclaration des variables globales
var i:int;
var bird:Birds;
var ballon:Ballon;
var stockBirds:Array = [];

// lance la fonction d'initialisation
init();

// initialisation du jeu
function init():void{
        for(i=0; i<5; i++){
                bird = new Birds();
                bird.x = int(Math.random()*550);
                bird.y = int(Math.random()*400);
                stockBirds.push(bird);
                addChild(bird);
        }
        ballon = new Ballon();
        ballon.x = 275;
        ballon.y = 200;
        addChild(ballon);
        addEventListener(Event.ENTER_FRAME, main);
}

// boucle principale du programme
function main(e:Event):void{
        deplacementBirds();
        testCollisionsBirds();
}

// déplacement des oiseaux
function deplacementBirds():void{
        for(i=0; i<stockBirds.length; i++){
                bird = stockBirds[i];
                bird.x += 10;
                if(bird.x > 550) {
                        bird.x = 0;
                        bird.y = int(Math.random()*400);
                }
        }
}

// déplacement des oiseaux
function testCollisionsBirds():void{
        for(i=0; i<stockBirds.length; i++){
                bird = stockBirds[i];
                if(bird.hitTestObject(ballon)) {
                        removeChild(bird);
                        stockBirds.splice(i,1);
                        trace("oiseau détruit");
                }
        }
}
 


Que fait ce programme ?

Il commence par créer un ballon, puis 5 oiseaux qu'il stocke dans un tableau.
Au passage il les places aléatoirement sur la scène et place le ballon au centre de la scène.
Puis l'écouteur va lancer la fonction "main" (principale) à chaque frame du programme.
Si le framerate est réglé sur 30 cette fonction sera appellée 30 fois par seconde.
La fonction principale ne sert qu'à centraliser les choses, comme déplacer les oiseaux puis tester la collision avec le ballon.

Pour déplacer les oiseaux on se sert d'une nouvelle fonction qui fait une boucle sur tous les oiseaux compris dans le tableau de stockage.
Chaque oiseau est déplacé de 10 pixels sur l'axe X à chaque fois que cette fonction est appelée.
Si l'oiseau sort des limites de la scène il est replacé de l'autre côté sur l'axe X et aléatoirement sur l'axe Y.

Pour tester la collision on se sert d'une autre fonction, histoire de bien séparer les choses, qui fait elle aussi une boucle sur tous les oiseaux compris dans le tableau de stockage. Si un oiseau touche le ballon, il est détruit, donc retiré de la scène et retiré du tableau de stockage, la console affiche que l'oiseau est détruit.

Voici le résultat :


- Afficher le SWF -
Fichier joint  test_programme.swf   16.48 Ko   14 téléchargement(s)

Fichier(s) joint(s)



#14 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 15 August 2013 - 16:38 PM

Merci Spi tu ma déjà bien aider.

Je vais étudier tout ça !

#15 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 17 August 2013 - 16:19 PM

Bonjour,

J'ai bien compris comment faire pour importer des occurrences d'un symbole directement depuis la bibliothèque
et l'afficher comme dans ton exemple:

var bird1:Birds = new Birds();
addChild(bird1); //ajout à la liste d'affichage
bird1.x = 1000; //position de bird1 en x

Mais admettons que je veuille quand même disposer quelques occurrences d'un symbole graphique directement sur la scène, est il tout de même possible de les mettre dans un tableaux ?


Merci.

#16 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 17 August 2013 - 16:25 PM

Oui a la condition que tu donne un nom d’occurrence à ton objet (panneau propriétés de l'objet), mais c'est déconseillé car tu fini par ne plus savoir ce qui est posé ou pas sur la scène et à quel moment. Si tu veux faire les choses proprement il faut faire un choix entre faire les choses par le code ou poser des choses à la main sur la scène.

#17 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 17 August 2013 - 23:24 PM

Merci Spi.

#18 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 18 August 2013 - 14:43 PM

Bonjour,

Spi pourrai tu m'expliquer ce que signifie la ligne ? bird = stockBirds[i];

merci

#19 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 18 August 2013 - 14:51 PM

// déclaration des variables globales
var i:int;
var bird:Birds;
//....

Dans la déclaration des variables globales, je crée une variable "bird" qui est de type "Birds".
Cette variable est dite "générique", c'est à dire que je peux l'utiliser pour tout et n'importe quoi tant qu'il s'agit d'un objet de type "Birds".

Elle est utilisée ici :


// initialisation du jeu
function init():void{
                for(i=0; i<5; i++){
                                bird = new Birds();
                                bird.x = int(Math.random()*550);
                                bird.y = int(Math.random()*400);
                                stockBirds.push(bird);
                                addChild(bird);
                }

           //..
 

Et ici :

// déplacement des oiseaux
function deplacementBirds():void{
                for(i=0; i<stockBirds.length; i++){
                                bird = stockBirds[i];
                                bird.x += 10;
                                if(bird.x > 550) {
                                                bird.x = 0;
                                                bird.y = int(Math.random()*400);
                                }
                }
}

Et ici :

// déplacement des oiseaux
function testCollisionsBirds():void{
                for(i=0; i<stockBirds.length; i++){
                                bird = stockBirds[i];
                                if(bird.hitTestObject(ballon)) {
                                                removeChild(bird);
                                                stockBirds.splice(i,1);
                                                trace("oiseau détruit");
                                }
                }
}

Je réutilise donc toujours la même variable, qui prend telle ou telle valeur selon ce que j'ai envie d'utiliser, c'est l'intérêt dune variable qui comme son nom l'indique peut varier et donc changer de valeur.

Pour cette ligne :

bird = stockBirds[i];

Je dis simplement au code que ma variable "générique" correspond à ce moment précis à l'objet qui se trouve dans le tableau de stockage des oiseaux à l'index indiqué à par la variable "i". C'est un raccourcis plutôt que d'écrire :

// déplacement des oiseaux
function testCollisionsBirds():void{
                for(i=0; i<stockBirds.length; i++){
                                if(stockBirds[i].hitTestObject(ballon)) {
                                                removeChild(stockBirds[i]);
                                                stockBirds.splice(i,1);
                                                trace("oiseau détruit");
                                }
                }
}


#20 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 18 August 2013 - 14:57 PM

OK merci beaucoup Spi pour ta disponibilité, ta réactivité et les connaissances/expériences que tu transmet ici :D
(je devrai ajouter ta patience avec un novice tel que moi XD)


(au passage je retire ma dernière question)

#21 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 21 August 2013 - 16:19 PM

Hello,

Je souhaite utiliser un tableau avec un écouteur d’événement de type MouseEvent
J'avoue ne pas savoir comment écrire cela !



ballonBleu1.addEventListener(MouseEvent.CLICK, clicsurleballon);

function clicsurleballon(event:MouseEvent):void
{
removeChild(ballonBleu1);

nbdeballoncliquez++ // la variable nbdeballoncliquez est augmenter de 1
T2 = getTimer();    // la variable T2 est egale au temps ecoule depuis le lancement du prog.
 
}

 

Le but est de faire cela avec ballonBleu2,ballonBleu3 etc....à l'aide d'une boucle et d'un tableau.
Je ne sais pas par quelle bout commencer !

Merci.

#22 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 21 August 2013 - 17:22 PM

Un truc de ce genre (pas testé) :


var tableau:Array = [ballon1,ballon2,ballon3];

init();

function init():void{
    // ajoute un écouteur souris sur chaque objet contenu dans le tableau
    for(var i:int = 0 ; i<tableau.length; i++){
            tableau[i].addEventListener(MouseEvent.CLICK, cliqueBallon);
    }
}

function cliqueBallon(e:MouseEvent):void{
    var ballon = e.target; // récupère la cible de l'événement
    removeChild(ballon); // supprime la cible de l'affichage
    ballon.removeEventListener(MouseEvent.CLICK, cliqueBallon);// supprime l'écouteur de la cible
    tableau.splice(tableau.indexOf(ballon),1); // supprime la cible du tableau
    nbdeballoncliquez++; // incrémente le score
    ballon = null; // vide la variable temporaire
}


#23 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 21 August 2013 - 18:10 PM

Si tu es sur de ne mettre que des ballons dans ton tableau, tu devrais peut-etre utiliser un Vector au lieu d'un Array. Le principe est le même, sauf que le vector garde en mémoire le type d'objet qu'il stocke :


private var listeDeBallons :Vector.<MaClasseBallon>;
 

La difference est très utile car cela te permet d'acceder aux propriétées et aux fonctions de ta classe a traver la liste dans le code, cela t'assure aussi que dans la tableau il n'y ai que des Ballons et rien d'autre, si tu venais a tenter d'ajouter autre chose cela te donnerais une erreur. C'est aussi plus optimisé (je crois).

#24 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 21 August 2013 - 18:18 PM

Merci pour vos réponses.

Je vais essayer de faire marcher ça de suite.

#25 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 21 August 2013 - 18:51 PM

Merci Spi ton code fonctionne à merveille :)

#26 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 22 August 2013 - 18:10 PM

Hello,

Je cherche à optimiser une partie de mon code.


var tableau3:Array = [];  


tableau3.push(ballonRouge1V3);     //ajout d'un élément au tableau
tableau3.push(ballonJauneV3);
tableau3.push(petitJauneV3);
tableau3.push(bleuV3);
tableau3.push(petitRougeV3);
tableau3.push(ballonRouge2V3);




function init3():void{
    // ajoute un écouteur souris sur chaque objet contenu dans le tableau
    for(var i:int = 0 ; i<tableau3.length; i++){
            tableau3[i].addEventListener(MouseEvent.CLICK, cliqueBallon3);
    }

}

function cliqueBallon3(e:MouseEvent):void{
    var ballon3 = e.target; // récupère la cible de l'événement
    removeChild(ballon3); // supprime la cible de l'affichage
    ballon3.removeEventListener(MouseEvent.CLICK, cliqueBallon3);// supprime l'écouteur de la cible
    tableau3.splice(tableau3.indexOf(ballon3),1); // supprime la cible du tableau
nbdeballoneclate++ // incrémente le score du nombre de ballon cliquez
    txtballon.text = nbdeballoneclate.toString();  //affiche le nombre de ballons cliquez
    nbdeballoncliquez3++; // incrémente la variable
    ballon3 = null; // vide la variable temporaire

}

//* Evenements qui se déclenchent lors d'un clic sur un ballon TROISIEME SEQUENCE ! *//



ballonRouge1V3.addEventListener(MouseEvent.CLICK, clicsurleballonRouge1V3);

function clicsurleballonRouge1V3(event:MouseEvent):void
{  
T11 = getTimer();    // la variable T2 est egale au temps ecoule depuis le lancement du prog.
}
 

Je me demande s'il est possible d’intégrer la dernière fonction dans la boucle.
Pour faire ceci :

Si le ballon cliquez "e.target" est le ballon numéro 3 du tableau (ici bleuV3) alors T15 = getTimer();
SI le ballon cliquez "e.target" est le ballon numéro 4 avec T17 = getTimer();

Et ainsi de suite !
Mes tentatives n'ont pas aboutit.

Merci.

#27 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 22 August 2013 - 18:58 PM

Est-ce que tu peux expliquer plus precisement ce que tu essaye de faire, je ne comprends pas trop tes histoires de tableau3, ballon3, T15, T17.

#28 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 22 August 2013 - 21:09 PM

Bien sur Draad,

Je vais essayer !

Je crée des clips 'ballons' qui sont rangé dans un tableau comme me l'a fort bien appris Monsieur Spi.

J'utilise la classe getTimer() pour récupérer le temps qui c'est écoulé depuis le lancement du programme.

Je crée des variable que j'appel T0, T1 etc...

J'associe ces variables à chaque ballons dans l'ordre dans lequel je veut qu'ils soient cliquez.

Le premier ballon est associé à T0, le deuxieme à T1 et ainsi de suite.

Lors du clic sur un ballon, la variable T(0,1 etc..) est égale au temps qui c'est écoulé depuis le lancement du programme.

Ce que je souhaite faire c'est utiliser ma boucle et mon tableau pour ne pas avoir à écrire machinalement :

ballonRouge1V3.addEventListener(MouseEvent.CLICK, clicsurleballonRouge1V3);

function clicsurleballonRouge1V3(event:MouseEvent):void
{
T11 = getTimer(); // la variable T2 est egale au temps ecoule depuis le lancement du prog.
}

ballonBleu1V3.addEventListener(MouseEvent.CLICK, clicsurleballonBleu1V3);

function clicsurleballonRouge1V3(event:MouseEvent):void
{
T12 = getTimer(); // la variable T2 est egale au temps ecoule depuis le lancement du prog.
}

#29 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 23 August 2013 - 02:23 AM

Tu ne m'as pas expliqué a quoi te servent les variables T1 et T2 . Est-ce que cela te sert a savoir si les ballons ont bien été cliqué dans l'ordre d'appartion? Est-ce que cela te sert a savoir combien de points le joueur va marquer en cliquant sur le ballon?

#30 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 00:19 AM

Hello,

Les variables T1 , T2 ainsi que toutes les variables qui commencent par T me servent à savoir à quelle moment depuis le lancement du programme chaque ballon à été cliquez.

Cela me permet de savoir dans quelle ordre les ballons ont été cliquez !

Je souhaite que le joueur gagne un point si ils cliquent sur les ballons dans un ordre précis.
Sinon il ne gagne rien.

Par exemple le joueur doit cliquez sur le ballonBleu, puis le ballonJaune, et enfin le ballonRouge

J'attribue une variable T à chaque ballon
Dans l'exemple :

ballonRouge = T1,
ballonBleu = T2,
ballonJaune = T3

Les variables T1,T2 et T3 = un nombre qui correspond au temps écoule depuis le lancement du programme.

Si je clic sur le ballonRouge au bout de 5 seconde. T1 sera égale à 500 par exemple.
Si je clic sur le ballonRouge au bout de 10 seconde, T1 sera égale à 1000.
Si je clic sur le ballonBleu au bout de 5 seconde. T1 sera égale à 500.

Alors si le joueur a cliquez sur les ballons dans le bon ordre alors :

T2<T3<T1

Si par exemple T3 est plus grand que T2 cela voudra dire que le joueur à cliquez sur le ballonBleu avant le ballonJaune.


J'espère être compréhensible.


Ou est passez Spi ? Image IPB

#31 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 00:38 AM

Ah, ça à l'air de marcher avec :


if (tableau[i] == tableau[2])
{
nbdeballonshoot ++
TA3 = getTimer()
}


#32 thot

    Ceinture Noire

  • Moderateur
  • PipPipPipPipPipPipPip
  • 331 messages

Posté 25 August 2013 - 00:48 AM

Bonsoir à tous, je me permets de mettre mon petit grain de sel dans cette conversation.
phillipeonline ta démarche est bonne et c'est très bien de te faire épauler pour la création de ton
premier jeu, mais à ton niveau il me semble que c'est un prématuré d'avoir un projet de ce genre là.

Je t'explique: au début du topic, tu dis n'avoir jamais travaillé avec les tableaux et vouloir également travailler
avec des classes. Je crois que tu prends les choses un peu trop rapidement, normalement quand on aborde
la POO, on sait déjà depuis un bon moment travailler en procédural, et les fondamentaux du langage sont acquis
(je pense que MonsieurSpi essayait de te remettre sur cette voie avec la solution du code procédural sur les calques).

A ta place je lirais entièrement l'ebook de Thibault Imbert disponible gratuitement sur son site http://bytearray.org.
Il faut impérativement et avant tout projet, que tu maitrises les notions de base ce qui n'est apparemment pas le cas.
Crois-moi après tout sera plus simple :) ;). Bon apprentissage !

#33 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 01:05 AM

Hello,

Merci pour ton commentaire Thot, et pour le liens.

Cependant, je n'utilise pas de classe pour le moment !
Il me reste deux trois difficultés à résoudre pour mon jeux. Le reste sera dans la même veine !
Je vais donc insister quelques peu, tout en poursuivant mes lectures.

#34 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 01:45 AM

Yes ça marche :)


for(i=0; i<tableau4.length; i++){

if(tir.hitTestObject(tableau4[i]))
{


if(tableau4[i] == bal17) {
nbdeballonshoot ++
TA3 = getTimer();
trace("TA3")
}

Merci Draad de t'avoir penché là dessus.

#35 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 25 August 2013 - 12:14 PM

Citation

Cela me permet de savoir dans quelle ordre les ballons ont été cliquez !

Inutile, tu peux utiliser un tableau pour ça ;-)
Lorsqu'un ballon est cliqué tu met son nom ou sa couleur ou ce que tu veux comme info pour le reconnaître, comme le temps passé, dans un tableau, il te suffit ensuite de lire ce tableau dans l'ordre pour trouver l'ordre dans lequel les ballons ont été cliqués.

Citation

je pense que MonsieurSpi essayait de te remettre sur cette voie avec la solution du code procédural sur les calques
Exactement ;-)

#36 thot

    Ceinture Noire

  • Moderateur
  • PipPipPipPipPipPipPip
  • 331 messages

Posté 25 August 2013 - 17:05 PM

Je me permets d'insister, lit cet e-book =), le recommande à tout le monde !

#37 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 17:25 PM

Merci Spi.

J'ai télécharger l'e-book thot ;)

#38 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 17:26 PM

Au fait Spi, il y a quelque chose qu'on ne peut pas faire avec des tableaux ? :D (humour)

#39 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 25 August 2013 - 17:30 PM

Ben en fait le tableau c'est un peu la base de tout, avant de passer aux classes, et même là tu va en utiliser très souvent. Disons que la gestion par tableau et par boucles telle que j'essaye de t'amener à la faire va te simplifier la vie par la suite.

#40 thot

    Ceinture Noire

  • Moderateur
  • PipPipPipPipPipPipPip
  • 331 messages

Posté 25 August 2013 - 17:38 PM

Héhé bien de l'avoir téléchargé, maintenant le plus important, le lire ! ;)

#41 philippeonline

    Ceinture Marron

  • Members
  • PipPipPipPipPipPip
  • 102 messages

Posté 25 August 2013 - 17:48 PM

Voir le messagethot, le 25 August 2013 - 17:05 PM, dit :

Je me permets d'insister, lit cet e-book =), le recommande à tout le monde !

Merci.J'aurai tout le temps de le lire demain au boulot.

#42 draad

  • Members
  • PipPipPipPipPipPipPipPip
  • 654 messages

Posté 25 August 2013 - 21:18 PM


for(i=0; i<tableau4.length; i++){
if(tir.hitTestObject(tableau4[i]))
{

if(tableau4[i] == bal17) {
nbdeballonshoot ++
TA3 = getTimer();
trace("TA3")
}
 

Ca marche, mais tu te complique la vie, imagine que tu ai 10 000 ballons, tu va devoir écrire ton test pour chaque ballon ! Si tu utilise mieu les tableau, tu pourra trouver automatiquement le bon ballon et le bon timer en fonction de ce dernier comme le conseille Mr Spi. L'interet des tableau, c'est de pouvoir conserver un ordre de classement facilement accessible si tu ne connais pas exactement l'instance que tu souhaite interroger, mais si tu la connais, tu peux aussi utiliser un Objet qui va te servir a stocker tes ballons et tes timers non plus par ordre d'apparrition, mais par clef de recherche :

Exemple, si tes ballons etendent la classe Sprite


private var tousMesBallons  : Object = {};
private var tousMesNumero :Object  = {};
private var numeroDuDernierBallonClique :int = -1;
private var pointsComboDeClic                             :int = 0;

private function creerDesBallons (nombreDeBallons:uint):void
{
        for (var i:int = 0; i < nombreDeBallons; i++)
        {
                var instanceDeBallon :Ballon = new Ballon ();
                instanceDeBallon.name = String(i);
                tousMesBallons[instanceDeBallon.name] = instanceDeBallon;
                tousMesTimer[instanceDeBallon.name]  = i;
                instanceDeBallon.addEventListener(MouseEvent.Click, clicSurUnBallon );
        }
}
private function clicSurUnBallon (e:MouseEvent):void
{
         var ballonQuiEstClique :Ballon = e.currentTarget as Ballon;
         if(tousMesNumero[ballonQuiEstClique.name] == numeroDuDernierBallonClique + 1)
         {
                 pointsComboDeClic  ++;
                 numeroDuDernierBallonClique ++;
         }
         else
         {
                pointsComboDeClic  = 0;
         }
 


Ainsi, en donnant un nom a chacun de tes ballons, tu peux te servir de ce nom pour definir une clef d'accès dans ton objet :

tousMesBallons["LeNomDeMonBallon"] = quelqueChose;

Ensuite tu peux rappeller cette clef a n'importe quel moment, et celà te rendra la valeur associé a cette clef, en l'occurence ton instance de Ballon.

trace (tousMesBallons["LeNomDeMonBallon"]);
--> quelqueChose;

Et cela t'evitera de definir un ecouteur pour chaque ballon, un seul ecouteur qui gere n'importe quelle situation !

Tu as donc un objet qui garde en mémoire tous tes ballons en utilisant pour clef leur valeur 'name' (qui doit être un String), et la meme chose pour les numeros de tes ballons.

#43 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 26 August 2013 - 03:27 AM

Je dirais que c'est le premier pas vers les classes, ou la manière de penser logiquement la structure du programme peu importe le nombre d'objets. Mais je ne sais pas si ce n'est pas encore un peu tôt pour tout ça, pour le moment il serait bien de finir un jeu complétement fonctionnel avec des méthodes simples et classiques, puis une fois que tout marche on réfléchis à comment tout optimiser et mieux structurer l'ensemble.

#44 tlecoz

  • Honoris
  • PipPipPipPipPipPipPipPip
  • 3486 messages

Posté 26 August 2013 - 12:23 PM

Désolé de mettre mon grain de sel et d'aller à contre-courant mais je n'ais jamais vraiment compris pourquoi on apprenait les classe aprés avoir appris tout le reste.

Les classes permettent de structurer une application, de regrouper les traitement par module autonome... Je trouve cela beaucoup plus clair comme mode de pensée qu'un projet non orienté objet.

D'autant plus que tout fonctionne à base d'objet donc de classe en AS.

Pour moi en tout cas, le jour ou on m'a appris à écrire des classes, ça a été une véritable révélation Image IPB

Le fait de pouvoir coder avec FlashDevelop et donc de profiter de l'auto-complétion est un énorme plus non négligeable et facilite beaucoup l'apprentissage du langage (parce qu'au travers de l'auto-complétion, on découvre les mots clé associés à chaque objet sans avoir besoin de lire la doc)

Je ne comprend pas bien pourquoi Spi parle de méthode "simple et classique" pour parler de projet sans classe. Je n'ai pas l'impression que coder avec des classes soit plus compliqué (je pense l'inverse) ; quand au mot 'classique' je trouve qu'il va bien aux 'classes' Image IPB

Le débat est ouvert ! Image IPB

EDIT : Ce qu'il y a de bien avec les classe, c'est qu'en cas d'erreur, on sait immédiatement ou se trouve le probleme. Par exemple, on te dirait "il y a un problème dans la classe Ballon, à telle ligne".
Contrairement à un projet sans classe qui te dira seulement la ligne approximative et qui te laissera chercher d'ou vient vraiment le problème. Puisque tout est décomposé en module (classe) , quand un problème survient, il survient dans un module précis (dans notre cas, la classe Ballon). On peut alors tenter de corriger l'objet Ballon sans risquer de casser le reste du code car il est physiquement séparé (dans le sens ou il se trouve dans d'autres fichiers) du reste du code

#45 Monsieur Spi

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 7017 messages

Posté 26 August 2013 - 14:50 PM

Hello,

Citation

Désolé de mettre mon grain de sel et d'aller à contre-courant mais je n'ais jamais vraiment compris pourquoi on apprenait les classe aprés avoir appris tout le reste.

Bah moi ça me semble normal, tout dépend de ce que tu entend par "tout le reste", disons que apprendre à se servir des bases (syntaxe, variables, tableaux, boucles, fonctions et début de structure) me semble indispensable avant de se lancer dans quelque chose de plus élaboré (qui ne veut pas forcément dire plus complexe). Si on prend le bouquin de T. Imbert, les classes et la programmation orientée objet ça commence au chapitre 8, avant on a tout le reste : API, bases du langage, mode événementiel, liste d'affichage, symboles, programmation événementielle, interactive. Or quand je vois quelqu'un s'attaquer à écrire des classes sans jamais avoir utilisé un simple tableau, je me dis que c'est mettre la charrue avant les bœufs, il y a d'autres choses à comprendre avant.

Citation

Les classes permettent de structurer une application, de regrouper les traitement par module autonome... Je trouve cela beaucoup plus clair comme mode de pensée qu'un projet non orienté objet.

Oui tu as raison, mais avant de penser à structurer convenablement en orienté objet il faut savoir écrire un programme, or il me semble plus simple d'apprendre à écrire un petit programme de quelques lignes en procédural, enfin ce n'est que mon avis, mais il ne me semble pas qu'on commence tout de suite par les classes.

Citation

Je ne comprend pas bien pourquoi Spi parle de méthode "simple et classique" pour parler de projet sans classe. Je n'ai pas l'impression que coder avec des classes soit plus compliqué (je pense l'inverse) ; quand au mot 'classique' je trouve qu'il va bien aux 'classes' Image IPB

Parce que pour moi il est plus simple, sur de petits programmes d'une centaine de lignes, de tout avoir sous les yeux pour voir comment ça fonctionne d'un bloc de manière séquentielle, plutôt que de me repérer dans une structure plus abstraite et éclatée. Ce que j'entends par là c'est qu'un petit jeu tout simple peut se traiter en une centaine de lignes de codes avec quelques déclarations de variables, deux fonctions et trois boucles, ou à contrario étalé sur parfois 500 ou 800 lignes voire plus avec des répétitions dans tous les sens et un code lourd, et à ce moment là faire des classes ne changera rien au problème, un truc mal codé que ce soit en POO ou procédural restera un truc mal codé. Coder avec les classes n'est pas plus compliqué, c'est juste une manière de penser différente, qui déroute beaucoup de débutant (alors que c'est celle qui se rapproche le plus de notre mode de pensée, tandis que le procédural se rapproche de la manière de penser de la machine et donc plus complexe sur de gros projets), moins évidente que de poser juste une fonction sur un calque. Quand au "classique" on a tous commencé à apprendre à coder en procédural, toi aussi d'ailleurs puisque tu dis que lorsqu'on t'as appris à écrire des classes ça a été une révélation, mais pour que ça en soit une il fallait bien que tu ait les bases pour comprendre pourquoi ça rendait toute la logique plus claire.

Ensuite personne ne remet en question l'aspect pratique, clair et structuré de la POO et des classes, je pense qu'on est tous d'accord là dessus, mais ce n'est généralement pas ce qu'on apprend en premier quand on débute. Image IPB



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)