Hallo,
ich habe ein Control, welches mir ein kariertes Feld zeichnet. Die Größe der zu zeichnenden Felder kann ich auch individuell bestimmen. Jetzt habe ich es so gemacht, dass wenn ich auf eines dieser Felder klicke das gesamte Feld ausgefüllt wird, also mit einer anderen Farbe übermalt wird. Entsprechende Funktionen habe ich alles schon fertig. Jetzt möchte ich aber zufällig einige Felder ausmalen lassen, also ohne, dass ich vorher darauf klicken muss.
Hier erstmal der Code, wie ich den habe:
Private Function GetFieldIndex(ByVal x As Integer, ByVal y As Integer) As _
Integer
' Errechnet den Index des Feldes (von links nach rechts)
Return (Me.Width \ FieldSize.Width) * (GetLineFromField(y) - 1) + _
GetColumnFromField(x) - 1
End Function
Private Function GetFieldPosition(ByVal x As Integer, ByVal y As Integer) As _
Point
' Errechnet aus den X- und Y-Koordinaten die Zeilen- und Spaltennummer
Return New Point(GetColumnFromField(x), GetLineFromField(y))
End Function
Private Function GetFieldRectangle(ByVal x As Integer, ByVal y As Integer) _
As Rectangle
' Errechnet aus der X- und Y-Koordinate das entsprechende Rechteck
Dim width As Integer = FieldSize.Width - 1
Dim height As Integer = FieldSize.Height - 1
Return New Rectangle((x \ FieldSize.Width) * FieldSize.Width, (y \ _
FieldSize.Height) * FieldSize.Height, width, height)
End Function
Private Function GetFieldRectangle(ByVal FieldPosition As Point) As Rectangle
' Errechnet aus der Zeilen- und Spaltennummer das entsprechende Rechteck
Dim width As Integer = FieldSize.Width - 1
Dim height As Integer = FieldSize.Height - 1
' X und Y Koordinaten mit 1 subtrahieren, damit das Raster nicht
' überzeichnet wird
Return New Rectangle((FieldPosition.X - 1) * FieldSize.Width, ( _
FieldPosition.Y - 1) * FieldSize.Height, width, height)
End Function
Private Function GetColumnFromField(ByVal x As Integer) As Integer
' Spalte berechnen und mit 1 addieren (verhindert null-basierte Spalte)
Return x \ FieldSize.Width + 1
End Function
Private Function GetLineFromField(ByVal y As Integer) As Integer
' Zeile berechnen und mit 1 addieren (verhindert null-basierte Zeile)
Return y \ FieldSize.Height + 1
End Function
Private Sub Field_Paint(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
' Berechne, wie viele vertikalen Linien gezeichnet werden können
For i As Integer = 0 To Me.Width \ FieldSize.Width
' Vertikale Linie zeichnen
e.Graphics.DrawLine(New Pen(pLineColor), i * FieldSize.Width - 1, 0, i _
* FieldSize.Width - 1, Me.Height)
Next
' Berechne, wie viele horizontalen Linien gezeichnet werden können
For i As Integer = 0 To Me.Height \ FieldSize.Height
' Horizontale Linie zeichnen
e.Graphics.DrawLine(New Pen(pLineColor), 0, i * FieldSize.Height - 1, _
Me.Width, i * FieldSize.Height - 1)
Next
' Anzahl der Einheiten (Felder) zeichnen
For i As Integer = 0 To pUnits.Length - 1
' Rechteck zum ausfüllen berechnen und zeichnen
e.Graphics.FillRectangle(New SolidBrush(pUnits(i).Color), _
GetFieldRectangle(pUnits(i).Position))
Next
End Sub
Private Sub Field_MouseClick(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseClick
' Überprüfe, ob jede Einheit (Feld) im Array gezeichnet wurde
If pUnitsSet < pUnits.Length Then
' Wenn nicht, dann die Position für nächste Einheit (Feld) festlegen
pUnits(pUnitsSet).Position = GetFieldPosition(e.X, e.Y)
' Zähler um 1 erhöhen
pUnitsSet += 1
' Zu zeichnendes Rechteck neuzeichnen lassen
Me.Invalidate(New Region(GetFieldRectangle(e.X, e.Y)))
End If
End Sub Dabei ist pUnit ein Array von Objekten vom Typ Unit. Diese beinhalten eine Eigenschaft Position, welches die Zeilen- und Spaltennummer beinhaltet, wo dieses gezeichnet werden soll und eine Eigenschaft Color, die die entsprechende Farbe beinhaltet. Color ist hierbei aber unwichtig.
Wie kann ich also nun nach Zufallsprinzip diese Felder zeichnen lassen? Allerdings soll es nur auf der linken Hälfte des gesamten Controls passieren! Ich brauche also eine Funktion, die die Felder auf der linken Hälfte des Controls nach Zufallsprinzip ausmalt. Dabei kann die Anzahl aber variieren, also die Größe des Arrays pUnits. Vielleicht sollte die Funktion auch überprüfen, ob überhaupt soviele freie Felder dafür vorhanden sind. Bei Bedarf kann ich das Control auch in ein neues Projekt packen und als Archiv irgendwo hochladen (wobei das hier schon fast alle Methoden sind).
Danke schonmal |