/* @pjs preload="images/piquet0.png"; @pjs preload="images/piquet1.png"; @pjs preload="images/face.png"; @pjs preload="images/droite1.png"; @pjs preload="images/gauche1.png"; @pjs preload="images/droite2.png"; @pjs preload="images/gauche2.png"; */ /** declaration des images */ PImage imageUsager; PImage imageUsagerGauche; PImage imageUsagerDroite; PImage imageUsagerGauche2; PImage imageUsagerDroite2; PImage orienteUsager; PImage imgPiquet0 ; PImage imgPiquet1 ; class Usager { float posX, posY, deltaX; float vX, vY; float periode, phi, x0; // periode en secondes PImage image = imgPiquet0; int tintR, tintB, tintG; // pour modifier la couleur du skieur void init(float posY) { float x0temp = 0.1 * random(width/8.0, width/4.0); this.posX = random(width/4, 3*width/4); this.posY = posY; this.vY = random(4, 12); this.periode = 0.18*x0temp; this.phi = random(0, 6.28); this.x0 = x0temp; // this.image = image; this.tintR = int(random(100,250)); this.tintG = int(random(100,250)); this.tintB = int(random(100,250)); } void dessine() { this.deltaX = this.x0 * sin(2*PI * millis()/(1000 * this.periode) + this.phi); this.posX += deltaX; tint(this.tintR, this.tintG, this.tintB); this.posY += (this.vY - vitesseSkieur); if (this.posY < -40) { this.init( height+40, this.image); } if (this.posY > height+140) { this.init( -40, this.image); } // ellipse(this.posX, this.posY, 20, 20); } } /*** Déclarations du tableau */ Usager usagers[]; void setupUsagers() { usagers = new Usager[nombreUsagers]; // Creation du tableau for (int i = 0; i < nombreUsagers; i++) { usagers[i] = new Usager(); float x0i = random(width/4); usagers[i].init( height+40+random(100*nombreUsagers)); } } void dessineUsagers() { for (int i =0; i 12) orienteUsager = imageUsagerDroite2; else if (usagers[i].deltaX > 4) orienteUsager = imageUsagerDroite; else if (usagers[i].deltaX > -4) orienteUsager = imageUsager; else if (usagers[i].deltaX > -12) orienteUsager = imageUsagerGauche; else orienteUsager = imageUsagerGauche2; image(orienteUsager, usagers[i].posX-33, usagers[i].posY-33); tint(0); } } class Piquet { float posX, posY, vY; // la position du piquet int cote; // -1 pour à gauche, +1 pour à droite float bezierPhiUp, bezierPhiDown; // le dephasage de la corde int bezierXUp, bezierYUp, bezierXDown, bezierYDown; float bezierOmega = 2*PI/1; PImage imagePiquet = imgPiquet0; // l'image du piquet void init(int cote, PImage image, float abscisse, float ordonnee) { this.posX = abscisse; this.posY = ordonnee; this.imagePiquet = image; this.cote = cote; this.bezierPhiUp = random(0, 6.28); this.bezierPhiUp = random(0, 6.28); } } /*** Déclarations des 2 tableaux de pquets */ Piquet[] piquetsDroite; Piquet[] piquetsGauche; /*** Création des premiers piquets */ void setupPiquets(){ piquetsGauche = new Piquet[6]; // Creation du tableau piquetsDroite = new Piquet[6]; // Creation du tableau placePiquets(piquetsDroite, -1); // on place les 6 premiers piquets d'un coté... placePiquets(piquetsGauche, 1); // ...et de l'auter } /*** Placement des premiers piquets */ void placePiquets(Piquet piquets[], int cote) { // PImage imgPiquet0 = loadImage("images/piquet0.png"); // image 12x48 px // PImage imgPiquet1 = loadImage("images/piquet1.png"); // image 12x48 px for (int i=0; i < 6; i++) { // pour les 6 piquets piquets[i] = new Piquet(); // on crée le piquet PImage img = imgPiquet0; if (int(random(0, 3)) > 1) img = imgPiquet1; // une image sur deux au hasard piquets[i].init( cote, img, width/2 + largeurCouloir * cote*random(width/2-50, width/2-5) / 100, 200*i); // on initialise le piquet en fixant ses propriétés initiales } } /*** Dessin des piquets, fonction appelée dans la boucle, une fois par tableau */ void dessinePiquets(Piquet piquets[]) { for (int i=0; i < 6; i++) { // on deplace les 6 piquets comme si de rien n'était.... piquets[i].posY -= vitesseSkieur; // le piquet se déplace verticalement a la vitesse du skieur, mais vers le haut if (piquets[i].posY < -200) { // si le piquet est sorti de l'écran (par le haut) avec une marge pour que la corde se trace // PImage imgPiquet0 = loadImage("images/piquet0.png"); // image 12x48 px // PImage imgPiquet1 = loadImage("images/piquet1.png"); // image 12x48 px PImage img = imgPiquet0; if (int(random(0, 3)) > 1) { // choix aleatoire d'une image sur deux img = imgPiquet1; } piquets[i].init( piquets[i].cote, // on ré-initialise le piquet pour continuer la boucle img, //la position du piquet dépend : de son coté, de la largeur du couloir, ondule dans l'espace disponible avec le temps (todo : periode fonction de vitesseSkieur) // il est positionné de part et d'autre du centre de la fenetre width/2 + piquets[i].cote * random(width/2-100, width/2) * largeurCouloir / 100 + sin(2*PI*millis()/10000) * width/2 * (100-largeurCouloir)/100, 1000 ); } image(piquets[i].imagePiquet, piquets[i].posX-3, piquets[i].posY); // on dessine le piquet noFill(); // pour que l'interieur des splines soit invisible stroke(255, 0, 0); // cordes en rouge if (i == 0) { // on trace la corde entre les piquet0 et piquet6 if (piquets[0].posY>piquets[5].posY) { // ... seulement si p0 est en dessous de p6 bezier( piquets[5].posX, piquets[5].posY, // la corde est une courbe de bezier piquets[5].posX+ 20*sin(omegaPiquet*millis()/1000 + piquets[0].bezierPhiUp), piquets[5].posY + 80, // la tangente varie avec le temps et bezierPhi piquets[0].posX+ 20*sin(omegaPiquet*millis()/1000 + piquets[0].bezierPhiUp), piquets[0].posY, piquets[0].posX, piquets[0].posY); } } else { // on trace la corde entre un piquet et son precedent (sauf entre piquet0 et piquet6) ... if (piquets[i].posY>piquets[i-1].posY) { // ... seulement si p[i] est en dessous de p[i-1] bezier( piquets[i-1].posX+5, piquets[i-1].posY, piquets[i-1].posX+ 20*sin(omegaPiquet*millis()/1000 + piquets[i].bezierPhiUp), piquets[i-1].posY + 80, piquets[i].posX+ 20*sin(omegaPiquet*millis()/1000 + piquets[i].bezierPhiUp), piquets[i].posY, piquets[i].posX+5, piquets[i].posY); } } } } int vitesseSkieur = 10; // mis ici pour le défilement de la piste et des obstacles, à terme devra etre lié à la propriété vY du skieur "skieur.vY" int largeurCouloir = 60; // largeur de la piste en % de l'écran float omegaPiquet = 2*PI/2; // pulsation de l'ondulation de la corde de bord de piste, periode de 2 secondes int largeurEcran = 800; int hauteurEcran = 600; int nombreUsagers = 4; void keyPressed(){ if (key == 'a' && vitesseSkieur>1) vitesseSkieur--; // 'a' ralentit if (key == 'z' && vitesseSkieur<20) vitesseSkieur++; // 'z' accelere if (key == 's' && largeurCouloir>10) largeurCouloir -= 5; // 's' retrecit couloir if (key == 'q' && largeurCouloir<100) largeurCouloir += 5; // 'q' elargit couloir println(vitesseSkieur+", "+largeurCouloir); } void setup() { frameRate(30); size(largeurEcran, hauteurEcran); imageUsager = loadImage("images/face.png"); imageUsagerGauche = loadImage("images/gauche1.png"); imageUsagerDroite = loadImage("images/droite1.png"); imageUsagerGauche2 = loadImage("images/gauche2.png"); imageUsagerDroite2 = loadImage("images/droite2.png"); imgPiquet0 = loadImage("images/piquet0.png"); imgPiquet1 = loadImage("images/piquet1.png"); setupPiquets(); // bords de piste par raph setupUsagers(); } void draw() { background(255, 255, 255, 50); dessinePiquets(piquetsDroite); // bord droit de la piste dessinePiquets(piquetsGauche); // bord gauche de la piste dessineUsagers(); }