UED 131 Programmation impérative TP4 Variables, expressions, fonctions Souvent Toto varie, Bien fol est qui s’y fie. Anonyme TP4 / Compétences générales visées = - I Savoir manipuler les variables Comprendre la différence entre variables locales et globales Utiliser les variables combinées avec le mode dynamique pour créer des boucles Rappel de cours – les fonctions Ecrire une fonction utilisateur 2 parties • une déclaration (ou signature) o un type de retour o un nom o des paramètres sous la forme de couples (type nom) • un corps (un bloc d’instructions) Syntaxe <typeDeRetour> <nomDeFonction>(<paramètres>) { // corps de la fonction } Remarques diverses • Le nom des fonctions : o est arbitraire o mêmes règles de formation d’identificateurs que pour les variables o donner des noms explicites o une fonction doit être appelée pour être exécutée ! • La place des fonctions : o les fonctions peuvent être placées n’importe où dans le programme, en dehors des fonction setup et draw o en général, elles sont placées après le draw • Les paramètres sont optionnels • Une fonction qui réalise une tâche plutôt qu’un calcul ne renvoie aucun résultat : o on parle généralement de procédure o le type de retour est void o void ne peut pas être utilisé comme type de variable UED 131 II Programmation impérative Mode dynamique et portée des variables Compétences = • Comprendre la différence entre variable locale et variable globale • Savoir déclarer ses variables au bon endroit • Savoir initialiser ses variables au bon endroit • Savoir manipuler ses variables au bon endroit Pré-requis = Si vous ne l’avez pas déjà fait, faites l’exercice IV.1. du TP3 Rappel de cours : Les programmes informatiques sont optimisés pour ne pas gaspiller la place en mémoire. Lorsqu'une variable est déclarée, elle ne va être définie que le temps nécessaire. • une variable n’est utilisable que pour les instructions qui suivent la déclaration de la variable (en suivant l’ordre séquentiel, de haut en bas) ; • une variable déclarée à l’intérieur d’une fonction (entre { et }) ne sera utilisable qu’à l’intérieur de cette même fonction ; C’est une variable locale ; • une variable déclarée en début de fichier, à l’extérieur de toutes fonctions, sera visible et utilisable de partout ; c’est une variable globale ; II.1. (!)(*) Variables locales et globales Soit le code source suivant : void setup() { size (400,400); background(0,0,0); frameRate(50); } void draw() { int rouge=25; int vert=60; int bleu=200; fill(rouge,vert,bleu); rect(20,20,360,360); rouge = (rouge + 1) % 255; vert = (vert + 1) % 255; bleu = (bleu + 1) % 255; } a) Quel résultat attend-on de ce programme ? Essayez d’exécuter le programme. Que se passe-t-il ? b) Corrigez le programme en rendant les variables globales. UED 131 Programmation impérative II.2. (!)(*) Variables locales et globales Soit le code source suivant : void setup() { size (400,400); background(0,0,0); int rouge=25; int vert=60; int bleu=200; } void draw() { fill(rouge,vert,bleu); rect(20,20,360,360); } a) Quel résultat attend-on de ce programme ? Essayez d’exécuter le programme. Que se passe-t-il ? b) Corrigez le programme en rendant les variables globales pour dessiner un carré coloré sur fond noir ; c) Corrigez le programme en rendant les variables locales à la fonction draw pour dessiner un carré coloré sur fond noir ; d) Que se passe-t-il quand les variables sont déclarées à la fois comme étant globales et comme étant locales à la fonction draw ? Donnez-leur des valeurs différentes pour comprendre comment le programme se comporte. Quelles variables « l’emportent » ? II.3. (!)(*) Variables locales et globales Soit le code source suivant (la fonction text qui sert à afficher une chaîne de caractères à une position donnée) : String chaine; void setup() { size (400, 400); background(0, 0, 0); PFont font = createFont("Arial", 32); textFont(font); } void draw() { chaine="Un texte"; text(chaine, 20, 100); affiche(); text(chaine, 20, 300); } void affiche() { chaine="dans la fonction affiche"; text(chaine, 20, 200); } a) Exécuter le programme. Qu'est ce qui s'affiche et pourquoi ? b) Dans la fonction affiche, modifier la ligne : chaine="dans la fonction affiche"; en la remplaçant par : String chaine="dans la fonction affiche"; Exécutez le programme. Qu'est ce qui s'affiche et pourquoi ? UED 131 Programmation impérative III Petit retour en arrière… Compétences = Comprendre l’utilisation de variables et de draw pour dessiner avec des boucles III.1. (!)(**) Des variables pour dessiner Si vous ne l’avez pas déjà fait, reprenez l’exercice IV.5 du TP3, et programmez au minimum la première figure. = dans une fenêtre de 500 pixels de côté, dessinez un rectangle centré dans la fenêtre de plus en plus grand (le rectangle central est de taille (10x10), et chaque rectangle est 20 pixels plus large et plus haut que le précédent) Indice 1 : le tracé peut être plus facile en utilisant rectMode Indice 2 : utilisez le mode dynamique pour ne pas avoir à écrire de boucle IV Pour aller plus loin… Compétences = Approfondir l’utilisation des variables, des expressions, et de l’interaction avec la souris IV.1. (!)(**) Un chronomètre a) Créez une variable compteur, de type entier, pour compter le nombre d’appels à la fonction draw (appelé aussi le nombre de frames) depuis le début de l’exécution du programme. Où faut-il la déclarer ? l’initialiser ? l’incrémenter ? b) Affichez cette variable dans une fenêtre de taille (500x100) c) Créez une variable secondes, de type entier, pour compter le temps écoulé depuis le début du programme, et mettez sa valeur à jour en utilisant les variables compteur et frameRate. Modifier l’affichage pour afficher un message de la forme : Temps écoulé depuis le début du programme : 3s d) Au bout d’une trentaine de secondes, on peut se rendre compte qu’il arrive que la variable secondes oscille entre deux valeurs au moment du passage des secondes. En affichant les valeurs de compteur, frameRate et secondes, proposez une interprétation de ce phénomène. En utilisant l’instruction max, proposez une correction. e) Comment faire si l’on souhaite afficher les dixièmes, les centièmes ou les millièmes de secondes ? f) On a vu à la question d) que cette méthode n’est pas très fiable, du fait de la variabilité de frameRate. Il est donc préférable d’utiliser l’instruction millis. Après avoir consulté la documentation au sujet de cette instruction, modifiez votre programme pour l’utiliser à la place du compteur. g) Ajoutez la possibilité d’ajouter un temps intermédiaire à chaque fois qu’on clique avec la souris, sous la forme suivante : UED 131 Programmation impérative IV.2. (!)(**) Un toto qui va et vient Reprenez l’exercice de la tête à toto a) Créez les variables totoX et totoY pour stocker les coordonnées de la tête à toto. Les coordonnées doivent être des réels. b) Associez-lui un vecteur vitesse (totoVx, totoVy) dont les coordonnées sont également des réels. Initialisez totoVx à 0 et totoVy à 5. c) Ecrivez la fonction deplace qui ajoute le vecteur vitesse à la position courante de la tête à toto à chaque appel de la fonction draw() : d) Ajoutez une fonction mouseClicked pour inverser le sens de déplacement à chaque clic souris IV.3. (***) Toto dans un champ de pesanteur On voudrait maintenant simuler un champ gravitationnel. Pour cela : a) Déclarez une variable g, de type réel, de valeur 0.981 (regarder le mot clé final) b) Ajoutez une fonction accelere qui calcule la nouvelle vitesse de la tête en ajoutant la gravité à la vitesse verticale (totoVy) c) Ajoutez une fonction go qui appelle successivement accelere et deplace IV.4. (***) Toto en orbite On voudrait maintenant que Toto se place en orbite autour du centre de la fenêtre. Pour cela : a) Modifiez la fonction accelere de manière à ce que (regardez la fonction dist) : (𝑥!"#$%" − 𝑡𝑜𝑡𝑜𝑋) 𝑡𝑜𝑡𝑜𝑉𝑥 = 𝑡𝑜𝑡𝑜𝑉𝑥 + 𝑑𝑖𝑠𝑡(𝑡𝑜𝑡𝑜, 𝑐𝑒𝑛𝑡𝑟𝑒) (𝑦!"#$%" − 𝑡𝑜𝑡𝑜𝑌) 𝑑𝑖𝑠𝑡(𝑡𝑜𝑡𝑜, 𝑐𝑒𝑛𝑡𝑟𝑒) c) Ajoutez une fonction trajectoire de manière à afficher la trajectoire de Toto sous forme d’une suite de segments entre deux positions successives. Il faudra pour cela créer aussi deux nouvelles variables totoX0 et totoY0 pour stocker la position précédente la tête à Toto. d) Ajoutez une variable booléenne trajec (qui vaudra true si on souhaite afficher la trajectoire ou false si on souhaite afficher la tête à Toto) et modifiez la fonction mouseClicked de manière à alterner entre les deux modes. Adaptez la fonction draw pour appeler toto ou trajectoire selon la valeur de trajec. (regarder pour cela la structure if…else) 𝑡𝑜𝑡𝑜𝑉𝑦 = 𝑡𝑜𝑡𝑜𝑉𝑦 +