Category: bases_programmation

  • 🤖Bases de la Programmation : Mise en page du code

    La mise en page de votre code doit suivre certaines régles :

    Le nesting

    quand un code est contenu dans des balises {} il faut ajouter une tabulation à toute ses lignes. Plus le code est “profond” c’est à dire utilisé dans des balises qui sont elles meme dans des balises {{}} plus on ajoute de tab

    Exemple d’une mauvaise mise en page :

    function substract_to_zero(_number_A,_number_B){
    const substraction = _number_A - _number_B
    if (const < 0){
    return 0
    }
    return substraction
    }

    Tout est aligné et il est difficile de déterminer où s’arrêtent et commencent les balises

    function substract_to_zero(_number_A,_number_B){
      const substraction = _number_A - _number_B
      if (const < 0){
        return 0
      }
      return substraction
    }

    Si on applique la règle des tab alors on distingue beaucoup mieux les ensembles et sous ensembles du code.

    Il est également conseillé de construire la logique de son code de manière à limiter les sous ensembles

    Evitez de :

    • Déclarer des fonctions dans des fonctions dans des fonctions
    • Imbriquer beaucoup de if(if(if()))

    Essayons de diminuer le “nesting” de cette fonction qui filtre des nodes selon 3 conditions :

    // on cherche un read avec le mots clef '_B' et dont l'attribu "POSITION.X" est suppérieur à 20
    
    const snode= selection.selectedNode(0)
    
    function is_what_we_want(_node){
      if(node.type(_node)=="READ"){
          // de type "READ"
          if(node.getName(_node).indexOf("_B")!=-1){
            // a le _B dans son nom
            if(node.getTextAttr(_node,"POSITION.X",0)>20){
              // c'est bien ce qu'on cherche ! 
              return true
            }
          }
      }
      
      // toute les conditons n'ont pas été remplies
      return false
    }
    
    
    MessageBox.information(is_what_we_want(snode))
    

    Ce code a un peu une sorte de scoliose non ?

    Ce genre de code devient de plus en plus dure à lire à force de rajouter des conditions

    Deux solution au “nesting”:

    1 utiliser une syntaxe booléenne : on concatène nos conditions en une seul syntaxe booléenne , c’est concis mais un peu dur à lire

    // on cherche un read avec le mots clef '_B' et dont l'attribu "POSITION.X" est suppérieur à 20
    
    const snode= selection.selectedNode(0)
    
    function is_what_we_want(_node){
    
      // on stock les conditions dans des variables 
      var is_read = node.type(_node)=="READ"
      var as_kw = node.getName(_node).indexOf("_B")!=-1
      var pos_20 = node.getTextAttr(_node,"POSITION.X",0)>20
      
      // on test d'un coup si elles sont toutes vrais avec l'opérateur &&
      return is_read && as_kw && pos_20
      
    }
    
    
    MessageBox.information(is_what_we_want(snode))

    2 inverser les conditions : au lieu de vérifier si une condition est “true” on vérifie si l’inverse de la condition est “true”. De cette manière on return très tôt dans la fonction. Si l’inverse est true pas besoin d’aller plus loin…

    // on cherche un read avec le mots clef '_B' et dont l'attribu "POSITION.X" est suppérieur à 20
    
    const snode= selection.selectedNode(0)
    
    function is_what_we_want(_node){
    
      if(node.type(_node)!="READ"){
        // n'est PAS de type read !
        return false
      }
      
      if(node.getName(_node).indexOf("_B")==-1){
        // n'a PAS '_B' dans son nom
        return false
      }
    
      if(node.getTextAttr(_node,"POSITION.X",0)<=20){
        // POSITION.X est INFERIEUR ou égale à 20 
        return false
      }
      // tout les obstacles sont franchi ! ce node est bien celui qu'on cherche
      return true
    }
      
    
    MessageBox.information(is_what_we_want(snode))
  • 🤖Bases de la Programmation : Les Mots Clefs : For loop

    Les for loop sont présents dans quasiment tout les scripts Harmony. Le role du for loop est de faire “boucler” le bloc de code entre {} un certain nombre de fois.

    On s’en sert typiquement pour exécuter un bloc de code sur chaque élément d’une array.

    Ecrivons un script qui met la position en Z de tout les nodes sélectionnés à 0

    On pourrait écrire une première version du code comme ceci :

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    
    set_z_to_zero(snodes[0])
    set_z_to_zero(snodes[1])
    set_z_to_zero(snodes[2])
    set_z_to_zero(snodes[3])
    set_z_to_zero(snodes[4])
    set_z_to_zero(snodes[5])
    set_z_to_zero(snodes[6])
    

    Le problème avec ce code c’est qu’il ne fonctionnera que si l’utilisateur n’a sélectionné précisément que 7 nodes. Il faudrait un code qui fonctionne avec 0 ou plusieurs nodes sélectionnés .

    On pourra améliorer le code comme ceci :

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    
    var index = 0
    // on test si l'index existes dans l'array  snode : 
    if(typeof arrayName[index] !== 'undefined'){
      // il y a un node à cet index on peut lui appliquer la fonction 
      set_z_to_zero(snodes[index ])
    }
    // on incrémente l'index -> 1
    index+=1
    if(typeof arrayName[index] !== 'undefined'){
      // il y a un node à cet index on peut lui appliquer la fonction 
      set_z_to_zero(snodes[index ])
    }
    // on incrémente l'index -> 2
    index+=1
    if(typeof arrayName[index] !== 'undefined'){
      // il y a un node à cet index on peut lui appliquer la fonction 
      set_z_to_zero(snodes[index ])
    }
    // on incrémente l'index -> 3
    index+=1
    if(typeof arrayName[index] !== 'undefined'){
      // il y a un node à cet index on peut lui appliquer la fonction 
      set_z_to_zero(snodes[index ])
    }
    // on incrémente l'index -> 4
    index+=1
    if(typeof arrayName[index] !== 'undefined'){
      // il y a un node à cet index on peut lui appliquer la fonction 
      set_z_to_zero(snodes[index ])
    }
    

    C’est un peu mieux, l’utilisateur peut maintenant sélectionner entre 0 et 5 nodes et le code ne crash pas car on test à chaque foi si l’index existe.

    ça fonctionne, mais Normalement vous devriez ressentir une sorte de profond désarroi esthétique en voyant ce code.

    Il faudrait que l’utilisateur puisse selectionner autant de nodes qu’il souhaite

    Essayons avec le mots clé while.

    Le mots-clé while exécute un bloc de code tant qu’une proposition booléenne est vrais. Comme dans un if, la proposition booléenne ou condition se trouve entre parenthèses après le while.

    while ( a < b ) {}

    Si dans votre description du code vous utilisez le mots “tant que” il est fort probable que vous utiliserez le mots clef “while”

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    // on commence à l'index 0 de l'array 
    var index = 0
    // tant que l'index n'est pas égal au dernier index ( nombre d'élément dans l'array -1 )
    while (index < snodes.length-1){
      // on applique la fonction
      set_z_to_zero(snodes[index ])
      // on augment l'index pour passer à l'élément suivant
      index+=1
    }
    

    On gagne tout de suite un peu d’espace mais ça fait encore pas mal de lignes.

    Personnellement je déconseille l’utilisation du mots-clé while car si il y a une erreur dans la condition le code peut facilement boucler à l’infini.

    Ce code par exemple comptera jusqu’à l’infini (enfin jusqu’à ce que Harmony crash)

    // a ne pas utiliser sauf si vous voulez faire crasher harmony biensur ! 
    var limit = 100
    var number = 0
    while(limit < 200){ // cette condtion est toujours true car limit ne change pas !
      number+=1
      MessageLog.trace(number)
    }
    // la partie du code qui ne sera jamais exécutée car on se sortira jamais de cette boucle while
    MessageLog.trace("code finito!")

    le mots-clé for

    Pour palier aux defaults du while: le for nous permet de boucler mais d’une manière plus contrôlée ! voici sa syntaxe :

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    // on retrouve le code du while mais à l'horizontale : 
    for(var index = 0 ; index < snodes.length ; index++){ 
      set_z_to_zero(snodes[index])
    }
    

    On ne peut pas faire plus concis ! 3 lignes

    Néanmoins cette syntaxe devrait vous perturber un peu :

    des “;” dans des parenthèses ? c’est une sorte de micro code ?

    Qu’est ce qui se passe dans ces parenthèses ?

    Pour comprendre un for Loop il faut bien comprendre les trois blocs contenus dans ses parenthèses ()

    • Bloc Initialisation : on déclare une variable d’index ( souvent i ) et on lui attribue une valeur de départ ( souvent 0 ) . C’est une déclaration de variable normale vous pouvez lui donner le nom et la valeur que vous voulez.
    • Bloc Condition : fonctionne comme un while , si la condition est true on exécute le code dans le bloc d’exécution ainsi que celui contenu entre les {}
    • Bloc Exécution : une ligne de code à exécuter quand la condition est true. Dans 99% des cas le code exécuté incrémente l’index (i++)

    On commence par l’initialisation puis on exécute le 3eme bloc et le code entre {} tant que la condition du deuxième bloc est true !

    Quelques exemples de ce qu’on peut trouver dans les parenthèses

    InitialisationCondition Exécution
    (var index = 0 ;index < 10;index++)
    (var i = 0 ;i < arr.length;i++)
    (var s = 0;s < snodes.length;s++)
    (var j = arr.length-1;j >= 0;j–)

    Comportement de chaque parenthèses

    for 1—> exécute le code 10 fois
    for 2—> exécute le code pour chaque élément de l’array
    for 3—> exécute le code pour chaque node sélectionné
    for 4—> exécute le code pour chaque node sélectionné du dernier au premier

    Je vous conseille de tester le code suivant pour bien comprendre le comportement des différents for loop :

    const snodes = selection.selectedNodes()
    
    // executer le code X fois 
    const X = 10
    for(var i = 0; i < X  ; i++){
      MessageLog.trace(i)
    }
    
    // parcourir une array en commençant le premier element [0]
    for(var i = 0 ; i < snodes.length ; i++){
      MessageLog.trace(i)
      MessageLog.trace(snodes[i])
    }
    
    // parcourir une array en commençant par le dernier element [length-1] et en comptant à rebourt i--
    for(var i =  snodes.length-1 ; i >= 0 ; i--){
      MessageLog.trace(i)
      MessageLog.trace(snodes[i])
    }
    

    Court-circuiter la boucle : continue et break

    Et si le node selectionné courant snodes[i] n’est pas un PEG ? Si, par exemple il est de type ‘COMPOSITE’

    Cela ne nous intéressera pas de changer sa position en Z car il n’en a pas. Donc nous risquons de perdre une boucle pour rien, et donc de gaspiller des ressources en calcul.

    Comment pourrait-on “sauter” cette boucle ?

    Comment pourrait-on et passer à la boucle suivante si le node n’est pas de type ‘PEG’ ?

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    
    
    for(var index = 0 ; index < snodes.length ; index++){
      if(node.type(snodes[i])!="PEG"){
        // ce n'est pas un peg 
      }
      // essaye quand meme de changer son Z ? 
      set_z_to_zero(snodes[index])
    }
    
    

    Le mots-clé “continue”

    Le mots clé continue dis à l’ordinateur ‘pas besoin de lire les lignes suivante , passe à la boucle suivante avec une nouvelle valeur d’index (i+1)’ ‘pioche une nouvelle carte’

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    
    for(var index = 0 ; index < snodes.length ; index++){
      // est ce que c'est un peg ? 
      if(node.type(snodes[i])!="PEG"){
        // ce n'est pas un PEG passe à la boucle suivante !
        continue
      }
      // c'est un peg tu peux executer la suite du code de la boucle 
      set_z_to_zero(snodes[index])
    }
    

    continue est très puissant pour optimiser un scripte. Il vous entraine aussi à bien définir les cas où il est utile d’exécuter une ligne ou non.

    Si maintenant j’écris un for loop qui cherche quelque chose. Mettons le premier node dans la sélection qui contient la chaîne de charactères : “HEAD” si je veux trouver le node de la tête dans un rig.

    const snodes = selection.selectedNodes()
    
    var found_node = ""
    
    for(var index = 0 ; index < snodes.length ; index++){
      const node_name = node.getName(snodes[i])
      if(node_name.indexOf("HEAD")!=-1){
        // on a trouvé un node avec HEAD ! on peut ranger son chemin dans la variable 'found_node'
        found_node = snodes[i]
      }
      // on continue à chercher meme si on a dit qu'on en voulait qu'un seul 
    }

    Ce code n’est pas très optimal ! est ce que vous comprenez pourquoi ?

    Imaginons un pirate qui parcourt une liste de 4 îles pour retrouver son trésor oublié. Imaginons qu’il trouve son trésor dans la deuxième île mais qu’il continue quand même à chercher dans les îles 3 et 4 pour voir si le trésor qu’il vient de trouver ne s’y trouve pas… (oui c’est un pirate fou).

    Eh bien ce code se comporte un peu comme le pirate. Il parcourt tout les nodes, même si il a trouvé celui qu’il cherchait.

    Il faudrait trouver un moyen de lui dire d’arrêter de chercher :

    c’est le mots-clé break

    const snodes = selection.selectedNodes()
    
    var found_node = ""
    
    for(var index = 0 ; index < snodes.length ; index++){
      const node_name = node.getName(snodes[i])
      if(node_name.indexOf("HEAD")!=-1){
        found_node = snodes[i]
        // on a trouvé le node ! tu peux t'arrêter là ! 
        break 
      }
    }

    Le mots-clé break permet de sortir de la boucle

    Quand l’ordinateur rencontre le mots-clé break dans une boucle il saute directement après le } de la boucle et lit les lignes suivantes du programme. On gagne ainsi en temps d’exécution ! surtout si quantité parcourue est grande.

    La Notation condensée ‘for in’

    il est possible d’écrire une boucle qui parcourt une array avec une syntaxe encore plus condensée :

    for ( var i in my_array ) {}

    Avec ce que nous venons de voir vous devriez comprendre ce que fait le code suivant

    const snodes = selection.selectedNodes()
    
    function set_z_to_zero(_node){
      node.setTextAttr(_node,"POSITION.Z",frame.current(),0)
    }
    
    
    for(var index in snodes){
      set_z_to_zero(snodes[index])
    }
    

    Exactement la même chose qu’avec un for loop classique !

    Attentions cette notation est trompeuse car beaucoup de choses sont implicites :

    Ce code parcourt l’array en commençant par l’index 0 et en incrémentant de 1 jusqu’a la fin de l’array.

    Cette notation condensée existe car c’est le type de for loop qu’on utilise dans la grande majorité des cas avec une array. Pas besoin d’écrire .length ou i++ : tout est inclu dans le “in” , mais ses possibilités sont limitées !

  • 🤖 Bases de la Programmation : Les Variables de type “bool”

    les variables de type bool ou booléennes sont le type le plus simple en informatique puisqu’elle ne peuvent avoir que deux valeurs : TRUE ou FALSE ( 0 ou 1 )

    Ce type sert principalement à faire des comparaisons. Ces comparaisons s’écrivent sous une forme qu’on appel synthaxe booléenne.

    Si vous aimez les phrases avec des doubles négations, vous n’allez pas ne pas adorez les valeur booléennes.

    Déclaration :

    var my_bool = true
    MessageBox.information(my_bool) 
    // affiche true
    
    var my_bool = false
    MessageBox.information(my_bool) 
    // affiche false

    Les opérateurs booléens

    OpérateurSymbole
    EST ( égale à ) ==
    N’EST PAS ( différent de ) !=
    ET ( au moins 1 false ? ) = true&&
    OU ( au moins 1 true ? ) = true||
    EST SUPERIEUR A >
    EST INFERIEUR A <
    INFERIEUR OU EGAL A <=
    SUPERIEUR OU EGAL A >=
    const A = true
    const B = false
    
    var result = A == B 
    MessageBox.information(result ) 
    // affiche false , true n'est pas égale à false
    
    result = A != B 
    MessageBox.information(result ) 
    // affiche true , true est bien 'pas égal' à false
    
    result = A == A 
    MessageBox.information(result ) 
    // affiche true , true est bien à true
    
    result = A != A 
    MessageBox.information(result ) 
    // affiche true , true n'est pas 'pas égal' à true
    
    result = A && B 
    MessageBox.information(result ) 
    // affiche false , au moins une valeur (B) est false
    
    result = A && A 
    MessageBox.information(result ) 
    // affiche true aucune valeur n'est false
    
    result = A || B 
    MessageBox.information(result ) 
    // affiche true au moins une valeur (A) est true
    
    result = B || B
    MessageBox.information(result ) 
    // affiche false aucune valeur n'est true
    
    

    Comparer des valeurs autre que booléennes :

    Les opérateurs booléens permettent de comparer tout un tas de combinaisons de variables.

    result = 10 == 5
    MessageBox.information(result ) 
    // affiche false 10 n'est pas égal à 5
    
    result = (2 + 2 )== 5
    MessageBox.information(result ) 
    // affiche false 4(2+2) n'est pas égal à 5
    
    result =(2 + 2 ) != 5
    MessageBox.information(result ) 
    // affiche true 4(2+2) est bien différent de 5
    
    
    
    // comparaisons de quantités : 
    
    result  =  3 < 5
    MessageBox.information(result ) 
    // affiche true 
    
    result  =  10 < 5
    MessageBox.information(result ) 
    // affiche false
    
    
    // comparaisons de string : 
    
    result = "A" == "A"
    MessageBox.information(result ) 
    // affiche true la string "A" est identique à "A"
    
    result = "abcd" == "xyz"
    MessageBox.information(result ) 
    // affiche false les deux string ne sont pas égales 
    
    
    

    MAIS A QUOI ça sert ???

    La syntaxe booléenne va être extrêmement utile lorsque nous allons utiliser les mots if et else

    nodes = selection.selectedNodes()
    if (nodes.length < 1 ){
      MessageBox.information("veuillez selectionner au moins 1 node ) 
    }

    C’est avec les propositions booléennes qu’on va pouvoir créer des conditions à vérifier et structurer toute l’arborescence conditionnelle du code

  • 🤖 Bases de la Programmation : Les Variables de type ‘object’

    Les objets sont comme des tableaux, mais des tableaux un peu spéciaux car leur ligne peut aussi contenir des tableaux. C’est un type très très utile pour stocker des données et les manipuler toutes ensembles. Les objets repose sur un systeme de “clef:valeur,” exactement comme dans un tableau à deux colonnes.

    Si vous voulez vous créer une ficher perso D&D c’est le type de variable qu’il vous faut :

    Les objets simples :

    Mettons qu’on veuille créer un nouveau personnage avec des stats de base

    NomMonToutou
    RaceLabrador
    Force100
    Agilité10
    Cri “ouaf”

    On peut traduire le tableaux ci dessus en déclarant une variable de type Object

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      force:100,
      agilité:10,
      cri:"ouaf"
    }

    Dès la déclaration d’un object on peut définir sa structure. Vous remarquerez que les données de l’objet sont contenu dans des balises {} comme pour les fonctions.

    • pour séparer “les colonnes du tableau” on utilise le symbole “:”
    • pour séparer les “lignes du tableau” on utilise “,”

    Afficher une valeur de l’objet :

    une foi l’objet déclarer on va pouvoir acceder à ce qu’on appel ses propriétés ou attribus par l’intermédiaire de “.”

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      force:100,
      agilité:10,
      cri:"ouaf"
    }
    
    MessageBox.information(perso.nom) 
    // affiche MonToutou
    
    
    MessageBox.information(perso.agilité) 
    // affiche 10
    
    MessageBox.information(perso.cri) 
    // affiche ouaf

    On peut également acceder à la valeur d’une clef de l’objet en utilisant la synthaxe suivante :

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      force:100,
      agilité:10,
      cri:"ouaf"
    }
    
    MessageBox.information(perso["nom"]) 
    // affiche MonToutou
    
    
    MessageBox.information(perso["agilité"]) 
    // affiche 10
    
    MessageBox.information(perso["cri"]) 
    // affiche ouaf

    Modifier l’objet :

    Pour modifier la valeur d’une clef d’ un objet ajoute le signe = devant la clef que l’on veut modifier comme pour modifier une variable simple :

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      force:100,
      agilité:10,
      cri:"ouaf"
    }
    
    MessageBox.information(perso["nom"]) 
    // affiche MonToutou
    
    // modification de la valeur de la clef "cri" 
    perso.cri = "miaou"
    
    MessageBox.information(perso.cri) 
    // affiche miaou

    Les objets complexes :

    Les objets complexes sont des objets qui contiennent eux même des objets

    On pourrait décomposer notre fiche perso en deux tableaux

    TABLEAU_A :

    NomMonToutou
    RaceLabrador
    Statistiquesvoir tableau b
    Cri “ouaf”

    TABLEAU_B

    Force100
    Agilité10

    le tableau A contient le tableau B

    On déclare cet objet comme ceci :

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      statistiques:{
        force:100,
        agilité:10,
      },
      cri:"ouaf"
    }
    

    Pour afficher la clef “force” mainenant nous allons devoir passer par “statistiques”

    // declaration 
    var perso = {
      nom:"MonToutou",
      race:"Labrador",
      statistiques:{
        force:100,
        agilité:10,
      },
      cri:"ouaf"
    }
    
    MessageBox.information(perso.statistiques.force) 
    // autre synthaxe
    MessageBox.information(perso["statistiques"]["force"]) 

    Le format JSON

    Le format json est un type de fichier qui permet de sauvegarder des objets

    Vous devriez reconnaitre ici le format des master controller : le tbstate

    Un tbstate est un objet complexe !

  • 🤖 Bases de la Programmation : Les Variables de type “array”

    Le type array fait partie , avec le type ‘object’, des types de variables “composées”

    Ces variables qui contiennent d’autres variables.

    Les array sont des listes de variables avec un numéro appelé “index”. On déclare la valeur d’une array en mettant une série de valeurs séparées par des “,” entre parenthèses “[]”.

    Declaration d’une Array

    var my_array = ["A","B","C"]
    

    Une array peut contenir plusieur type de valeurs :

    var my_array = [10,"B",true]
    

    Appel d’une array simple

    var my_array = ["A","B","C"]
    MessageBox.information(my_array) 
    // affiche A,B,C

    Appel d’une array avec index : Les array sont comme des immeubles. Chaque étage contient une valeur qu’on appel en l’appelant un certain “index” de l’array (numéro de l’étage). Comme dans les ascenceur on commence par 0 pour la première valeur 1 pour le deuxieme ect… on appel un index ajoutant [index] après le nom de la variable.

    var my_array = ["A","B","C"]
    MessageBox.information(my_array[0]) 
    // affiche A
    MessageBox.information(my_array[1]) 
    // affiche B
    MessageBox.information(my_array[2]) 
    // affiche C

    Cette “valeur d’étage” peut aussi être une variable de type “int”

    var my_array = ["A","B","C"]
    var etage = 1
    MessageBox.information(my_array[etage]) 
    // affiche B

    Obtenir le nombre d’éléments : Array.length

    Pour afficher le nombre d’éléments dans une array on utilise une propriété native des array : “length”

    Pour acceder à une propriété d’une variable on utilise son nom , suivi d’un “.” suivi du nom de la propriété :

    var my_array = ["A","B","C"]
    MessageBox.information(my_array.length) 
    // affiche 3 , car il y a 3 éléments dans la liste

    Modifier une Array

    Pour ajouter un élément à la fin de l’array on utilise la méthode native “push”

    On accède à une méthode native comme à une propriété via le “.” . Une méthode se comporte comme une fonction et donc il faudra lui passer des arguments, dans le cas de push : la valeur à ajouter.

    var my_array = ["A","B","C"]
    my_array.push("D")
    MessageBox.information(my_array)  
    // affiche A , B , C , D 

    On peut également ajouter un élément au début de l’array avec la méthode “shift”

    var my_array = ["A","B","C"]
    my_array.shift("D")
    MessageBox.information(my_array)  
    // affiche  D , A , B , C 

    Plus de details sur les méthodes d’array ici :

    https://www.w3schools.com/js/js_arrays.asp

  • 🤖 Bases de la Programmation : Les Variables de type “string” part 1

    Les string sont des chaines de charactères. En informatique, un charactère est un symbole graphique avec un code spécial. Il peut s’agir d’une lettre, d’un chiffre ou même d’un émoticône. La plupart des touches du clavier correspondent à un charactère ou “char”.

    👉 Une string est donc une liste de char. C’est LE type qui s’occupe de tout ce qui est valeurs textuelles en programmation.

    Déclarer une string

    On déclare une valeur string en mettant une serie de charactère entre guillemets. Ces guillemets sont là pour dire à l’ordinateur qu’il s’agit d’une valeur et non d’instructions de code. C’est exactement l’usage qu’on en fait lorsque qu’un personnage parle dans un roman. On utilise les guillemet pour distinguer la voix du narrateur de celle du personnage qui parle.

    var my_string = "bonjour"
    MessageBox.information(my_string)
    // affiche bonjour

    L’opérateur +

    On peut combiner des string entre elles grâce à l’opérateur + comme ceci :

    var my_string = "bonjour "
    var ville= " angouleme" 
    var phrase= my_string + ville
    MessageBox.information(phrase)
    // affiche bonjour angouleme 
    

    En javascript le type string est “contagieux” . C’est à dire qu’il convertit tout ce qu’on lui additionne en type string

    var my_string = "abdc"+
    var my_int = 123
    MessageBox.information( my_string + my_int )
    // affiche abcd123 my_int a été traité comme une string 
    
  • 🤖 Bases de la Programmation : Les Variables de type ‘int’ et ‘float’

    🔢 INT

    Les variables avec des valeurs de type int ou “integer” contiennent des nombres entiers : 0,1,2,3,4,5…999999 donc des valeurs numériques sans décimales

    Ces variables peuvent être combinées entre elle avec les opérateurs mathématiques que l’on connait

    opérationsymbole dans le code
    addition+
    soustraction
    multiplication*
    division/
    modulo (reste de la division)%

    const A = 4 
    const B = 2
    
    var result = A + B
    MessageBox.information(result)
    // affiche 6
    
    var result = A - B
    MessageBox.information(result)
    // affiche 2
    
    var result = A * B
    MessageBox.information(result)
    // affiche 8
    
    var result = A / B
    MessageBox.information(result)
    // affiche 2
    
    var result = A % B
    MessageBox.information(result)
    // affiche 0
    
    // comme en math on peut également utiliser des parenthèses :
    var result = ( A + B ) * B 
    MessageBox.information(result)
    // affiche 12

    💲FLOAT

    Les variables avec des valeurs de type float contiennent des nombres décimaux :

    1.5 30.459 0.9999 ( on n’utilise pas le symbole “,” mais “.” comme les anglais)

    Ces variables peuvent être combinées entre elle avec les mêmes opérateurs mathématiques que les valeurs de type int.

    Exercices

    https://github.com/TBScriptingFormateur/FormationScriptingHarmony/blob/main/exercices/bases_variables_int_float.js

  • 🤖 Bases de la Programmation : Les Classes

    Les Classes sont aux fonctions ce que les objets sont aux variables simples : une classe est un groupement de fonctions appelées “méthodes” et de variables appelées “propriétés”. C’est un mélange entre une fonction ( avec des arguments ) et un objet (fonctionnement en clef valeur accessible par des . )

    Lorsque que vous utilisez l’api Harmony vous ne faites qu’utiliser des classes.

    Déclarer une classe

    Hors des script harmony nous avons droit d’utiliser le mots clef class

    class my_class(){
    
    }

    mais dans harmony le mots clef class est interdit et nous sommes contraints d’utiliser le mots clef function à la base. Le resultat est le même mais cela peut vraiment prêter à confusion au début.

    Avec l’exemple suivant , pouvez vous comprendre à quoi sert une classe ?

    function Animal(_type,_sound ){
      this._type= _type
      this._sound = _sound 
      this.make_sound= function(){
        MessageBox.information(this._sound )
      }
      this.talk= function(){
        MessageBox.information("Hello ! i'm a "+this._type)
      }
    }
    
    var medor = new Animal("dog","ouaf")
    medor.talk()
    // affiche hello ! i'm a dog 
    medor.make_sound()
    // affiche ouaf
    
    var mimi = new Animal("chat","miaou")
    mimi .talk()
    // affiche hello ! i'm a cat
    mimi .make_sound()
    // affiche miaou
    
    
    

    On voit deux nouveaux mots clefs “this” à l’intérieur de la déclaration et “new”

    new permet d’instancier une classe. Instancier une classe revient à créer une copie de la classe en suivant son plan et à reset tout ses propriétés.

    Une instance est comme objet sauf qu’elle est unique, elle va pouvoir avoir ses propres valeurs de propriétés et évoluer le long du code. C’est typiquement comme cela que l’on code le comportement d’un enemie dans un jeux.

    function Enemy(_name,_hitpoints,_damage) {
        this._name = _name
        this._hp = _hitpoints
        this._damage = _damage
        this.attack = function(_player){
          _player.hitpoints -= this._damage
        }
    }

    L’état d’une instance peu changer au cour du temps si les méthodes de la classes le permettent

    function Human() {
        this._stomac =[]
        this.eat= function(_something){
          this._stomac.push(_something)
        }
    }
    
    var BlancheNeige = new Human()
    MessageBox.information(BlancheNeige._stomac)
    // affiche []
    
    BlancheNeige.eat("apple")
    MessageBox.information(BlancheNeige._stomac)
    // affiche ["apple"]

    Dans harmony

    lorsque l’on utilise “node” on fait appel à une instance de la classe Node qui propose tout un tas de méthodes pour manipuler les nodes

    MessageBox est AUSSI une classe

    enfait TOUT dans la doc toonboom est une classe.

    ToonBoom utilise les classes pour ranger ses functions par thème sous forme de méthodes.