coded and optimized tiles rain
This commit is contained in:
parent
3375fb8f7b
commit
a5de4b8d85
14 changed files with 379 additions and 16 deletions
111
build/dp0.js
111
build/dp0.js
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
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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
125
src/rain.ts
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue