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/scene.js · 6.4 Ko
/* ==========================================================================
* js/scene.js — L'ASSEMBLAGE DE LA SCÈNE 3D
* --------------------------------------------------------------------------
* Ce fichier ne dessine presque rien lui-même : il APPELLE les fabriques des
* autres fichiers (mer, palmier, pirogue, ciel) et les place dans le diorama.
* Il construit aussi l'île : une plage (disque de sable) et une colline à
* deux bosses (deux demi-sphères).
*
* Il offre à main.js une interface très simple :
* scene.mettreAJour(t, dt, heure) -> à chaque image
* scene.appliquerPalette(p) -> quand l'heure change
*
* Dépend de : Zdog, Baie.CONFIG, Baie.QUALITE, Baie.tirerVersLeFond, et des
* fabriques Baie.creerMer, creerPalmier, creerPirogue, creerCiel.
* ========================================================================== */
(function () {
'use strict';
var TAU = Zdog.TAU;
// ---- Constantes réglables -------------------------------------------------
// Les palmiers : position au sol (x, z), hauteur, inclinaison, orientation,
// graine. Ils sont placés AUTOUR de la colline, sur la plage (rayon ≈ 75).
// Sur mobile, on n'utilise que les premiers de la liste.
var PALMIERS = [
{ x: 58, z: 28, hauteur: 46, penche: 12, orientation: 0.4, graine: 3 },
{ x: -62, z: 20, hauteur: 52, penche: -14, orientation: 2.5, graine: 8 },
{ x: 34, z: 58, hauteur: 40, penche: 10, orientation: 1.0, graine: 15 },
{ x: -30, z: -62, hauteur: 50, penche: 12, orientation: -0.5, graine: 21 },
{ x: 60, z: -30, hauteur: 44, penche: -10, orientation: 3.8, graine: 33 },
{ x: -10, z: 52, hauteur: 36, penche: 8, orientation: 2.0, graine: 40 },
];
/**
* Construit l'île : plage + colline.
*
* @param {Zdog.Anchor} parent Où l'accrocher.
* @returns {Object} { appliquerPalette(p) }
*/
function creerIle(parent) {
// 1) LA PLAGE MOUILLÉE : un grand disque couché, un peu plus large.
// Une Ellipse n'a qu'un `diameter` pour un cercle. Elle regarde vers z
// par défaut ; rotate x = TAU/4 la COUCHE (sa face regarde vers le haut).
var plageMouillee = new Zdog.Ellipse({
addTo: parent,
diameter: 172,
rotate: { x: TAU / 4 },
translate: { y: 1 },
fill: true,
stroke: false,
color: '#d9c48f',
});
// Juste après la mer (qui est à -1 000 000), avant tout le reste.
Baie.tirerVersLeFond(plageMouillee, -500001);
// 2) LA PLAGE SÈCHE : un disque un peu plus petit, posé dessus.
var plage = new Zdog.Ellipse({
addTo: parent,
diameter: 152,
rotate: { x: TAU / 4 },
translate: { y: -0.5 },
fill: true,
stroke: false,
color: '#f2deaa',
});
Baie.tirerVersLeFond(plage, -500000);
// 3) LA COLLINE : deux demi-sphères (Hemisphere).
// Une Hemisphere a son dôme tourné vers z ; rotate x = TAU/4 le redresse
// vers le HAUT. Sa base est un disque dont la couleur est `backface`.
// stroke: false => bord net, sans contour.
var colline1 = new Zdog.Hemisphere({
addTo: parent,
diameter: 104,
translate: { x: -18, z: -14 },
rotate: { x: TAU / 4 },
stroke: false,
color: '#6fcf5a',
backface: '#f2deaa',
});
var colline2 = new Zdog.Hemisphere({
addTo: parent,
diameter: 64,
translate: { x: 24, z: 6 },
rotate: { x: TAU / 4 },
stroke: false,
color: '#6fcf5a',
backface: '#f2deaa',
});
var tmp = [0, 0, 0];
/** Recolore l'île selon la palette. */
function appliquerPalette(p) {
plage.color = p.css.sable;
plageMouillee.color = Baie.Palette.nuancer(p.rgb.sable, -0.12, tmp);
colline1.color = p.css.herbe;
colline1.backface = p.css.sable;
// La 2e bosse est un peu plus claire : elle reçoit plus de lumière.
colline2.color = Baie.Palette.nuancer(p.rgb.herbe, 0.1, tmp);
colline2.backface = p.css.sable;
}
return { appliquerPalette: appliquerPalette };
}
/**
* Construit TOUTE la scène (île, mer, palmiers, pirogue, ciel).
*
* @param {Zdog.Illustration} illo L'illustration à laquelle accrocher la scène.
* @returns {Object} { monde, mettreAJour(t, dt, heure), appliquerPalette(p) }
*/
function creerScene(illo) {
var Q = Baie.QUALITE;
// Le « monde » : une ancre qui contient tout. On la descend un peu pour
// que le point de rotation (centre de l'illustration) soit au milieu de la
// scène plutôt qu'au niveau de la mer.
var monde = new Zdog.Anchor({
addTo: illo,
translate: { y: Baie.CONFIG.decalageVertical },
});
// L'ordre de création n'a pas d'importance pour l'affichage : Zdog trie
// par profondeur (et nos astuces tirerVersLeFond gèrent mer et plage).
var mer = Baie.creerMer(monde);
var ile = creerIle(monde);
// Les palmiers : une BOUCLE sur la liste de réglages, une fabrique par palmier.
var palmiers = [];
for (var i = 0; i < Math.min(Q.palmiers, PALMIERS.length); i++) {
palmiers.push(Baie.creerPalmier(monde, PALMIERS[i]));
}
var pirogue = Baie.creerPirogue(monde, mer);
var ciel = Baie.creerCiel(monde);
/**
* Fait avancer toute la scène d'une image. À appeler à chaque image.
* AUCUNE création d'objet ici : seulement des nombres modifiés.
*
* @param {number} t Temps d'animation (s). Ne progresse pas en pause.
* @param {number} dt Durée de l'image (s). Vaut 0 en pause.
* @param {number} heure Heure de la journée (0 à 24), pour placer soleil et lune.
*/
function mettreAJour(t, dt, heure) {
mer.mettreAJour(t);
for (var i = 0; i < palmiers.length; i++) { palmiers[i].mettreAJour(t); }
pirogue.mettreAJour(t, dt);
ciel.mettreAJour(t, dt);
ciel.placerAstres(heure);
}
/**
* Applique une palette de couleurs à tous les éléments.
* Appelée seulement quand l'heure a changé (pas à chaque image).
* @param {Object} p Palette (Baie.Palette.calculer()).
*/
function appliquerPalette(p) {
mer.appliquerPalette(p);
ile.appliquerPalette(p);
for (var i = 0; i < palmiers.length; i++) { palmiers[i].appliquerPalette(p); }
pirogue.appliquerPalette(p);
ciel.appliquerPalette(p);
}
return { monde: monde, mettreAJour: mettreAJour, appliquerPalette: appliquerPalette };
}
Baie.creerScene = creerScene;
})();