24/01/2018

Apprendre à coder, Par où commencer quand on n'y connait rien ?

Ce qui est sympa quand on apprend à coder, c'est de voir les changement rapidement.
Le logiciel avec lequel je me suis le plus éclaté, c'est Processing, conçu à la fois pour l'éducation et les performances artistiques...

J'ai commencé avec "Learning Processing" (et ses exemples) et "The Nature Of Code" écrits par Daniel Shiffman, qui sévi maintenant en vidéos :  http://shiffman.net/videos/ .

Le logiciel Arduino  pour ceux qui s'intéressent aux objets connectés ou à la robotique est également basé sur Processing (avec quelques exemples).
Il existe même une version Android pour ceux qui souhaiteraient pouvoir coder sur leur smartphone en attendant leur bus ( rigolez pas, ça m'est arrivé), il suffit de télécharger l'appli APDE sur le PlayStore.

Processing permet de créer des programmes sur votre ordi (Windows / Linux ou MAC), APDE des applis Android, mais celui qui me parait le plus intéressant actuellement c'est P5JS.

Vous pouvez soit télécharger le fichier ZIP (P5JS COMPLETE), et modifier l'exemple, soit utiliser directement l'éditeur en ligne  https://alpha.editor.p5js.org/.
 (on doit pouvoir enregistrer son travail en s'abonnant, sinon copiez votre code avec Ctrl+c et collez le dans un fichier texte sur votre ordi avec Ctrl+v ).
Pour retrouver facilement l'éditeur en ligne, recherchez "p5js online" sur Google .

Commencez par P5js online, (allez voir notamment les exemples dans 'Files/Example').

On va commencer par faire quelques tests, mais pour aller plus loin (image, video, gestion de plusieurs fichiers, utilisation de librairies, il faudra téléchargez 'P5JS Complete' pour travailler sur votre ordi.
On y reviendra, mais sous son allure très simple, P5js permet de faire des choses monstrueuses. Vous ne me croyez pas ? Allez donc jeter un oeil sur Open Processing, cliquez sur l'un des exemples, au hasard, son code est accessible en cliquant sur l'icône '</>' et pour executer le code, c'est sur le triangle 'play' (ça sera toujours le même que ce soit sur Processing, APDE, P5JS)...

Ce qui peut vous être utile, si vous bloquez, ou pour avoir des exemples d'utilisation des fonctions,  c'est d'aller voir les "REFERENCES" ou "EXEMPLES" de chacun des logiciels :

P5JS : REFERENCE & EXEMPLES
PROCESSING : REFERENCE & EXEMPLES
APDE : https://github.com/Calsign/APDE/wiki


Les librairies sont des extensions du logiciel.


Programmer , c'est quoi ? A la base, c'est écrire du code pour créer une application, automatiser une tâche, transformer des données, mais avec Processing et toute la série ( je parlerais de Processing de manière générale), ça va un peut plus loin, et on peut pousser le côté créatif / artistique assez facilement, enfin ça ça dépend de chacun... Fonctionnel / Visuel...


Pour une première approche, on va se concentrer sur l'éditeur online de P5js que vous pouvez ouvrir en cliquant ici  : https://alpha.editor.p5js.org/

Par défaut, dans chacun de ses logiciels, on trouve deux fonctions :
- une fonction 'setup' qui permet de mettre en place l'environnement
- un fonction 'draw' (ou 'loop' dans le logiciel Arduino) qui boucle à l'infini tant qu'on ne l'arrête pas expressément.

Quelques notions essentielles sont nécessaires :
- une variable est un espace de stockage en mémoire dans laquelle on va pouvoir stocker une chaine de caractères, un nombre, un objet;
- une fonction est une action que l'on va pouvoir appeler à plusieurs endroits sans être obligé de la réécrire.

Une fonction commence par le mot 'function' , suivi du nom de la fonction, suivi d'un couple de parenthèse, suivi d'un couple d'accolades. Les parenthèses seront utilisées pour envoyer des paramètres à la fonction, et les accolades contiendront le corps de la fonction, ce qu'elle fera réellement.


Bien maintenant, nous avons tout pour commencer.
En ouvrant l'editeur P5js online, vous pouvez cliquer sur le 'triangle PLAY' pour lancer le programme présent, et le carré 'STOP' pour arrêter.

function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background(220);
}


En fait on a déjà, ici 4 fonctions : setup et draw, les deux fonctions que nous venons de voir et
- la fonction 'createCanvas(400,400);' qui créé notre espace de travail de 400 pixels de largeur par 400 pixels de hauteur. le premier pixel, de coordonnées (0,0) se situant en haut à gauche, et le dernier pixel, de coordonnées (400,400) si situant en bas à droite, et vers le milieu de notre espace de travail, on aura le pixel (200,200) jusque là, tout va bien ????

[vous pouvez remplacer les 400 par d'autres valeurs, pour modifier la taille de votre espace de travail.]

Ok, on continue...
Noter que chaque commande se termine par un point-virgule, vous risquez d'en oublier parfois, mais vous vous en rendrez vite compte : votre programme ne se lancera pas, et vous aurez un message d'erreur, dans la console (cadre gris, en bas à gauche) vous indiquant un truc du style :


Uncaught SyntaxError: missing ; after argument list (sketch: line 2)

la fonction 'backgound (220);'
est la seule action exécutée actuellement, et elle remplit le fond (et oui, background = fond, on est obligé de comprendre un peu l'anglais quand on veut programmer !)
On remplit ici le fond avec la couleur (220);

Pour les couleurs, une seule valeur, indique un niveau de gris : 0 = noir, 255 = blanc.
Pour un peu plus de fun, les couleurs peuvent aussi s'écrire comme un triplet de valeurs (rouge, vert, bleu) allant de 0 à 255.
ainsi la couleur (255, 0, 0) vous donnera du rouge.

Pour vérifiez, modifiez le code ainsi :

function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background(255, 0, 0);
}

Votre fond devrait devenir rouge. Pour trouver vos couleurs favorites allez voir ici et noter les valeurs RVB de vos couleurs.

STROKE & FILL


Deux autres fonctions qui vous seront très utiles, et qui se placent avant les éléments que l'on veut dessiner:
- 'stroke()' détermina la couleur de votre trait,
- et 'fill()' la couleur de remplissage.

J'en ajoute deux tant qu'on est là, mais ces deux-ci ne devraient pas vous pposer de problèmes :
- rect() permet de dessiner un rectangle, et
- ellipse() permet de dessiner une ellipse.... Wahou, trop dur....

Vous pouvez tester le code suivant qui vous dessinera, sur fond rouge, un rectangle vert dont le contour est jaune et une ellipse jaune dont le contour est vert :

function setup() { 
  createCanvas(400, 400);
function draw() { 
  background(255, 0, 0);
stroke(255,255,0); 
fill(42,156,23);
rect(50, 50, 75, 100);
stroke(42,156,23);
fill(255,255,0); 
ellipse(250, 350, 75, 100);
}

Pour 'rect' et 'ellipse', on utilise 4 paramètres : les deux premiers, sont les coordonnées, l'endroit où l'on va dessiner les éléments, le troisième correspond à la largeur, et le quatrième à la hauteur.

On a déjà bien avancé, non ? Profitez-en pour faire une pause, vous pouvez ajouter des cercles, des rectangles et pourquoi pas un triangle ???

Vous pouvez aussi vous inspirer de ZOOG, le personnage de  "Learning Processing"



notez la notation des commenatires par la double barre oblique // et les commentaires sur plusieurs lignes entourés par /*......*/

// un commentaire sur une ligne
function setup() { 
/* ici 
un 
commentaire
sur
plusieurs
lignes */
  createCanvas(400, 400);
function draw() { 
  background(121, 248, 248);
ellipseMode(CENTER);
rectMode(CENTER); 
// Corps
stroke(0);
fill(247,255, 56);
rect(240, 145, 20, 100);
// Tête
fill(0, 255, 0);
ellipse(240, 115, 60, 60); 
// Yeux
fill(0); 
ellipse(221, 115, 16, 32); 
ellipse(259, 115, 16, 32);
// Jambes
stroke(0);
line(230, 195, 220, 205);
line(250, 195, 260, 205); 
}

Pas la peine que je vous explique à quoi servent les deux fonctions, je vous laisse découvrir par vous même leur utilité ou allez voir la "référence" :

ellipseMode(CENTER);  --> https://p5js.org/reference/#/p5/ellipseMode
rectMode(CENTER); --> https://p5js.org/reference/#/p5/rectMode

Interaction
Un peu plus de fun ? Ajoutons de l'interaction, en utilisant la position de la souris, elle est définie par deux variables prédéfinies : 'mouseX' et 'mouseY', et poussons le bouchon, en utilisant la position précédente de la souris 'pmouseX' et 'pmouseY', ajoutons une action lors du clic 

function setup() { 
  createCanvas(400, 400);
// La vitesse est réglée 30 images par seconde.
  frameRate(30);
function draw() { 
  background(121, 248, 248);
ellipseMode(CENTER);
rectMode(CENTER); 
// Corps
stroke(0);
fill(247,255, 56);
rect(mouseX, mouseY, 20, 100);
// Tête
fill(0, 255, 0);
ellipse(mouseX, mouseY-30, 60, 60);
// La couleur des yeux est déterminée en fonction de la position de la souris.
  fill(mouseX/2, 0, mouseY/2); 
  ellipse(mouseX-19, mouseY-30, 16, 32); 
  ellipse(mouseX+19, mouseY-30, 16, 32); 
// Jambes
stroke(0);
// Les jambes sont dessinées en fonction de la position de la souris et de sa position précédente.
  line(mouseX-10, mouseY+50, pmouseX-10, pmouseY+60);
  line(mouseX+10, mouseY+50, pmouseX+10, pmouseY+60);
}
function mousePressed() {
  console.log("Mets moi dans ta poche!");
}

référence : http://learningprocessing.com/examples/chp03/example-03-06-interactive-zoog


Les yeux de ZOOG changent de couleur en fonction de la position de la souris, les jambes semblent trainer, et quand on clique ( function moussePressed )  un message est écrit dans la console ( cadre gris en bas à gauche).


Jetez aussi un oeil sur cette page pour voir quelques interactions avec le clavier .

Notez au passage l'utilisation des conditions:
- si (condition) alors faire {...} sinon faire {...}

function setup(){

 createCanvas(480, 270);

}



function draw() {

  background(255);

  stroke(0);

  line(240, 0, 240, 360);

  line(0, 135, 640, 135);



  // Fill a black color

  noStroke();

  fill(0);



  // Depending on the mouse location, a different rectangle is displayed.    

  if (mouseX < 240 && mouseY < 135) {

    rect(0, 0, 240, 135);

  } else if (mouseX > 240 && mouseY < 135) {

    rect(240, 0, 240, 135);

  } else if (mouseX < 240 && mouseY > 135) {

    rect(0, 135, 240, 135);

  } else if (mouseX > 240 && mouseY > 135) {

    rect(240, 135, 240, 135);

  }

}


et des boucles :
Pour 'i' de 0 à la moitié de la largeur (width/2) , avec un pas de 10, dessiner un rectangle commencant à la position (i,10), de largeur 3 et de hauteur 200+i.

function setup(){

createCanvas(500,500);

}



function draw(){

fill(255,115,143);



for(var i=0; i<width/2 ; i+=10){

    rect(i, 10, 3, 200+i);

  }

}

[ 'width' correspond à la largeur de l'environnement de travail, ou canvas, 'height' correspond à la hauteur ]

On a encore plein de trucs à voir comme les Objets/ Classes, les tableaux d'objets, ou comment utiliser des librairies externes, mais vous devriez maintenant être armé pour aller triturer
quelques démos sur Open Processing ou modifier le code du jeu basé sur  slither.io

En cas de doute, consultez la REFERENCE P5JS





05/01/2018

Tutoriel slither.io sur P5JS

English Translation of this article ]

Objectif : recréer un jeu inspiré de slither.io.


Découverte de l'éditeur P5js online

Commencez par ouvrir l'éditeur P5js online : https://alpha.editor.p5js.org/
Vous devriez voir le code suivant :


       
function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background(220);
}

Dans P5js, deux fonctions sont importantes : la fonction 'setup' qui permet de mettre en place l'environnement et la fonction 'draw' qui boucle à l'infini.

Dans 'setup', la fonction 'createCanvas(400, 400)' définit un espace de 400 pixels de largeur par 400 pixels de hauteur. Notez que chaque instruction se termine par un point virgule ';'.

Dans 'draw', la fonction 'background' définit la couleur de fond.

Dans l'éditeur p5js online, cliquez sur le bouton 'PLAY' (triangle rose sur fond gris) pour exécuter votre code. Un carré gris ( background(220); ) de 400 pixels de largeur par 400 pixels de hauteurs ( createCanvas(400, 400); ) devrait apparaître sur la droite.
Le carré juste à droite du bouton 'PLAY' est le bouton 'STOP' et est utilisé pour stopper l’exécution de votre code.

Notez que chaque définition de fonction commence par le mot 'function', suivi du nom de la fonction, ensuite, nous avons deux parenthèses '()' permettant éventuellement de définir des paramètres pour la fonction, et le corps de la fonction contenu entre deux accolades '{ }'.

Premiers essais

On peut à ce stade faire déjà quelques essais. Par exemple, vous pouvez : 
- remplacer createCanvas(400, 400);  par createCanvas(600, 600); pour agrandir le canvas ou 
- remplacer  background(220); par background(10, 150, 100);
  pour changer la couleur de fond en un vert. Choisissez maintenant la couleur qui vous convient. De nombreuses palettes existent sur internet pour choisir vos couleurs.

Note : La définition des couleurs sous P5js :
Il existe trois manière de définir les couleurs dans p5js : 
- 1 nombre compris entre 0 et 255 : un niveau de gris, avec 0 correspondant à noir et 255 correspondant à blanc;
- 3 nombres compris entre 0 et 255 séparés par des virgules : ici on définit un mélange des trois couleurs 'rouge', 'vert', 'bleu'.
- 4 nombres compris entre 0 et 255 : idem que précédemment, le quatrième paramètre définissant la transparence.


Contrôles du jeu


Dans slither.io, on joue avec la souris. On va donc avoir besoin des coordonnées de la souris. Sous P5js, elles sont définies par les variables 'mouseX' et 'mouseY'.

Note : Le manuel de référence :
Pour avoir un aperçu des fonctionnalités existantes dans P5js, consultez le manuel de référence... par exemple pour 'mouseX' , c'est ici https://p5js.org/reference/#/p5/mouseX et pour mouseY, c'est ici : https://p5js.org/reference/#/p5/mouseY

On va en profiter pour dessiner un premier petit truc, un cercle, ou une ellipse

Note: Dessiner une ellipse :
Pour une ellipse, on définit 3 ou 4 paramètres (le quatrième, la hauteur est optionnelle) 
extrait du manuel de référence :  ellipse(x,y,w,[h])
x pour l'abscisse de l'ellipse, y pour l'ordonnée, w pour sa largeur et h sa hauteur. Les crochets autour du 'h' indiquent que ce paramètre est optionnel.

Juste après la ligne background, insérer la ligne :

ellipse(mouseX, mouseY,10);

Vous devriez obtenir ce code :

       
function setup() {

  createCanvas(600, 600);

}



function draw() {

   background(10, 150, 100);

  ellipse(mouseX, mouseY, 10);

}


Exécutez-le en cliquant sur le triangle rose. En bougeant la souris sur le canvas, vous devriez voir un petit point blanc suivre votre souris... C'est l'ellipse qui a les même coordonnées que votre souris... Facile, non ???


vous pouvez changer la forme de cette ellipse, en lui ajoutant un quatrième paramètre (le 'h' optionnel de tout à l'heure, en modifiant la valeur de sa largeur ('w'), ou en modifiant sa couleur. Pour changer la couleur, insérez juste avant la ligne ellipse(mouseX, mouseY, 10);  une ligne utilisant la fonction 'fill' ( fill = remplissage )  . Par exemple, en insérant  fill(100, 100, 240)vous colorerez votre ellipse en violet (100 pour rouge, 100 pour vert et 240 pour bleu).

notre fonction draw devrait maintenant contenir le code suivant : 

       
background(10, 150, 100);

  fill(100, 100, 240);

  ellipse(mouseX, mouseY,10);




L'objet 'Nourriture'


Notre slither suit notre souris, première étape remplie, mais maintenant, il va lui falloir quelque nourriture à manger...

Pour ce faire, on va créer une 'Classe'. Sous P5js une classe va nous permettre de créer un objet que l'on pourra réutiliser par la suite. Une classe se créé comme une fonction.
Un 'grain' de nourriture sera dans un premier temps matérialisé par un petit carré positionné au hasard dans le canvas. Pour le hasard, on va ici user de la fonction 'random'
Après l'accolade de fermeture de la fonction draw(){...} collez le code de la fonction 'Nourriture'. Notez la majuscule, c'est un signe distinctif pour différencier les Classes des fonctions de base.

function setup() { 
  createCanvas(600, 600);
} 

function draw() { 
   background(10, 150, 100);
  fill(100, 100, 240);
  ellipse(mouseX, mouseY,10);
}

function Nourriture(){
  this.x = random (10, width-10);
  this.y = random (10, height-10);
  this.color =  color(random(0,255),random(0,255),random(0,255));
 
}

Note : Mais qu'est-ce que ce 'this' ??? 
'This' est ici pour définir une variable interne à la classe... 'this.x' on définit l'abscisse propre à notre objet 'Nourriture', comme 'this.y' définit son ordonnée et 'this.color' ... sa couleur, notez ici la manière de définir une couleur aléatoire, en prenant un random en 0 et 255 pour chacune des trois couleurs.

Mais ceci ne suffit pas encore pour voir notre objet 'Nourriture', nous devons également lui créer une fonction interne que nous appelerons 'display', ou plutôt 'this.display' car c'est une fonction interne à l'objet. 
A vous de bosser, je vous donne le code, essayez de deviner ce qu'il fait, reportez-vous éventuellement au manuel de référence

 this.display = function(){
    stroke(color(random(0,255),random(0,255),random(0,255)));
    strokeWeight(1);
    fill(this.color);
    rect(this.x, this.y, 5,5);
    noStroke();
  }

Bon ok, pour ceux qui se seraient perdus ou aurait la flemme : 
- stroke() définit la couleur du contour de l'élément qui va suivre.
- strokeWeight() définit son épaisseur
- fill() : remplissage comme vu précédemment, ici on remplit avec 'this.color'
- rect(), on dessine un rectangle à la position aléatoire (this.x, this.y,..) définie lors de la création de l'objet 'Nourriture' , les troisième et quatrième paramètre définissent comme pour l'ellipse, la largeur et la hauteur du rectangle.
- noStroke(); est ici utilisé pour enlever le contour pour les prochains objets. (On ne sait pas à ce stade ce qui sera dessiné après le rectangle, donc précaution).

Nous avons maintenant une fonction pour dessiner notre objet 'Nourriture', mais il n'existe pas encore. Nous allons pour ce faire, créer une variable 'nourriture', sans majuscule, cette fois, avant la fonction 'setup', car c'est une variable 'global' (on pourra l'utiliser n'importe où dans notre code ).

var nourriture; 

ensuite, il ne reste plus qu'à l' 'implémenter' dans la fonction 'setup' en utilisant le code :
(implémenter = définir notre variable 'nourriture' comme étant un nouvel objet de la Classe  'Nourriture', grâce au mot clé "new") 

nourriture = new Nourriture();

et à demander son affichage dans la fonction 'draw' 

nourriture.display();

Si votre code est le même que celui qui suit, vous devriez voir maintenant un cube 'clignotant' placé de manière aléatoire et représentant un 'grain' de nourriture : 


       
var nourriture;



function setup() {

  createCanvas(600, 600);

 nourriture = new Nourriture();

}



function draw() {

   background(10, 150, 100);

  fill(100, 100, 240);

  ellipse(mouseX, mouseY,10);

  nourriture.display();

}



function Nourriture(){

  this.x = random (10, width-10);

  this.y = random (10, height-10);

  this.color =  color(random(0,255),random(0,255),random(0,255));

 

 this.display = function(){

    stroke(color(random(0,255),random(0,255),random(0,255)));

    strokeWeight(1);

    fill(this.color);

    rect(this.x, this.y, 5,5);

    noStroke();

  }

}




Ajouter un adversaire qui sera déplacé par le clavier

Si on veut jouer avec un ami, on peut imaginer un adversaire que le serpent ne devra pas rencontré... Allez donc voir sur cette page : http://www.lyceelecorbusier.eu/p5js/?p=2019#more-2019  le paragraphe indiquant "Pour déplacer un élément au clavier avec les flèches directionnelles utiliser UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW."


Déterminer si la nourriture a été croquée

Si vous êtes arrivé là, allez jeter un oeil au code un peu plus évolué, et tentez de la modifier : http://smag0.blogspot.fr/2017/12/code-slitherio-pour-p5js.html

Des fonctionnalités de jeux plus avancées avec P5Play


Pour faciliter le développement de jeux, des librairies P5js existent, comme la librairie P5play :
voyez par exemple le jeu asteroids développé avec p5play.
D'autres librairies existent pour P5js : https://p5js.org/libraries/

OpenProcessing
OpenProcessing est une galerie d'animations réalisées avec P5js ou Processing et est accessible à  cette adresse : https://www.openprocessing.org/browse/#