Category: Cour

  • 🤖 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.

  • 🤖 Bases de la programmation : Les Fonctions

    Concept

    Le concept de fonction viens de la notation mathématique “f(x)” : pour représenter le resultat d’une modification d’une valeur abstraite “x” par une sérié d’opération (mutiliplication , addition ect … ) . Mais on peut aussi penser aux fonctions comme à des “verbes” dans un language. Certain verbes n’ont pas d’objets comme “dormir” et certain supposent un objet comme “manger qq”.

    On peut aussi voir les fonction comme des “tuyaux” dans lesquelles passent les valeurs du programme afin d’être transformées. Elles ont comme input les “arguments” et comme output une valeur de retour “return”.

    L’utilisation des fonctions n’est pas obligatoires pour qu’un programme fonctionne mais elles améliorent grandement son organisation et sa lisibilité.

    Déclaration

    La définition d’un verbe dans un dictionnaire est très proche d’un code de déclaration de fonction.

    Déclarer une fonction signifie décrire son comportement. C’est son “plan d’action” sous forme de code . Le code contenu entre les balises {} sera exécuté au moment de son “appel”.

    function sayhello() {
       MessageLog.trace("hello")
    }

    Appel

    Pour appeller une fonction et executer son code il suffit d’écrire son nom suivi de parenthèses ()

    
    function sayhello() {
       MessageLog.trace("hello")
    }
    
    sayhello()
    sayhello()
    sayhello()
    
    // affiche 
    // hello
    // hello 
    // hello 

    Fonctions avec argument

    Les fonctions avec argument ont pour but de “faire quelque chose” avec une variable. Au moment de la déclaration on ne connais pas la valeur de la variable qui va être transmise alors on utilise une abstraction. Quelque chose qui peut varier mais dont le contenu est globalement prévisible comme “aliment” ou “fruit” si on veut parler d’une fonction “manger” par exemple.

    Comme dans une définition de dictionnaire où l’on précise qu’un verbe attends une certains catégorie de mots après lui : parler_à(quelqu’un)

    Plus simplement : lorsque l’on défini un argument on défini les “input” de la fonction un peu comme les inports d’un groupe dans la nodeview

    
    function say(_word) {
       MessageLog.trace(_word)
    }
    say("bonjour")
    // affiche : 
    // bonjour
    
    function manger(_aliment) {
       MessageLog.trace(" je mange "+_aliment)
    }
    
    manger("une pomme")
    // affiche : 
    // je mange une pomme 
    
    
    function stand_up_introduction(_word,_city) {
       MessageLog.trace("HEY ")
       MessageLog.trace(_word)
       MessageLog.trace(_city)
       MessageLog.trace("!")
    }
    
    stand_up_introduction("bonjour","toulouse")
    
    // affiche :
    // HEY 
    // bonjour
    // toulouse
    // !
    

    Fonctions avec valeur de retour

    Les fonctions avec valeur de retour vont pouvoir donner une valeur lorsqu’elle sont appelées : Dans cet example la fonction se comporte comme une valeur qu’on transmet à la variable “test”

    function myfunc() {
       return "ma_valeur_de_retour"
    }
    
    var test = myfunc()
    MessageLog.trace(test)
    // affiche ma_valeur_de_retour

    dans la déclaration on décide de la valeur que transmettra la fonction avec le mots clef “return” . C’est l’output de la fonction. Comme dans un groupe dans la nodeview c’est son port out, à la différence qu’une fonction ne peut avoir qu’un seul output.

    On peut biensur “retourner” une variable déclarée dans la fonction

    function myfunc() {
       var msg= "bonjour"
       return msg
    }
    
    var test = myfunc()
    MessageLog.trace(test)
    // affiche bonjour

    Avec les concepts d’argument et de return on peut maintenant écrire des petites fonctions mathématiques simples :

    function additionner(_A,_B) {
       var somme = _A + _B
       return somme
    }
    
    var resultat = additionner(2,2)
    MessageLog.trace(resultat)
    // affiche 4

    Fonctions Imbriquées

    On peut tout à fait appeler une fonction dans une déclaration de fonction

    function ajouter_flammes(_mots){
      return "🔥"+_mots+"🔥"
    }
    
    function dire_un_bonjour_en_feu_a(_prenom){
      var phrase = " bonjour "+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    var test= dire_un_bonjour_en_feu_a("le chat")
    MessageLog.trace(resultat)
    // affiche 🔥 bonjour le chat ! 🔥
    

    on peut également déclarer et appeler une fonction dans une fonction. Lorsque l’on veut décomposer le code d’une fonction complexe par exemple.

    On peut écrire le code ci dessus comme ce ci :

    
    // fonction principale
    function dire_un_bonjour_en_feu_a(_prenom){
      // sous fonction
      function ajouter_flammes(_mots){
        return "🔥"+_mots+"🔥"
      }
      
      var phrase = " bonjour "+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    var test= dire_un_bonjour_en_feu_a("le chat")
    MessageLog.trace(resultat)
    // affiche 🔥 bonjour le chat ! 🔥
    

    Le resultat est le meme. En revanche les autres fonctions n’auront plus acccès à “ajouter flammes” car elle est déclaré à l’interieur de “dir_un_bonjour_en_feu_a”

    Ce code ne fonctionnera pas :

    // fonction principale
    function dire_un_bonjour_en_feu_a(_prenom){
      // sous fonction
      function ajouter_flammes(_mots){
        return "🔥"+_mots+"🔥"
      }
      
      var phrase = " bonjour "+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    // fonction principale
    function dire_un_aurevoir_en_feu_a(_prenom){
      var phrase = " aurevoir"+_prenom+" ! "
      // CETTE FONCTION N'EST PAS VISIBLE D'ICI ! 
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    var test= dire_un_aurevoir_en_feu_a("le chat")
    MessageLog.trace(resultat)
    // affiche une erreur
    

    Pour que “aurevoir” et “bonjour” fonctionnent il faudra replacer “ajouter_flammes” à l’exterieur

    
    function ajouter_flammes(_mots){
      return "🔥"+_mots+"🔥"
    }
      
    
    function dire_un_bonjour_en_feu_a(_prenom){
      var phrase = " bonjour "+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    function dire_un_aurevoir_en_feu_a(_prenom){
      var phrase = " aurevoir"+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    var test= dire_un_aurevoir_en_feu_a("le chat")
    MessageLog.trace(resultat)
    // affiche 🔥 aurevoir le chat ! 🔥
    

    On pourrait encore décomposer nos fonction ainsi :

    function ajouter_char_des_deux_cotes(_mots,_char){
      return _char+_mots+_char
    }
    
    function ajouter_flammes(_mots){
      return ajouter_char_des_deux_cotes(_mots,"🔥")
    }
      
    
    function dire_un_bonjour_en_feu_a(_prenom){
      var phrase = " bonjour "+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    function dire_un_aurevoir_en_feu_a(_prenom){
      var phrase = " aurevoir"+_prenom+" ! "
      phrase = ajouter_flammes(_phrase)
      return phrase
    }
    
    var test= dire_un_aurevoir_en_feu_a("le chat")
    MessageLog.trace(resultat)
    // affiche 🔥 aurevoir le chat ! 🔥
  • 🛠️ Les outils de dev : Github DeskTop

    Git est un système de versioning de fichiers crée par Linus Thorvald . C’est un outil indispensable lorsque l’on veut faire du code en production. Il permet de garder une trace de chaque modification du code (commit , ou point de sauvegarde ) ainsi que de pouvoir gérer la collaboration entre plusieurs dev par un système de branches.

    Github est un site qui utilise le protocole git et permet de stocker du code dans le cloud.

    Github Desktop est une interface git simplifiée qui permet de synchroniser des fichiers locaux avec le cloud de github.



    Fonctionnement de Git


    Qu’est ce qu’un Repository ?

    • Un dossier versionné en cloud ( si on utilise github )
    • Le repos ‘origin’ est le dossier dans le cloud
    • Créer un repository sur github
    • Créer un clone du repository en local

    Qu’est ce qu’un Commit ?

    • Une modification reversible + un commentaire
    • Modifier un fichier du repos local et faire un premier commit
    • Push : on envoie le commit de notre repos local au repos origin
    • Pull : télécharger une mise à jour (commit) présente dans l’orgin vers notre répos local

    Qu’est ce qu’une Branche ?

    Une branche est une version paralelle du repository

    Le systeme de branche permet à plusieur dev de travailler en parallel sur le meme repository sans rentrer en conflit. Chacun créer sa branche , produit son code, puis l’envoie à la branche principale (‘master‘) via un “Pull request


    Pratique :

    • Formateur : Ajouter chaque élève en tant que collaborateur du repos “FormationScripting”
    • Créer un clone du repository en local
    • Créer une branche à son nom
    • Modifier le fichier ‘file_to_version.txt’
    • faire un commit puis un push

    Outils de dev

  • 🤖 Bases de la programmation : Les Variables : introduction

    Simplement dit : Une variable est un bout d’espace mémoire dans la RAM avec une adresse.

    👉 Si la RAM était un terrain constructible dont la surface correspond à sa mémoire disponible, les variables seraient comme les maisons que l’on construit sur ce terrain. Lorsque l’on déclare une variable on “réserve” une adresse dans la mémoire avec un nom. Ensuite dans le code ce nom fera référence au contenu de la variable : sa valeur. C’est un peu comme si , vous habitiez au “153 rue de paris” et que l’on faisait référence à vous comme “la personne qui au habite au 153 rue de paris“.

    Déclarer une variable : pour déclarer une variable en javascript on utilise le mots clé var suivi du nom de la variable, ici my_variable

    // on déclare l'adresse my_variable 
    var my_variable
    

    Pour assigner une valeur à une variable on utilise l’opérateur =

    var my_variable = 10
    // la valeur de my_variable est égale à 10
    
    

    Appeler une variable : une foi que la variable est déclarée et qu’une valeur lui a été assignée, il devient possible de l’appeler. Appeler une variable veut dire lire sa valeur. Pour appeler une variable il suffit d’écrire son nom. Par exemple en utilisant la fonction d’affichage d’Harmony on peut afficher le contenu de my_variable qui est égal à 10 plutot que d’afficher directement la valeur 10 :

    var my_variable = 10
    MessageBox.information(10)
    MessageBox.information(my_variable )
    // affiche 10 puis 10

    Changer la valeur d’une variable : pour cela il suffit de lui réassigner une nouvelle valeur avec le signe égal

    var A = 10
    A = 15
    
    MessageBox.information(A)
    // affiche 15

    On peut egalement à l’aide du signe égal transférer une valeur d’une variable à une autre :

    var A = 10
    var B = A
    
    MessageBox.information(A)
    MessageBox.information(B)
    // affiche 10 puis 10

    Attention à bien respecter l’ordre d’execution !

    var A = 10
    
    MessageBox.information(B)
    
    var B = 20
    
    // ce code renvoi une erreur car B est appelé AVANT d'être déclaré ! 

    Les Constantes :

    Il existe une deuxième type de variable qu’on nomme constante, qui, comme son nom l’indique ne peut pas changer. Si vous êtes sur qu’une variable va être seulement lue et jamais écrite au cour du code, il est intéressant de la déclarer en type constante car celui ci est plus légers à traiter pour le processeur (la maison prend moins de place..)

    Déclarer une constante :

    pour déclarer une constante on utilise le mots clé “const”

    const vitesse_de_la_lumiere = 299 792 458 // mettres par secondes
    
    // si on essaye de changer une constante
    vitesse_de_la_lumiere = 10
    
    // cela renvoie normalement une erreur ... 
    

    Les types de Valeurs :

    Il existe plusieurs type de valeurs : int , float , string , array , object

    Le type va déterminer comment les valeurs interagissent entre elles quand on les manipule avec des opérateurs ( + , – , * , / , % )

    L’opérateur + par exemple ne va pas du tout produire la même chose si on l’applique à des int ou à des string (chaînes de charactère)

    var A =1
    var B = 2
    var result = A+B 
    MessageBox.information(result )
    // affiche 3
    
    A = "1"
    B = "2"
    result = A+B 
    MessageBox.information(result )
    // affiche "12"

    Suite >>

  • ✨ API Harmony – Lire la doc

    L’API Harmony est un ensemble de classes mise à disposition par Toonboom pour permettre aux programmeurs d’interagir avec le logiciel. Ces classes sont comme déclarées avant l’exécution de notre scripte et nous pouvons les appeler dans notre code afin d’exécuter leur différentes méthodes.

    Chaque classe de l’api est décrite dans la documentation de scripting d’Harmony. On trouve également dans cette documentation quelque examples de code qu’on peut adapter à nos besoins.

    à gauche la liste des classes accessibles

    à droite la liste des propriétés et méthodes de la classe

    Pour appeler une méthode d’une classe écriver le nom de la classe suivi d’un “.” puis du nom de la méthode.

    Faites attentions à bien passer en argument à la méthode le type de variable décris dans la documentation : ici “String &node”

    var name = node.getName("Top/mynode")

    Pour chaque méthode est également renseigné le type retourné (1)

    à ne pas confondre avec le type de l’argument (2)

    Le code suivant ne fonctionnera pas :

    var name = node.getName(["Top/mynode"]) 
    

    car dans ce cas je passe à la méthode une array et non une string !

  • 🛠️ les outils de dev : VSCode

    https://code.visualstudio.com

    VSCode est un logiciel de programmation gratuit et open source relativement accessible pour les débutants. C’est une sorte de navigateur web mais pour les fichiers locaux.

    Créer un workspace

    Le système de Workspace se comporte comme des onglets prédéfinis dans un navigateur web. On ouvre les dossiers et fichiers qui nous interessent puis on sauvegarde simplement le workspace actuel pour ne pas avoir à tout réouvrir la prochaine foi.

    Ajouter un “folder”

    Sauvegarder le “Workspace” :

    Installation des Raccourcis :

    Je préconise d’utiliser les raccourcis Nodepad++

    • Crt+Shift+X pour ouvrir le gestionnaire d’extensions VSCode
    • Cherchez “Notepadd++”
    • Choisissez “Notepad++ keymap” et cliquez sur “installer”
  • ✨ API Harmony : Structure d’un Xstage

    Pour comprendre comment est structurée une scène Harmony il n’y pas de meilleur endroit que le fichier xstage.

    Si vous ouvrez un xstage dans un éditeur comme nodepad++ vous verrez qu’il s’agit enfait d’un énorme bloc de texte.

    Ce bloc de texte est structuré en balises </> selon un language qu’on appel XML pour eXtensible Markup Language (langage de balisage extensible). Tout ce qui fait la particularité d’une scene, à l’exeption des fichiers vectoriels de dessin, est décrit dans ce xml.

    Ce que vous avez sous les yeux est l’arborescence d’un immense objet xml. Le language xml, comme le json, est un language conçu uniquement pour organiser des données.

    voici notre fiche perso dnd en json

    {
      "name":"guntar",
      "type":"barbare",
      "statistiques" : {
        "endurance":100,
        "attaque":100,
        "interet_pour_la_bossa_nova":0,
        "conversation":5
      }
    }

    et voici le meme objet en xml

    <perso name="guntar" type="barbare" >
      <statistiques>
        <endurance val='100' />
        <attaque val='100' />
        <interetPourLaBossaNova val='0' />
        <conversation val='5' />
      </statistiques>
    </pers>

    L’arborescence d’un objet xml est un peu plus complexe que celle d’un objet json car elle est spécialement pensée pour décrire des ensembles et sous ensembles.

    Le contenu d’un element xml se situe entre :

    ses balises d’ouverture <element>

    Dans cet example on dit que l’elementA est le “parent” de l’elementB. L’élementB est un sous ensemble d’élémentA.

    Il exsite des balises qui n’englobent rien comme ici les statistiques <endurance />

    Chaque balise possède aussi des “propriétés” (name=”guntar”) qui sont une façon de renseigner des valeurs indépendament de la hiérarchie.

    Dans le xml d’un xstage les nodes sont décrit par des balises <module> </module>

    en propriété du module nous avons son type,nom et position dans la nodeview :

    si vous modifiez ces valeurs et sauvegarder le xml. Votre scène sera modifiée !

    En sous élement du module se trouve l’élément <attrs> </attrs>

    C’est là que se déroule toute la liste des attributs du node. Ce sont ces données là qui sont affichée lorsque l’on ouvre la fenêtre “node properties” dans Harmony.

    C’est aussi ces objets que nous allons modifier lorsque nous utilisons les methodes de la classe node : node.getTextAttr et node.setTextAttr