Annuaire › Code ouvert
Code publié par son auteur, en lecture seule. « Copier dans mon espace » crée un nouveau site à vous (non publié) que vous pouvez modifier librement.
js/pirogue.js · 6.3 Ko
/* ============================================================
pirogue.js - la classe Pirogue (le joueur)
============================================================
Une CLASSE est un "moule" : elle décrit à la fois les DONNÉES
d'un objet (position, vitesse...) et ses ACTIONS (se déplacer,
se dessiner...). `new Pirogue()` fabrique un objet à partir du moule.
Vue du dessus : la pirogue est dessinée pointe vers le HAUT, avec
son balancier (le flotteur latéral des pirogues malgaches).
============================================================ */
class Pirogue {
/* constructor : appelé par `new Pirogue()`. */
constructor() {
this.larg = PIROGUE.largeur;
this.long = PIROGUE.longueur;
this.y = PIROGUE.y;
this.reinitialiser();
}
/* ----------------------------------------------------------
reinitialiser()
But : remettre la pirogue au centre pour une nouvelle partie.
---------------------------------------------------------- */
reinitialiser() {
this.x = LARGEUR_JEU / 2;
this.vx = 0; // vitesse horizontale mesurée (pour l'inclinaison)
this.inclinaison = 0; // angle d'inclinaison en radians
this.invulnerable = 0; // secondes d'invulnérabilité restantes
this.tempsPagaie = 0; // sert à animer la pagaie
}
/* ----------------------------------------------------------
limites()
But : donner les positions x minimale et maximale permises,
pour rester sur l'eau (le balancier dépasse à droite).
Retour : {min, max}
---------------------------------------------------------- */
limites() {
return { min: RIVE + 22, max: LARGEUR_JEU - RIVE - 44 };
}
/* ----------------------------------------------------------
mettreAJour(dt, direction, cibleX)
But : déplacer la pirogue.
Paramètres :
dt : secondes écoulées depuis la dernière image
direction : -1 (gauche), 0 (rien), +1 (droite) : clavier
cibleX : abscisse du doigt (monde logique) ou null : tactile
Le clavier est prioritaire sur le doigt.
---------------------------------------------------------- */
mettreAJour(dt, direction, cibleX) {
const xAvant = this.x;
if (direction !== 0) {
// Clavier : déplacement = vitesse x temps.
this.x += direction * PIROGUE.vitesseClavier * dt;
} else if (cibleX !== null) {
// Tactile : on se rapproche du doigt, mais pas plus vite que la
// vitesse maximale (constrain borne l'écart parcouru à chaque image).
const pasMax = PIROGUE.vitesseTactile * dt;
this.x += constrain(cibleX - this.x, -pasMax, pasMax);
}
// On empêche de sortir de l'eau.
const lim = this.limites();
this.x = constrain(this.x, lim.min, lim.max);
// Vitesse réelle (distance / temps) ; on évite de diviser par zéro.
this.vx = dt > 0 ? (this.x - xAvant) / dt : 0;
// Inclinaison : la pirogue "penche" dans le sens du déplacement.
// lerp() adoucit le changement pour éviter un mouvement saccadé.
const inclinaisonVoulue = constrain(this.vx * 0.0007, -0.3, 0.3);
this.inclinaison = lerp(this.inclinaison, inclinaisonVoulue, 0.2);
this.tempsPagaie += dt;
if (this.invulnerable > 0) this.invulnerable -= dt;
}
/* ----------------------------------------------------------
boite()
But : rectangle de collision (un peu plus petit que le dessin,
c'est plus agréable pour le joueur).
Retour : {x, y, l, h} (x, y = coin haut-gauche)
---------------------------------------------------------- */
boite() {
return { x: this.x - 9, y: this.y - 30, l: 18, h: 60 };
}
/* ----------------------------------------------------------
dessiner()
But : dessiner la pirogue.
Pendant l'invulnérabilité, elle CLIGNOTE (une image sur deux
n'est pas dessinée).
---------------------------------------------------------- */
dessiner() {
if (this.invulnerable > 0 && Math.floor(this.invulnerable * 10) % 2 === 0) return;
const L = this.long;
const W = this.larg;
const rebond = Math.sin(this.tempsPagaie * 3) * 1.5; // léger mouvement de houle
push();
translate(this.x, this.y + rebond); // l'origine (0,0) devient le centre de la pirogue
rotate(this.inclinaison); // puis on incline tout le dessin
// --- Sillage derrière la pirogue (deux traînées en V) ---
stroke(255, 255, 255, 120);
strokeWeight(3);
strokeCap(ROUND);
line(-4, L * 0.45, -16, L * 0.45 + 34);
line(4, L * 0.45, 16, L * 0.45 + 34);
// --- Balancier : deux bras + un flotteur long, sur le côté droit ---
stroke(COULEURS.coqueContour);
strokeWeight(3);
line(W * 0.35, -L * 0.18, W * 1.55, -L * 0.18);
line(W * 0.35, L * 0.18, W * 1.55, L * 0.18);
fill(COULEURS.balancier);
strokeWeight(2);
ellipse(W * 1.55, 0, W * 0.5, L * 0.72);
// --- Coque : une forme fermée faite de deux courbes de Bézier ---
// bezierVertex(cx1, cy1, cx2, cy2, x, y) : courbe vers (x, y) avec 2 points de contrôle.
fill(COULEURS.coque);
stroke(COULEURS.coqueContour);
strokeWeight(2);
beginShape();
vertex(0, -L / 2); // proue (pointe avant)
bezierVertex(W * 0.95, -L * 0.2, W * 0.9, L * 0.3, 0, L / 2); // côté droit jusqu'à la poupe
bezierVertex(-W * 0.9, L * 0.3, -W * 0.95, -L * 0.2, 0, -L / 2); // côté gauche en retour
endShape(CLOSE);
// Intérieur de la pirogue (plus sombre)
noStroke();
fill(COULEURS.coqueInterieur);
ellipse(0, 0, W * 0.8, L * 0.62);
// --- Pagaie (à gauche), qui balance avec le temps ---
push();
translate(-W * 0.3, -2);
rotate(Math.sin(this.tempsPagaie * 6) * 0.35);
stroke(COULEURS.pagaie);
strokeWeight(3);
line(0, 0, -W * 0.9, 18);
noStroke();
fill(COULEURS.pagaie);
ellipse(-W * 0.95, 20, 6, 14);
pop();
// --- Le pagayeur vu du dessus : épaules + chapeau de paille ---
noStroke();
fill('#2f6f8f');
ellipse(0, 0, W * 0.85, W * 0.45);
fill(COULEURS.chapeau);
stroke('#b89c3c');
strokeWeight(1.5);
circle(0, -2, W * 0.85);
noFill();
circle(0, -2, W * 0.4);
pop(); // fin du repère de la pirogue : retour au repère normal
}
}