Your target is watching you
De Centre de Ressources Numériques - Labomedia
Révision de 24 janvier 2015 à 16:46 par Olivier (discussion | contributions)
Your target is watching you |
---|
Pour modifier la page utiliser l'onglet Modifier avec formulaire.
Résumé | Sketch Processing qui produit des GIF animés |
---|---|
Auteur(s) | Olivier |
Licence | CC-BY-SA 3 |
Date de création | 10 novembre 2014 |
Sommaire
Intentions / Contexte
Faire un truc rigolo.
Principe de fonctionnement
On clique sur des petites bouboules qui changent de couleur et rebondissent et on exporte le tout en un GIF animé de 10 images.
Besoins / Compétences
Développement sous Processing
Documentation
Code Source
// Ce script permet de produire des motifs animés
// et de les exporter en un GIF qui boucle sur lui-même
// Click pour dessiner/effacer
// 'x' pour tout effacer
// 'w' pour inverser
// 's' pour exporter le GIF
// copyright Olivier Baudu 2014 pour le http://labomedia.net
// Publié sous les termes de la license GPL v3.0
import gifAnimation.*;
Cible[] motif;
GifMaker gifExport;
Boolean save;
int non_modifiable;
int wait;
int start_frame;
void setup() {
motif = new Cible[283];
save = false;
wait = 0;
size(400, 400);
smooth();
strokeWeight(3);
frameRate(60);
for (int i = 0; i < motif.length; i++) {
motif[i] = new Cible(i);
}
}
void draw() {
background(0);
// Pour chaque élément du tableau...
for (int i = 0; i < motif.length; i++) {
//...l'afficher en plaçant l'oeil en fonction du curseur
motif[i].affiche(mouseX, mouseY);
// si l'élément est survolé
// et qu'un bouton de la souris est enfoncé
// et que l'élément est modifiable
if ( motif[i].survol(mouseX, mouseY) &
mousePressed == true &
non_modifiable != i ) {
// changer l'état de l'élément
motif[i].onOff();
// définir cet élément comme non modifiable pendant 1 seconde
non_modifiable = i;
wait = int(frameRate);
}
}
// si le temps d'attente est écoulé
if (wait == 0) {
// plus aucun élément n'est "non modifiable"
non_modifiable = -1;
} else wait--;
// si la sauvegarde a été activé
if (save) {
// compte les images qui se sont écoulées
int nb = frameCount-start_frame;
// si ce nombre est inférieur à 10
if (nb < 11) {
// ajouter l'image au GIF
gifExport.setDelay(1);
gifExport.addFrame();
} else {
// sinon exporter le GIF
save = false;
gifExport.finish();
}
}
}
void keyPressed () {
// si 's' est pressé, la sauvegarde est activée
// et un GIF vierge créé
if (key == 's') {
save = true;
start_frame = frameCount;
gifExport = new GifMaker(this, str(frameCount)+"cible.gif");
gifExport.setRepeat(0);
}
// si 's' est pressé, tous les éléments ont leur état passé à OFF
if (key == 'x') {
for (int i = 0; i < motif.length; i++) {
motif[i].reset();
}
}
// si 's' est pressé, tous les éléments ont leur état inversé
if (key == 'w') {
for (int i = 0; i < motif.length; i++) {
motif[i].inverse();
}
}
}
class Cible {
int x, y, y_init;
int tmps;
int nbPixParLigne;
int taille;
color actual_color, on_color, off_color;
Boolean on;
Cible (int num) {
tmps = 0;
nbPixParLigne = 11;
taille = 50;
on_color = color(0);
off_color = color(255);
actual_color = off_color;
on = false;
// calcule la position de chaque cible
x = num%nbPixParLigne * taille + (num/nbPixParLigne%2*taille/2);
y = num/nbPixParLigne * taille/3;
y_init = y;
}
void affiche(int xM, int yM) {
// actualise la position de l'élément au besoin
bond();
fill(actual_color);
stroke(0);
// dessine des ronds concentriques
for (int i=5; i > 1; i--) {
ellipse(x, y, i*10, i*10);
}
// calcule la position de l'oeil
// en la contraingant dans une zone
float xO = x-constrain((x-xM)/25, -4, 4);
float yO = y-constrain((y-yM)/25, -4, 4);
noStroke();
fill(0);
// affiche l'oeil
ellipse(xO, yO, 10, 10);
}
Boolean survol(int xM, int yM) {
// vérifie si le curseur est sur la cible
return xM >= x-12 & xM <= x+12 & yM >= y-12 & yM <= y+12;
}
void onOff() {
// inverse l'état et la couleur de l'élément
on = !on;
if (on) actual_color = on_color;
else actual_color = off_color;
}
void reset() {
// affecte à l'élément l'état OFF et la couleur associée
on = false;
actual_color = off_color;
}
void inverse() {
onOff();
if (on) {
tmps = int(random(0, 10))*36;
}
}
void bond() {
// si l'état est ON, ou qu'il est OFF mais pas à sa position initiale
if ((on) | (!on & tmps != 0)) {
// simule un bond l'élément en s'appuyant sur la fonction cosinus
y -= 5*cos(radians(tmps));
// ajoute 36 à la variable "bondissante"
// c'est ici que réside "l'astuce" car 360°/10 = 36°
// il n'y a donc que 10 positions pour chaque élément
// ce qui rend possible un export en GIF de 10 images
tmps +=36;
// remet la variable à zéro si elle est égale à 360
if (tmps == 360) {
tmps = 0;
y = y_init;
}
}
}
}