private void PbPlateau_Paint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(new SolidBrush(BackColor), PbPlateau.ClientRectangle); if (Jeu == null) { return; } bool bResolu; if (ResolutionAutomatiqueEnCours) { bResolu = Jeu.ResolutionAutomatiqueIsResolu(); } else { bResolu = Jeu.IsResolu(); } SizeF szCasePlateau = new SizeF((float)PbPlateau.Width / Jeu.Largeur, (float)PbPlateau.Height / Jeu.Hauteur); SizeF szCaseImg = new SizeF(0, 0); if (Image != null) { szCaseImg = new SizeF((float)Image.Width / Jeu.Largeur, (float)Image.Height / Jeu.Hauteur); } StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; for (int y = 0; y < Jeu.Hauteur; y++) { for (int x = 0; x < Jeu.Largeur; x++) { int iPiece = Jeu.Indice(x, y); int posPiece; if (ResolutionAutomatiqueEnCours) { posPiece = Jeu.ResolutionAutomatiquePositionPiece(iPiece); } else { posPiece = Jeu.PositionPiece(iPiece); } Point coordPiece = Jeu.Coordonnees(posPiece); #region calcul cadre pièce // Eviter que les rectangles tracés autour des pièces n'empiètent les uns sur les autres // ou disparaissent en bordure de cadre. // Les positions théoriques sont exprimées en réels. // Le dessin au pixel exige des entiers. // Le coin supérieur gauche doit être arrondi au pixel supérieur // sauf si on est en bordure gauche ou supérieure. // le coin inférieur droit doit être arrondi au pixel inférieur // sauf si on est en bordure droite ou inférieure // coordonnées des coins supérieur gauche (x0,y0) et inférieur droit (x1,y1) int x0, x1, y0, y1; if (coordPiece.X == 0) { x0 = 0; } else { // on ajoute 1 pixel pour ne pas mordre sur le bord droit de la pièce de gauche // conversion vers 0, donc < à v si v > 0 x0 = (int)(1 + coordPiece.X * szCasePlateau.Width); } if (coordPiece.Y == 0) { y0 = 0; } else { y0 = (int)(1 + coordPiece.Y * szCasePlateau.Height); } if (coordPiece.X == Jeu.Largeur - 1) { x1 = PbPlateau.Width; } else { x1 = (int)((1 + coordPiece.X) * szCasePlateau.Width); } if (coordPiece.Y == Jeu.Hauteur - 1) { y1 = PbPlateau.Height; } else { y1 = (int)((1 + coordPiece.Y) * szCasePlateau.Height); } #endregion calcul cadre pièce RectangleF rcF = new RectangleF(new PointF(coordPiece.X * szCasePlateau.Width, coordPiece.Y * szCasePlateau.Height), szCasePlateau); bool bDoOffset = AnimationEnCours; if (bDoOffset) { bDoOffset = (!ResolutionAutomatiqueEnCours && posPiece == PosPieceAnimation) || (ResolutionAutomatiqueEnCours && posPiece == Jeu.ResolutionAutomatiquePosPieceEnMouvement()); } if (bDoOffset) { float k = (float)Etape / (float)NbEtapes; rcF.Offset(k * DeltaDrawAnimation.X, k * DeltaDrawAnimation.Y); x0 += (int)(k * DeltaDrawAnimation.X); x1 += (int)(k * DeltaDrawAnimation.X); y0 += (int)(k * DeltaDrawAnimation.Y); y1 += (int)(k * DeltaDrawAnimation.Y); } Rectangle rcCadrePiece = new Rectangle(x0, y0, x1 - x0, y1 - y0); if (Image == null) { if (bResolu || iPiece != Jeu.CaseVide) { e.Graphics.DrawString((iPiece + 1).ToString(), Font, Brushes.Black, rcF, sf); } } else { if (bResolu || iPiece != Jeu.CaseVide) { RectangleF rcFimg = new RectangleF(new PointF(x * szCaseImg.Width, y * szCaseImg.Height), szCaseImg); e.Graphics.DrawImage(Image, rcF, rcFimg, GraphicsUnit.Pixel); } } // traçage des lignes if (!bResolu && iPiece != Jeu.CaseVide) { e.Graphics.DrawRectangle(Pens.Black, rcCadrePiece); } } } // traçage des lignes if (!bResolu) { e.Graphics.DrawRectangle(new Pen(Color.Black, 3), PbPlateau.ClientRectangle); } }