coded and optimized tiles rain

This commit is contained in:
Didictateur 2025-04-09 14:29:18 +02:00
parent 3375fb8f7b
commit a5de4b8d85
14 changed files with 379 additions and 16 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -165,7 +165,7 @@
loadScript('test.js', false); loadScript('test.js', false);
//script initial //script initial
loadScript('dp5.js'); loadScript('dp0.js');
</script> </script>
</body> </body>
</html> </html>

View file

@ -0,0 +1,134 @@
import { Rain } from "../rain"
// Configuration globale
const CANVAS_ID = "myCanvas";
const BG_RECT = { x: 0, y: 0, w: 1050, h: 1050 };
const MOUSE = { x: 0, y: 0 };
const FPS = 60; // Réduit de 90 à 60 pour de meilleures performances
const FRAME_INTERVAL = 1000 / FPS;
const RAIN = new Rain();
// Optimisation des références
let animationFrameId: number;
let lastFrameTime = 0;
let accumulatedTime = 0;
const callbacks: Array<() => void> = [];
const timeStep = 1 / FPS;
// Pré-calcul des dimensions
const canvas = document.getElementById(CANVAS_ID) as HTMLCanvasElement;
const ctx = canvas.getContext("2d", { alpha: false }) as NonNullable<CanvasRenderingContext2D>;
canvas.width = BG_RECT.w;
canvas.height = BG_RECT.h;
// Cache statique
const staticCanvas = document.createElement('canvas') as HTMLCanvasElement;
const staticCtx = staticCanvas.getContext("2d", { alpha: false }) as NonNullable<CanvasRenderingContext2D>;
staticCanvas.width = canvas.width;
staticCanvas.height = canvas.height;
// Optimisation du rendu avec requestAnimationFrame
function drawFrame(deltaTime: number) {
if (!ctx) return;
// Mise à jour avec pas de temps fixe pour stabilité physique
accumulatedTime += deltaTime / 1000; // Convertir en secondes
// Mettre à jour la simulation avec un pas de temps fixe
while (accumulatedTime >= timeStep) {
RAIN.update(timeStep);
accumulatedTime -= timeStep;
}
// Optimisation du rendu
staticCtx.fillStyle = "#007730"; // Couleur de fond
staticCtx.fillRect(BG_RECT.x, BG_RECT.y, BG_RECT.w, BG_RECT.h);
// Dessin de la pluie
console.log("draw")
RAIN.drawRain(staticCtx);
// Copier le buffer au canvas principal
ctx.drawImage(staticCanvas, 0, 0);
}
function animationLoop(currentTime: number) {
if (!lastFrameTime) {
lastFrameTime = currentTime;
animationFrameId = requestAnimationFrame(animationLoop);
return;
}
const deltaTime = currentTime - lastFrameTime;
lastFrameTime = currentTime;
// Limiter la fréquence des mises à jour si le navigateur est trop lent
if (deltaTime < 100) { // Ignorer les deltas trop grands (changement d'onglet, etc.)
drawFrame(deltaTime);
}
animationFrameId = requestAnimationFrame(animationLoop);
}
function initEventListeners() {
// Gestion des événements de redimensionnement et de pause
const handleVisibilityChange = () => {
if (document.hidden) {
cancelAnimationFrame(animationFrameId);
lastFrameTime = 0;
} else {
lastFrameTime = performance.now();
animationFrameId = requestAnimationFrame(animationLoop);
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
// Ajouter le nettoyage de l'event listener
callbacks.push(() => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
});
}
export function cleanup() {
cancelAnimationFrame(animationFrameId);
callbacks.forEach(fn => fn());
}
export async function initDisplay() {
if (!ctx) {
console.error("Context canvas indisponible");
return;
}
console.log("Load beginning");
try {
// Préchargement des ressources
await RAIN.preloadRain();
console.log("Loading completed");
// Initialiser les écouteurs d'événements
initEventListeners();
// Démarrer la boucle d'animation avec le temps actuel
lastFrameTime = performance.now();
animationFrameId = requestAnimationFrame(animationLoop);
window.cleanup = cleanup;
} catch (error) {
console.error("Erreur lors de l'initialisation:", error);
}
}
// Déclaration globale pour TypeScript
declare global {
interface Window {
cleanup: () => void;
}
}
// Initialisation automatique si le script est chargé directement
if (typeof window !== 'undefined') {
initDisplay().catch(console.error);
}

View file

@ -6,7 +6,7 @@ import { Game } from "../game"
const CANVAS_ID = "myCanvas"; const CANVAS_ID = "myCanvas";
const BG_RECT = { x: 0, y: 0, w: 1050, h: 1050 }; const BG_RECT = { x: 0, y: 0, w: 1050, h: 1050 };
var MOUSE = { x: 0, y: 0 }; var MOUSE = { x: 0, y: 0 };
const FPS = 30; const FPS = 60;
const FRAME_INTERVAL = 1000 / FPS; const FRAME_INTERVAL = 1000 / FPS;
// variables globales // variables globales

125
src/rain.ts Normal file
View file

@ -0,0 +1,125 @@
import { Tile } from "./tile"
import { Deck } from "./deck"
const G: number = 100;
const SIZE: number = 1;
const LIMIT_MAX = 1100;
const SPAWN_CHANCE = 0.75;
const INITIAL_Y = -150;
const INITIAL_VY = 50;
const MAX_X = 1000;
const ROTATION_FACTOR = Math.PI;
const MOMENTUM_RANGE = 1;
class FallingTile {
private tile: Tile;
private x: number;
private y: number;
private vy: number = INITIAL_VY;
private orientation: number;
private momentum: number;
public constructor(
tile: Tile,
x: number,
y: number,
orientation: number,
momentum: number
) {
this.tile = tile;
this.x = x;
this.y = y;
this.orientation = orientation;
this.momentum = momentum;
}
public update(dt: number): void {
this.vy += dt * G;
this.y += dt * this.vy;
this.orientation += dt * this.momentum;
}
public isOutside(): boolean {
return this.y > LIMIT_MAX;
}
public getTile(): Tile {
return this.tile;
}
public drawFallingTile(ctx: CanvasRenderingContext2D): void {
this.tile?.drawTile(
ctx,
this.x,
this.y,
SIZE,
false,
this.orientation,
false,
false
);
}
}
export class Rain {
private deck: Deck;
private tiles: FallingTile[] = [];
private tileAddTimer: number = 0;
public constructor() {
this.deck = new Deck(true);
}
public update(dt: number): void {
let i = this.tiles.length;
while (i--) {
const tile = this.tiles[i];
tile.update(dt);
if (tile.isOutside()) {
this.deck.push(tile.getTile());
this.tiles.splice(i, 1);
}
}
this.tileAddTimer += dt;
if (this.tileAddTimer >= (1 / SPAWN_CHANCE)) {
this.addFallingTile();
this.tileAddTimer = 0;
} else if (Math.random() < SPAWN_CHANCE * dt) {
this.addFallingTile();
}
}
public addFallingTile(): void {
if (this.deck.length() === 0) {
return;
}
if (this.deck.length() > 1) {
this.deck.shuffle();
}
const newTile = new FallingTile(
this.deck.pop()!,
Math.floor(Math.random() * MAX_X),
INITIAL_Y,
Math.random() * ROTATION_FACTOR,
(Math.random() * 2 - 1) * MOMENTUM_RANGE
);
this.tiles.push(newTile);
}
public drawRain(ctx: CanvasRenderingContext2D): void {
for (const tile of this.tiles) {
tile.drawFallingTile(ctx);
}
}
public async preloadRain(): Promise<void> {
console.log("preload rain");
await this.deck.preload();
}
}

View file

@ -1,4 +1,4 @@
Bienvenu sur ce site dédié au *Mahjong* ! Bienvenue sur ce site dédié au *Mahjong* !
Ce site est principalement destiné aux personnes découvrant ce Ce site est principalement destiné aux personnes découvrant ce
formidable jeu. formidable jeu.
@ -22,7 +22,6 @@ Cependant, de nombreux services y sont proposés:
- *Une introduction au MCR*, la variante chinoise dans l'onglet - *Une introduction au MCR*, la variante chinoise dans l'onglet
#ff00ff{MCR} #ff00ff{MCR}
Evidemment, ce site n'est pas encore fini, et possède encore Evidemment, ce site n'est pas encore fini, et possède encore
beaucoup de problème. Pour le moindre retour, ne pas hésiter beaucoup de problème. Pour le moindre retour, ne pas hésiter
à le faire savoir directement sur le Github pour pour aider à le faire savoir directement sur le Github pour pour aider

View file

@ -70,6 +70,8 @@ export class Tile {
ctx.translate(x + (75 * size) / 2, y + (100 * size) / 2); ctx.translate(x + (75 * size) / 2, y + (100 * size) / 2);
if (tilted) { if (tilted) {
ctx.rotate(rotation + this.tilt); ctx.rotate(rotation + this.tilt);
} else {
ctx.rotate(rotation);
} }
if (hidden) { if (hidden) {