Share
Explore
Exercice 1 : Un mini Paint
Le peut être modifié pour créer une petite application de coloriage.
Une palette contient une série de couleurs.
Si on clique sur une des cases de cette palette, on sélectionne la couleur indiquée par un petit triangle pointé sur sa case.
On peut colorier les cases de la grille de dessin avec la couleur sélectionnée en cliquant () ou en "glissant et appuyant" () dessus.
Capture d’écran 2020-04-19 à 12.54.54.png
Pour générer les couleurs de la palette, on peut s'inspirer de cet.

Il est basé sur la commande de Processing qui permet de passer du mode de couleur RGB habituel au mode de couleur
, basé sur une autre représentation des couleurs où les trois composantes ont une signification différente.

Voici le code permettant de générer un tableau contenant les couleurs de la palette illustrée ci-dessus :

color p[] = new color[m]; // Couleurs de la palette

// Initialisation de la palette de couleurs
colorMode(RGB, 255, 255, 255);
for (int j=0;j<m/2;j++) {
p[j] = color(255-2.0*j/m*255); // Dégradés de gris
}
colorMode(HSB, 360, 100, 100);
for (int j=m/2;j<m;j++) {
p[j] = color((j-m/2)*720/(m+2), 100, 100); // Arc-en-ciel
}
colorMode(RGB, 255, 255, 255); // Retour au mode RGB

Cet exercice permet de combiner les notions vues précédemment :
Un tableau à une dimensions contient les couleurs de la palette.
Un tableau à deux dimensions contient les codes des couleurs des cases de la grille. Ce code est un numéro qui fait référence à l'indice du tableau à une dimension.
Les interactions permettent de détecter où on clique avec la souris pour déclencher l'action correspondante : sélectionner une couleur lorsque l'on est au-dessus de la palette ou colorier une case lorsque l'on est au-dessus de la grille.

Correction de l'exercice 1
Your link was not successfully embedded. Please try again with a different URL.
int n = 25; // Nombre de cases horizontalement
int m = 25; // Nombre de cases verticalement
int a = 20; // Dimension d'une case
int x0 = 200; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;
int b = m/2; // Couleur choisie dans la palette initialement

color p[] = new color[m]; // Couleurs de la palette

color c[][] = new color[n][m]; // Déclaration d'un tableau à 2 dimensions

void setup() {
frameRate(30); // Taux de rafraîchissement de 30 Hz
size(800,600);

// 1. Initialisation de la palette de couleurs
colorMode(RGB, 255, 255, 255);
for (int j=0;j<m/2;j++) {
p[j] = color(255-2.0*j/m*255); // Dégradés de gris
}
colorMode(HSB, 360, 100, 100);
for (int j=m/2;j<m;j++) {
p[j] = color((j-m/2)*720/(m+2), 100, 100); // Arc-en-ciel
}
colorMode(RGB, 255, 255, 255); // Retour au mode RGB

// 2. Initialisation des éléments du tableau à 2 dimensions
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
c[i][j] = p[0]; // Remplir les cases de la grille
// en blanc = couleur de la première case de la palette
}
}
}

void draw() {
background(100); // Fond gris
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées du coin supérieur gauche de chaque case
int y = y0 + j*a;
fill(c[i][j]); // Couleur de chaque case de la grille
rect(x,y,a,a); // Dessin de chaque case de la grille
}
}
// Dessin de la palette
for (int j=0;j<m;j++) { // j numérote les lignes
int y = y0 + j*a;
fill(p[j]); // Couleur de chaque case de la palette
rect(100,y,a,a); // Dessin de chaque case de la palette
// Dessin du curseur triangulaire
if (j == b) triangle(100,y+a/2,100-a,y,100-a,y+a);
}
}

void mousePressed() {
interaction();
}

void mouseDragged() {
interaction();
}

void interaction() {
int mousei = (mouseX - x0) / a; // Changement de système de coordonnées :
int mousej = (mouseY - y0) / a; // (mouseX,mouseY) -> (mousei,mousej)
boolean dansLaGrille = mouseX >= x0 && mousei < n && mouseY >= y0 && mousej < m;
if (dansLaGrille)
c[mousei][mousej] = p[b]; // Change la couleur de la case avec la couleur sélectionnée
boolean dansLaPalette = mouseX >= 100 && mouseX < 100+a && mouseY >= y0 && mousej < m;
if (dansLaPalette)
b = mousej; // Change la couleur sélectionnée dans la palette
}

Exercice 2 : Des pions qui rebondissent dans une grille
Dans une grille de 25x25 cases de 20 pixels de côté, 10 pions noirs et ronds de 10 pixels de diagonale se déplacent en rebondissant sur les côtés de la grille. Les pions peuvent se déplacer indépendamment d'une case à la fois horizontalement, verticalement ou en diagonale.

Il s'agit d'utiliser deux tableaux à une dimension qui contient les différentes coordonnées des pions dans le système de la grille : i et j de chaque pion.
Capture d’écran 2020-04-28 à 11.46.08.png
Correction de l'exercice 2
Your link was not successfully embedded. Please try again with a different URL.
int n = 25; // Nombre de cases horizontalement
int m = 25; // Nombre de cases verticalement
int a = 20; // Dimension d'une case
int x0 = 150; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;

int np = 10; // Nombre de pions

// Déclaration des tableaux contenant les caractéristiques des pions
// dans le système de coordonnées de la grille (i,j)
int pi[] = new int[np]; // Composantes horizontales des positions
int pj[] = new int[np]; // Composantes verticales des positions
int vi[] = new int[np]; // Composantes horizontales des déplacements
int vj[] = new int[np]; // Composantes verticales des déplacements

void setup() {
size(800,600);
frameRate(10);
// Initialisation des tableaux des caractéristiques des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
pi[p] = (int)(random(n-2))+1; // Entre 1 et n-1 (pas sur les bords)
pj[p] = (int)(random(m-2))+1; // Entre 1 et m-1
vi[p] = (int)(random(3))-1; // Entre -1 et 1 (cases adjacentes)
vj[p] = (int)(random(3))-1; // Entre -1 et 1
}
}

void draw() {
background(100);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
fill(255);
rect(x,y,a,a);
}
}
// Animation et dessin des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
pi[p] += vi[p]; // Déplacement des pions
pj[p] += vj[p];
if (pi[p] <= 0 || pi[p] >= n-1) vi[p] = -vi[p]; // Rebonds
if (pj[p] <= 0 || pj[p] >= m-1) vj[p] = -vj[p];
// Dessin des pions
fill(0);
int x = x0 + pi[p]*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj[p]*a + a/2; // où se trouve le pion
ellipse(x,y,a/2,a/2);
}
}

Exercice 3 : Variante avec des murs dans la grille
Capture d’écran 2020-05-05 à 11.38.00.png
Le code ci-dessous est une variante de l'exercice précédent où on construit des "murs" (cases noires) dans la grille.

Un tableau à 2 dimensions permet de mémoriser les emplacements des murs : 0 pour une case vide, 1 pour une case murée.

L'exercice consiste à trouver comment faire rebondir les balles de l'exercice précédent sur les murs et non plus seulement sur les bords de la grille.

int n = 25; // Nombre de cases horizontalement
int m = 25; // Nombre de cases verticalement
int a = 20; // Dimension d'une case
int x0 = 150; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;

int np = 10; // Nombre de pions

// Déclaration des tableaux contenant les caractéristiques des pions
// dans le système de coordonnées de la grille (i,j)
int pi[] = new int[np]; // Composantes horizontales des positions
int pj[] = new int[np]; // Composantes verticales des positions
int vi[] = new int[np]; // Composantes horizontales des déplacements
int vj[] = new int[np]; // Composantes verticales des déplacements

// Déclaration d'un tableau 2D pour la grille
int grid[][] = new int [n][m];

void setup() {
size(800,600);
frameRate(10);
// Initialisation des tableaux des caractéristiques des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
pi[p] = (int)(random(n-2))+1; // Entre 1 et n-1 (pas sur les bords)
pj[p] = (int)(random(m-2))+1; // Entre 1 et m-1
vi[p] = (int)(random(3))-1; // Entre -1 et 1 (cases adjacentes)
vj[p] = (int)(random(3))-1; // Entre -1 et 1
}
// Initialisation d'un tableau 2D pour la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) {
grid[i][j] = (int)(random(10)); // Entre 0 et 9
if (grid[i][j] > 1) grid[i][j] = 0; // => 9 chances sur 10 d'avoir 0
}
}
}

void draw() {
background(100);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
if (grid[i][j] == 1) fill(0); // Noir
else fill(255); // Blanc
rect(x,y,a,a);
}
}
// Animation et dessin des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
pi[p] += vi[p]; // Déplacement des pions
pj[p] += vj[p];
if (pi[p] <= 0 || pi[p] >= n-1) vi[p] = -vi[p]; // Rebonds
if (pj[p] <= 0 || pj[p] >= m-1) vj[p] = -vj[p];
// Dessin des pions
fill(0);
int x = x0 + pi[p]*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj[p]*a + a/2; // où se trouve le pion
ellipse(x,y,a/2,a/2);
}
}

Correction de l'exercice 3
Pour éviter que les pions ne soient sur une case noire dès le début :
Initialiser le tableau des pions après le tableau de la grille (inverser les deux parties de code par rapport au code précédent)
Si un pion est sur une case noire, mettre la case en blanc
Tester si la case où sera le pion juste après son déplacement est un mur ou non

Your link was not successfully embedded. Please try again with a different URL.

int n = 25; // Nombre de cases horizontalement
int m = 25; // Nombre de cases verticalement
int a = 20; // Dimension d'une case
int x0 = 150; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;

int np = 10; // Nombre de pions

// Déclaration des tableaux contenant les caractéristiques des pions
// dans le système de coordonnées de la grille (i,j)
int pi[] = new int[np]; // Composantes horizontales des positions
int pj[] = new int[np]; // Composantes verticales des positions
int vi[] = new int[np]; // Composantes horizontales des déplacements
int vj[] = new int[np]; // Composantes verticales des déplacements

// Déclaration d'un tableau 2D pour la grille
int grid[][] = new int [n][m];

void setup() {
size(800,600);
frameRate(10);
// Initialisation d'un tableau 2D pour la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) {
grid[i][j] = (int)(random(10)); // Entre 0 et 9
if (grid[i][j] > 1) grid[i][j] = 0; // => 9 chances sur 10 d'avoir 0
}
}
// Initialisation des tableaux des caractéristiques des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
pi[p] = (int)(random(n-2))+1; // Entre 1 et n-1 (pas sur les bords)
pj[p] = (int)(random(m-2))+1; // Entre 1 et m-1
vi[p] = (int)(random(3))-1; // Entre -1 et 1 (cases adjacentes)
vj[p] = (int)(random(3))-1; // Entre -1 et 1
if (grid[pi[p]][pj[p]] == 1) // Si la case où se trouve le pion est noire,
grid[pi[p]][pj[p]] = 0; // on la met en blanc
}
}

void draw() {
background(100);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
if (grid[i][j] == 1) fill(0); // Noir
else fill(255); // Blanc
rect(x,y,a,a);
}
}
// Animation et dessin des pions
for (int p=0;p<np;p++) { // On parcoure la série de pions
// Rebonds sur les murs
// Tester si la case où sera le pion juste après son déplacement est un mur ou non
if (pi[p] > 0 && pi[p] < n-1 &&
pj[p] > 0 && pj[p] < m-1) // Si pas de rebonds sur les bords,
if (grid[pi[p]+vi[p]][pj[p]+vj[p]] == 1) { // Si le pion va se cogner sur un mur
vi[p] = -vi[p]; // Il rebondit
vj[p] = -vj[p];
}
pi[p] += vi[p]; // Déplacement des pions
pj[p] += vj[p];
if (pi[p] <= 0 || pi[p] >= n-1) vi[p] = -vi[p]; // Rebonds
if (pj[p] <= 0 || pj[p] >= m-1) vj[p] = -vj[p];
// Dessin des pions
fill(0);
int x = x0 + pi[p]*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj[p]*a + a/2; // où se trouve le pion
ellipse(x,y,a/2,a/2);
}
}

Déplacement d'un pion avec les flèches sur le clavier
Références
Pour capturer et réagir à la pression d'une touche sur le clavier, on peut utiliser les commandes Processing ,
et .

Le code suivant reprend le code de l'exercice 3 ci-dessus, le modifie pour n'avoir qu'un seul pion (donc plus besoin de tableaux à 1 dimension pour mémoriser les caractéristiques des pions) et ajoute une méthode pour gérer l'interaction avec le clavier.

int n = 25; // Nombre de cases horizontalement
int m = 25; // Nombre de cases verticalement
int a = 20; // Dimension d'une case
int x0 = 150; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;

int pi = n/2; // Coordonnées initiales du pion dans la grille
int pj = m/2;

// Déclaration d'un tableau 2D pour la grille
int grid[][] = new int [n][m];

void setup() {
size(800,600);
frameRate(10);
// Initialisation d'un tableau 2D pour la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) {
grid[i][j] = (int)(random(10)); // Entre 0 et 9
if (grid[i][j] > 1) grid[i][j] = 0; // => 9 chances sur 10 d'avoir 0
}
}
if (grid[pi][pj] == 1) // Si la case où se trouve le pion est noire,
grid[pi][pj] = 0; // on la met en blanc
}

void draw() {
background(100);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
if (grid[i][j] == 1) fill(0); // Noir
else fill(255); // Blanc
rect(x,y,a,a);
}
}
// Dessin du pion
fill(0);
int x = x0 + pi*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj*a + a/2; // où se trouve le pion
ellipse(x,y,a/2,a/2);
}

void keyPressed() {
int vi = 0;
int vj = 0;
if (key == CODED) {
if (keyCode == UP) {
vi = 0;
vj = -1;
} else if (keyCode == DOWN) {
vi = 0;
vj = 1;
} else if (keyCode == RIGHT) {
vi = 1;
vj = 0;
} else if (keyCode == LEFT) {
vi = -1;
vj = 0;
}
}
if (pi+vi >= 0 && pi+vi <= n-1 && // Si le pion ne va pas dépasser les bords
pj+vj >= 0 && pj+vj <= m-1)
if (grid[pi+vi][pj+vj] == 0) { // Si le pion ne va pas se cogner sur un mur
pi += vi; // Déplacement du pion
pj += vj;
}
}

Exemple : Pacman
On peut assez vite passer à un jeu de type Pacman à partir du code précédent. Pour cela, nous pouvons trouver le morceau de code contenant la description du labyrinthe du jeu dans les commentaires de cette vidéo.

Le code source complet est disponible :

Le code suivant reprend le tableau à 2 dimensions contenant des codes pour décrire chaque case du jeu (1: Mur; 0: Pastille; 8 : Grosse pastille; 6: Vide) inclut dans le code source.

Il suffit alors de quelques modifications au code de la section précédente pour ressembler à un jeu de Pacman (sans fantômes pour le moment).

int n = 28; // Nombre de cases horizontalement
int m = 31; // Nombre de cases verticalement
int a = 32; // Dimension d'une case
int x0 = 0; // Coordonnées du coin supérieur gauche de la grille
int y0 = 0;

int pi = n/2; // Coordonnées initiales du pacman dans la grille
int pj = m/2+2;

// Déclaration d'un tableau 2D pour la grille
int grid[][] = { // 1: Mur 0: Pastille 8 : Grosse pastille 6: Vide
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 8, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 8, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 6, 1, 1, 6, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 6, 1, 1, 6, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 8, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 8, 1},
{1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

void setup() {
size(896,992);
frameRate(25);
}

void draw() {
background(0);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
if (grid[j][i] == 1) { // Mur
fill(0); // Noir
stroke(0,0,255); // Contour bleu
strokeWeight(5);
rect(x,y,a-6,a-6,a/4);
strokeWeight(1);
}
else if (grid[j][i] == 0) { // Pastille
fill(255,255,0); // Jaune
ellipse(x+a/2,y+a/2,a/4,a/4);
}
else if (grid[j][i] == 8) { // Grosse Pastille
fill(255,255,0); // Jaune
ellipse(x+a/2,y+a/2,a/2,a/2);
}
}
}
// Dessin du pion
fill(255,255,0); // Jaune
int x = x0 + pi*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj*a + a/2; // où se trouve le pion
ellipse(x,y,a,a);
grid[pj][pi] = 6; // Avale les pastilles
}

void keyPressed() {
int vi = 0;
int vj = 0;
if (key == CODED) {
if (keyCode == UP) {
vi = 0;
vj = -1;
} else if (keyCode == DOWN) {
vi = 0;
vj = 1;
} else if (keyCode == RIGHT) {
vi = 1;
vj = 0;
} else if (keyCode == LEFT) {
vi = -1;
vj = 0;
}
}
if (pi+vi >= 0 && pi+vi <= n-1 && // Si le pion ne va pas dépasser les bords
pj+vj >= 0 && pj+vj <= m-1)
if (grid[pj+vj][pi+vi] != 1) { // Si le pion ne va pas se cogner sur un mur
pi += vi; // Déplacement du pion
pj += vj;
}
}

Exercice 4 : Ajouter un score
Dans le code ci-dessus, Pacman avale des pastilles. Comme exercice, il faut :
compter le nombre de pastilles avalées par Pacman et en faire un score (1 point par petite pastille; 10 points par grosse pastille).
Afficher le score en grosses lettres au centre du labyrinthe.
Quand le score atteint la valeur correspondant au moment où Pacman à avalé toutes les pastilles, on affiche au centre "GAME OVER".
Correction de l'exercice 4
L'instruction Processing permet d'arrêter l'appel à la méthode de manière indéfinie et ainsi de signaler l'arrêt du jeu.

int n = 28; // Nombre de cases horizontalement
int m = 31; // Nombre de cases verticalement
int a = 32; // Dimension d'une case
int x0 = 0; // Coordonnées du coin supérieur gauche de la grille
int y0 = 0;

int pi = n/2; // Coordonnées initiales du pacman dans la grille
int pj = m/2+2;

int score = 0;

// Déclaration d'un tableau 2D pour la grille
int grid[][] = { // 1: Mur 0: Pastille 8 : Grosse pastille 6: Vide
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 8, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 8, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 6, 1, 1, 6, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 6, 1, 1, 6, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 6, 6, 6, 6, 6, 6, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 6, 6, 6, 1, 6, 6, 6, 6, 6, 6, 1, 6, 6, 6, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 6, 6, 6, 6, 6, 6, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 0, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1},
{1, 8, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 8, 1},
{1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1},
{1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};

void setup() {
size(896,992);
frameRate(25);
textSize(32); // Taille des caractères
textAlign(CENTER,CENTER); // Alignement horizontal et vertical
}

void draw() {
background(0);
// Dessin de la grille
for (int i=0;i<n;i++) { // i numérote les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées (x,y) du coin supérieur gauche de chaque case
int y = y0 + j*a; // en fonction des coordonnées de la grille (i,j)
if (grid[j][i] == 1) { // Mur
fill(0); // Noir
stroke(0,0,255); // Contour bleu
strokeWeight(5);
rect(x,y,a-6,a-6,a/4);
strokeWeight(1);
}
else if (grid[j][i] == 0) { // Pastille
fill(255,255,0); // Jaune
ellipse(x+a/2,y+a/2,a/4,a/4);
}
else if (grid[j][i] == 8) { // Grosse Pastille
fill(255,255,0); // Jaune
ellipse(x+a/2,y+a/2,a/2,a/2);
}
}
}
// Dessin du pion
fill(255,255,0); // Jaune
int x = x0 + pi*a + a/2; // Coordonnées (x,y) du centre de la case
int y = y0 + pj*a + a/2; // où se trouve le pion
ellipse(x,y,a,a);
if (grid[pj][pi] == 0) // Si Pacman avale une petite pastille
score += 1;
if (grid[pj][pi] == 8) // Si Pacman avale une grosse pastille
score += 10;

text("SCORE: "+score,x0 + a*(n/2),y0 + a*(m/2-1) + a/4);

if (score == 282) // Si toutes les pastilles sont avalées
text("GAME OVER",x0 + a*(n/2),y0 + a*(m/2-1) + a/4);
noLoop(); // On arrête le jeu
}
grid[pj][pi] = 6; // Avale les pastilles
}

void keyPressed() {
int vi = 0;
int vj = 0;
if (key == CODED) {
if (keyCode == UP) {
vi = 0;
vj = -1;
} else if (keyCode == DOWN) {
vi = 0;
vj = 1;
} else if (keyCode == RIGHT) {
vi = 1;
vj = 0;
} else if (keyCode == LEFT) {
vi = -1;
vj = 0;
}
}
if (pi+vi >= 0 && pi+vi <= n-1 && // Si le pion ne va pas dépasser les bords
pj+vj >= 0 && pj+vj <= m-1)
if (grid[pj+vj][pi+vi] != 1) { // Si le pion ne va se cogner sur un mur
pi += vi; // Déplacement du pion
pj += vj;
}
}

Exercice 5 : Sommes des lignes et colonnes d'un tableau
Reprendre l'étape 6 du et ajouter en bas et à droite, respectivement les sommes des colonnes et des lignes des nombres du tableau.
Capture d’écran 2020-05-12 à 11.28.43.png
Correction de l'exercice 5
int n = 12; // Nombre de cases horizontalement
int m = 4; // Nombre de cases verticalement
int a = 50; // Dimension d'une case
int x0 = 100; // Coordonnées du coin supérieur gauche de la grille
int y0 = 50;

int c[][] = new int[n][m]; // 1. Déclaration d'un tableau à 2 dimensions

int sommeCol[] = new int[n];
int sommeLig[] = new int[m];

void setup() {
frameRate(2); // Taux de rafraîchissement de 2 Hz
size(800,300);
textSize(20); // Taille des caractères
textAlign(CENTER,CENTER); // Alignement horizontal et vertical
// 2. Initialisation des éléments du tableau à 2 dimensions
for (int i=0;i<n;i++) {
for (int j=0;j<m;j++) {
c[i][j] = (int)random(10);
sommeCol[i] += c[i][j]; // Somme de chaque colonne
sommeLig[j] += c[i][j]; // Somme de chaque ligne
}
}
}

void draw() {
background(200);
for (int i=0;i<n;i++) { // i numérote (les cases de chaque ligne =>) les colonnes
for (int j=0;j<m;j++) { // j numérote les lignes
int x = x0 + i*a; // Coordonnées du coin supérieur gauche de chaque case
int y = y0 + j*a;
fill(255);
rect(x,y,a,a);
fill(0);
if (j == 0) { // Au début de chaque colonne
text(i,x+a/2,y-a/2); // Décalage vertical pour écrire au-dessus des cases
text(sommeCol[i],x + a/2,y + m*a + a/2); // ou en-dessous des cases
}
if (i == 0) { // Au début de chaque ligne
text(j,x-a/2,y+a/2); // Décalage horizontal pour écrire à gauche des cases
text(sommeLig[j],x + n*a + a/2,y + a/2); // ou à droite des cases
}
fill(255,0,0);
text(c[i][j],x+a/2,y+a/2); // 3. Utilisation des éléments du tableau
}
}
}
Exercice récapitulatif
Voici un code qui affiche des mots à des endroits aléatoires dans la fenêtre.

La fonction donne la largeur en pixels d'une chaîne de caractères.

size(800,600);
textSize(32);

String mots[] = {"C'est","le","dernier","exercice"};
int n = mots.length;

background(255);
fill(0);
for(int i=0;i<n;i++) {
int x = (int)(random(width-textWidth(mots[i])));
int y = (int)(random(height-32*2))+32;
text(mots[i],x,y);
}
Capture d’écran 2020-05-17 à 16.13.30.png
Je vous propose une série d'exercices pour développer ce code :

a) Animer les mots pour les faire rebondir sur les bords
b) Donner de nouvelles positions aléatoires aux mots quand on clique dans la fenêtre
c) Surligner en jaune (avec un rectangle) le mot sur lequel on clique
d) Déplacer ce mot sélectionné avec la souris
e) Lorsqu'on clique à nouveau le mot reprend sa couleur initiale et reste à la nouvelle position
Annexe : La fourmi de Langton
Les vidéos suivantes parlent d'un concept qui s'inscrit dans la lignée des exercices et exemples précédents.

Il n'y pas d'obligation d'en prendre connaissance dans le cadre du cours. C'est pour aller plus loin si on veut.

La première vidéo explique ce qu'est la fourmi de Langton.


La seconde montre comment on peut la coder en Processing (en anglais).