🧱 Casse-briques néon

Un casse-briques rétro à l'ambiance néon. Bougez la souris pour déplacer la raquette, cliquez pour lancer la balle. Certaines briques libèrent des power-ups: balle supplémentaire ou raquette élargie.

Casse-briques néon

Bougez la souris pour viser, cliquez pour lancer la balle.

Score: 0 Vies: 3 Niveau: 1

Comment jouer

La raquette suit la souris à l'horizontale et le curseur est masqué au-dessus du cadre. Un clic lance la balle; sur écran tactile, un doigt fait les deux à la fois. On part avec trois vies et une grille de 45 briques réparties sur 5 rangées de 9.

Les briques du haut valent 50 points, celles du bas 10: la rangée la plus payante est aussi la plus difficile à atteindre. Environ une brique détruite sur cinq laisse tomber un power-up. Le jaune marqué W élargit la raquette de 70 % pendant huit secondes, le turquoise marqué +B ajoute une balle en jeu. Quand la grille est vide, le niveau suivant se dessine et la balle repart plus vite.

Comment c'est construit

Tout le contact passe par une seule fonction, circleRectCollision. Je ramène le centre de la balle sur le point le plus proche du rectangle avec deux bornages successifs, puis je compare la distance au carré au rayon au carré. Aucune racine carrée, et le même test sert pour la raquette, pour les briques et pour la capture des power-ups.

Le rebond sur la raquette n'est pas une réflexion physique, et c'est délibéré. Je calcule hitPos, la position du contact normalisée entre -1 et 1 par rapport au centre de la raquette, et j'en dérive directement un angle de sortie qui balaie soixante degrés de chaque côté de la verticale. Frapper avec le bord envoie la balle en biais, frapper au centre la renvoie droit. C'est exactement ce qui rend la raquette pilotable au lieu d'être subie.

La vitesse est recalculée à chaque contact avec la raquette, en gardant le plus grand entre la vitesse actuelle et BASE_BALL_SPEED augmenté de 25 px/s par niveau franchi. Comme les rebonds sur les murs et sur les briques ne font qu'inverser un signe, la norme reste constante entre deux touches de raquette. Effet de bord que j'ai remarqué en relisant: launchBalls utilise la vitesse de base sans le bonus de niveau, donc au niveau quatre la balle n'atteint sa vitesse annoncée qu'après avoir touché la raquette une première fois.

Sur les briques, l'axe du rebond est choisi en comparant le chevauchement horizontal et le chevauchement vertical: le plus petit des deux l'emporte et la composante correspondante est inversée. handleBrickCollision s'arrête à la première brique touchée par image et par balle, avec un break assumé.

L'état du jeu tient dans une seule chaîne de caractères, state, qui vaut ready, playing, lost ou win. Tant qu'on est en attente, la balle est recollée au centre de la raquette à chaque image. Le voile de message est en pointer-events: none, donc les clics le traversent et atteignent le canvas en dessous. Le néon, lui, se résume à shadowColor et shadowBlur posés avant chaque remplissage et remis à zéro juste après, sur un canvas redimensionné au rapport de pixels de l'écran, plafonné à deux.

Ce que j'en ai retenu

Première leçon: le contrôle vient de l'angle imposé par la raquette, pas de la simulation. Un rebond physiquement juste rendrait le jeu injouable, parce que le joueur n'aurait aucune prise sur la trajectoire. C'est un des cas où s'éloigner de la physique est la bonne réponse.

Deuxième leçon, un défaut que je laisse visible parce qu'il est instructif: resize rappelle layoutBricks, donc redimensionner la fenêtre en pleine partie fait réapparaître toutes les briques détruites pendant que le score, lui, reste acquis. La géométrie des briques et leur état de destruction vivent dans le même tableau, et c'est ça le vrai problème. Il faudrait recalculer les positions au redimensionnement et laisser survivre le drapeau de destruction. J'ai aussi laissé un paramètre fullReset sur resetGame qui n'est jamais lu.