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/sketch.js · 6.8 Ko
/* ============================================================
sketch.js - point d'entrée : setup(), draw() et entrées
============================================================
Ce fichier fait le lien entre p5.js et la classe Jeu :
- setup() : crée le canevas et l'objet Jeu (une fois) ;
- draw() : lit les entrées, met à jour et dessine (60 fois/s) ;
- touches, souris, doigt : transmis à Jeu ;
- windowResized() : adapte le canevas à l'écran.
POURQUOI scale() ? Le jeu "pense" en 360 x 640 unités. Le canevas
réel a une autre taille (téléphone, ordinateur...). scale(f)
agrandit tout le dessin du facteur f ; et pour les positions du
doigt, on fait l'opération inverse (division par f).
============================================================ */
/* ---------- Variables globales ---------- */
let jeu; // l'unique objet Jeu
let facteurEchelle = 1; // rapport canevas réel / monde logique
let dernierAppui = -1000; // instant (ms) du dernier appui : évite de compter deux fois un même toucher
let erreurSignalee = false; // pour n'afficher une éventuelle erreur qu'une fois dans la console
/* ------------------------------------------------------------
calculerTaille()
But : calculer la taille du canevas, toujours au format 9:16 (portrait),
en respectant la largeur ET la hauteur disponibles.
Retour : {w, h} en pixels
------------------------------------------------------------ */
function calculerTaille() {
const boite = document.getElementById('conteneur-jeu');
const dispo = boite ? boite.clientWidth : windowWidth; // largeur disponible dans la page
let w = Math.min(dispo, LARGEUR_CANVAS_MAX);
// On limite aussi pour que le canevas tienne dans la hauteur de la fenêtre.
const largeurMaxSelonHauteur = (windowHeight - MARGE_VERTICALE) * LARGEUR_JEU / HAUTEUR_JEU;
w = Math.min(w, largeurMaxSelonHauteur);
w = Math.max(w, LARGEUR_CANVAS_MIN);
const largeurEntiere = Math.floor(w);
return { w: largeurEntiere, h: Math.floor(largeurEntiere * HAUTEUR_JEU / LARGEUR_JEU) };
}
/* ------------------------------------------------------------
setup() : appelée UNE fois au démarrage par p5.
------------------------------------------------------------ */
function setup() {
const t = calculerTaille();
createCanvas(t.w, t.h).parent('conteneur-jeu');
facteurEchelle = t.w / LARGEUR_JEU;
frameRate(60); // 60 images par seconde visées
textFont(POLICE);
jeu = new Jeu();
describe("Jeu : une pirogue à balancier, vue du dessus, glisse sur l'eau. Il faut ramasser des gousses de vanille et éviter les rochers et les vagues. Se joue aux flèches, à Q et D, ou au doigt.");
}
/* ------------------------------------------------------------
draw() : appelée en boucle par p5 (≈ 60 fois par seconde).
deltaTime = millisecondes écoulées depuis l'image précédente.
On le convertit en secondes et on le BORNE à 0,05 s : si l'onglet
était en pause, on évite un énorme "saut" de la pirogue ou des obstacles.
------------------------------------------------------------ */
function draw() {
try {
const dt = Math.min(deltaTime / 1000, 0.05);
jeu.mettreAJour(dt, lireEntrees());
push();
scale(facteurEchelle); // à partir d'ici, on dessine en unités logiques
jeu.dessiner();
pop();
} catch (e) {
// Filet de sécurité : une erreur ne doit pas figer la boucle d'animation.
if (!erreurSignalee) {
console.error('Erreur dans draw() :', e);
erreurSignalee = true;
}
resetMatrix();
}
}
/* ------------------------------------------------------------
lireEntrees()
But : lire clavier et doigt/souris, et les résumer en deux valeurs.
Retour : {direction, cibleX}
direction : -1 (gauche), 0, +1 (droite) d'après le clavier
cibleX : abscisse (monde logique) du doigt/souris appuyé, sinon null
keyIsDown(code) : vrai tant qu'une touche est maintenue.
Codes : LEFT_ARROW / RIGHT_ARROW (flèches) ; 81 = Q, 65 = A, 68 = D.
------------------------------------------------------------ */
function lireEntrees() {
let direction = 0;
if (keyIsDown(LEFT_ARROW) || keyIsDown(81) || keyIsDown(65)) direction -= 1;
if (keyIsDown(RIGHT_ARROW) || keyIsDown(68)) direction += 1;
let cibleX = null;
if (touches.length > 0) {
cibleX = touches[0].x / facteurEchelle; // `touches` : liste des doigts posés
} else if (mouseIsPressed) {
cibleX = mouseX / facteurEchelle; // souris : bouton enfoncé
}
return { direction: direction, cibleX: cibleX };
}
/* ------------------------------------------------------------
gererAppui(px, py)
But : traiter un appui (souris ou doigt) en coordonnées canevas.
Retour : false si l'appui était sur le canevas (cela bloque le
comportement par défaut du navigateur : défilement, etc.),
true sinon (la page garde son comportement normal).
------------------------------------------------------------ */
function gererAppui(px, py) {
if (px < 0 || px > width || py < 0 || py > height) return true; // hors du canevas
// Sur certains appareils, un toucher déclenche aussi un "clic" simulé :
// on ignore le second événement s'il arrive tout de suite après le premier.
if (millis() - dernierAppui < 350) return false;
dernierAppui = millis();
jeu.appuyer(px / facteurEchelle, py / facteurEchelle); // division : retour au monde logique
return false;
}
/* Fonctions appelées automatiquement par p5 : */
function mousePressed() {
return gererAppui(mouseX, mouseY);
}
function touchStarted() {
if (touches.length > 0) return gererAppui(touches[0].x, touches[0].y);
return true;
}
/* ------------------------------------------------------------
keyPressed() : appelée une fois à chaque pression de touche.
Variables p5 : key (le caractère), keyCode (le code de la touche).
------------------------------------------------------------ */
function keyPressed() {
jeu.sons.activer();
if (keyCode === ENTER || keyCode === 32) { // 32 = barre d'espace
jeu.actionPrincipale();
}
if (key === 'm' || key === 'M') {
jeu.sons.basculerMuet();
}
// Pour les flèches et l'espace, on empêche le défilement de la page.
if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW ||
keyCode === UP_ARROW || keyCode === DOWN_ARROW || keyCode === 32) {
return false;
}
}
/* ------------------------------------------------------------
windowResized() : adapte le canevas si la fenêtre change
(rotation du téléphone...). Le jeu garde son monde logique.
------------------------------------------------------------ */
function windowResized() {
const t = calculerTaille();
resizeCanvas(t.w, t.h);
facteurEchelle = t.w / LARGEUR_JEU;
}