import processing.video.*;
// initialisation
// définition des constantes
PImage citrouille_img; // objet image citrouille
int t_animation_max = 30 * 60 * 30 ; // 30 min * 30 fps
int t_animation; // compteur pour la durée de l'animation avant une nouvelle
int t_disapear; // compteur permettant l'animation citrouille
int t_lr = 5 * 30 ; // durée max de l'animation gauche ou droite ici 5s
int t_fear = 10 * 30; // durée max de l'animation peur ici 10s
int t_laught = 6 * 30; // durée max de l'animation rire ici 6s
int t_angry = 12 * 30; // durée max de l'animation méchant ici 12s
int t_between = 15 * 30; // durée max entre deux animations ici 15s
String[] name_sketch = {"man","femme","girl"};
String[] style_sketch = {"center","left","right","fear","angry","laught","boredom"};
int n_sketch; // numéro de sketch actuel
String sketch_name; // nom du sketch ??
String sketch_style; // position du sketch ??
String event_pos;
Boolean paysage; // permettra de savoir l'orientation de l'Ă©cran principal (si multi-Ă©cran)
Movie[][] collection_movie = new Movie [name_sketch.length][style_sketch.length-1];
class Portrait {
PImage center;
PImage left;
PImage right;
PImage currentimg;
Movie v_current; // video en cours pour l'animation
int pic_height, pic_width; // servira Ă calculer la taille de l'image pour obtenir un plein Ă©cran
int mov_height, mov_width; // servira Ă calculer la taille de la video pour obtenir un plein Ă©cran
int mov_pos;
int t_anim;
String pos;
// constructeur avec les noms et position
Portrait (String name, String style) {
center = loadImage(name+"_immobile.bmp");
left = loadImage(name+"_left.bmp");
right = loadImage(name+"_right.bmp");
//v_current = new Movie(this.v_current,name+"_left.avi");// video left
if (!paysage) { // on est en orientation portrait
pic_width = width*(width/center.height);
pic_height = height*(width/center.height);
} else { // on est en orientation paysage
pic_width = height*(height/center.height);
pic_height = width*(height/center.height);
}
t_anim = 0;
pos = style;
}
// methode pour charger la vidéo actuelle et en changer plus tard
void change_video(Movie m) {
actual_portrait.v_current = m;
actual_portrait.v_current.play(); // chargement de la video pour qu'elle soit prĂȘte Ă dĂ©marrer
actual_portrait.v_current.jump(0); // positionnement au début de la vidéo
actual_portrait.v_current.pause(); // et on met la video en pause
while (actual_portrait.v_current.width == 0) delay(10);
actual_portrait.v_current.loadPixels();
for (int x=0;x<actual_portrait.v_current.width/2;x++) {
for (int y=0; y<actual_portrait.v_current.height/2;y++) {
color p_color = actual_portrait.v_current.pixels[x+y];
if (p_color == -16579837) { // notre pixel n'est pas noir donc on a un début d'image
actual_portrait.mov_width = actual_portrait.v_current.width-2*x;
actual_portrait.mov_height = actual_portrait.v_current.height;
mov_pos = actual_portrait.v_current.pixelWidth;
}
}
}
}
}
Portrait actual_portrait;
Portrait [] tab_portrait = new Portrait[3];
void settings() {
if (displayWidth<displayHeight) { //on est en orientation portrait ce qui est obligatoire pour le meilleur rendu
paysage = false;
} else {
paysage = true;
}
fullScreen(1); // l'application sera joué sur l'écran principal
}
void setup () {
if (millis() < 1000)
((java.awt.Canvas) surface.getNative()).requestFocus(); // permet que l'application ait le focus
surface.setAlwaysOnTop(true); // place l'application sur le devant de l'Ă©cran
surface.hideCursor(); // cache le curseur de la souris
smooth();
imageMode(CENTER); // le référentiel pour afficher n'est pas le coin haut gauche (0,0,) mais le centre de la zone de travail pour un contenu dynamique
translate (width/2, height/2); // on se place justement au centre de l'Ă©cran pour ĂȘtre au point de rĂ©fĂ©rence
n_sketch = 0;
sketch_name = name_sketch[n_sketch]; // on initialise le nom du sketch au premier sketch
sketch_style = style_sketch[0]; // on initialise la position au centre
event_pos = "none"; // on initialise la détection d'évÚnement à aucun évÚnement
t_animation = 0; // compteur pour la durée de l'animation avant une nouvelle
t_disapear = 0; // compteur permettant l'animation citrouille
citrouille_img = loadImage("citrouille2.png");
// chargement de la collection de vidéos
for (int i=0; i<name_sketch.length; i++) {
tab_portrait[i] = new Portrait (name_sketch[i],"center"); // chargement des portraits
for (int j=1; j<style_sketch.length; j++) {
collection_movie [i][j-1] = new Movie(this,name_sketch[i]+"_"+style_sketch[j]+".mp4");
}
}
actual_portrait = tab_portrait[n_sketch];
actual_portrait.change_video(collection_movie [0][3]); //chargement de fear Ă remplacer par ennui plus tard
actual_portrait.currentimg = actual_portrait.center;
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image(actual_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height); // affiche l'image center aux coordonnées 0,0 => !
// v
}
// animation
void draw() {
imageMode(CENTER); // le référentiel pour afficher n'est pas le coin haut gauche (0,0,) mais le centre de la zone de travail pour un contenu dynamique
translate (width/2, height/2); // on se place justement au centre de l'Ă©cran pour ĂȘtre au point de rĂ©fĂ©rence
if (millis() < 1000)
((java.awt.Canvas) surface.getNative()).requestFocus(); // permet que l'application ait le focus
// ce taux a été défini car équivalent au fps des vidéos fournies
frameRate(23.96); // vitesse d'animation 23.96 appels de draw() = 23.96 fps qui est la vitesse de nos animations
// on recherche un événement
detect_event();
if (actual_portrait.t_anim == t_animation_max) {
// marre de l'animation, on passe Ă une autre !!
if (t_disapear++ <= 5 * 23.96 ) {
Citrouille(t_disapear); // affichage dans la console du nombre de fois que la fonction draw a été affichée
} else {
t_animation = 0;
t_disapear = 0;
actual_portrait.t_anim = 0;
}
} else {
// on continue l'animation en cours
t_animation += 1;
// evenement arduino
play_anim(actual_portrait, event_pos);// sequence video ou image
}
}
// animation citrouille
// est lancée toutes les t_animation_max
// permet d'afficher des citrouilles au hasard dans l'Ă©cran pour tout le couvrir
// et permettre le changement de sketches vidéo
void Citrouille (int t) {
if (t == 1) { // on ne change le sketch qu'une fois, juste Ă la fin
if (n_sketch<name_sketch.length-1) {
n_sketch +=1;
} else {
n_sketch = 0;
}
actual_portrait = tab_portrait[n_sketch];
actual_portrait.change_video(collection_movie [n_sketch][3]); //chargement de fear Ă remplacer par ennui plus tard
actual_portrait.currentimg = actual_portrait.center;
}
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image(citrouille_img, random(width+2*citrouille_img.width)-citrouille_img.width,random(height+2*citrouille_img.height)-citrouille_img.height);
}
// animation de tableau vivant
//
void play_anim(Portrait n_portrait, String event_name) {
println(event_name);
println(n_portrait.pos);
n_portrait.t_anim +=1;
if (event_name == "none") { // il n'y a pas eu de nouvel Ă©vĂ©nement => on reste sur la mĂȘme animation
switch (n_portrait.pos) {
case "center" :
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image(n_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "left":
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.left,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "right" :
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.right,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "fear" :
println("f");
n_portrait.v_current.play();
PImage mS = n_portrait.v_current.get();
int vh = height/mS.height;
int x = 40; // problĂšme de convertion de la taille de la video du Ă cet ajout de bande noire dont j'ignore la provenance
mS.resize(mS.width*vh+x,mS.height*vh+x);
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image(mS,0,0);
break;
case "angry" :
break;
case "laught" :
break;
case "boredom" :
break;
}
} else {
n_portrait.pos = event_name;
switch (n_portrait.pos) {
case "center" :
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.center,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "left":
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.left,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "right" :
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.right,0,0,actual_portrait.pic_width,actual_portrait.pic_height);
break;
case "fear" :
// n_portrait.v_current.jump(n_portrait.t_anim/25);
println("a");
//n_portrait.v_current.read();
n_portrait.v_current.play();
if (paysage) // si on est en orientation paysage, il faut faire pivoter l'image
rotate (HALF_PI); // pour ĂȘtre dans le mĂȘme sens que pour le portrait il faudrait mettre -HALF_PI
image (n_portrait.v_current,0,0,actual_portrait.mov_width,actual_portrait.mov_height);
//n_portrait.currentimg = img;
break;
case "angry" :
break;
case "laught" :
break;
case "boredom" :
break;
}
}
}
void detect_event() {
if (keyPressed == true) {
if (key == CODED) {
if (keyCode == LEFT) event_pos = "left";
if (keyCode == RIGHT) event_pos = "right";
if (keyCode == UP) event_pos = "fear";
if (keyCode == DOWN) event_pos = "angry";
if (keyCode == CONTROL) event_pos = "laught";
} else {
switch (key) { // on a demandé à quitter le programme
case ESC :
println ("good bye");
exit();
break;
}
}
} else event_pos = "none";
}
// fonction pour lecture de l'image suivante dans la video
void movieEvent(Movie m) {
m.read();
}