Hier der Rest:
Grafik und Bedienung.
ReadOnly SF As New StringFormat With {.Alignment = StringAlignment.Center, _
.LineAlignment = StringAlignment.Center}
Protected Overrides Sub OnPaint(e As PaintEventArgs)
Dim g = e.Graphics
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
'Felder zeichnen mit Nummer
For Each f In Felder
If f.Belegt AndAlso f IsNot AktFeld Then
g.FillRectangle(New SolidBrush(pFeldFarbe), f.Quadrat)
g.DrawString(f.Nummer.ToString, Me.Font, New SolidBrush(Me.ForeColor), _
f.Quadrat, SF)
End If
Next
'Schwarzen Felderrahmen zeichnen
g.DrawRectangles(Pens.Black, Quads)
'----------------------------------------
If Gestartet Then
'Gelbe Markierung zeichnen
If ÜberFeld IsNot Nothing Then
g.DrawRectangle(Pens.Yellow, ÜberFeld.Quadrat)
End If
'Bewegtes Feld zeichnen mit blauem Rahmen
If AktFeld IsNot Nothing Then
Dim r = AktFeld.Quadrat
g.FillRectangle(New SolidBrush(pFeldFarbe), r)
g.DrawRectangle(Pens.Blue, r)
g.DrawString(AktFeld.Nummer.ToString, Me.Font, New SolidBrush( _
Me.ForeColor), r, SF)
End If
End If
End Sub
Protected Overrides Sub OnMouseLeave(e As EventArgs)
ÜberFeld = Nothing
Me.Refresh()
End Sub
Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
If Gestartet AndAlso e.Button = MouseButtons.None Then
ÜberFeld = FeldUnterMaus(e.Location)
Me.Refresh()
End If
End Sub
Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
If Gestartet AndAlso e.Button = MouseButtons.Left Then
ÜberFeld = Nothing
AktFeld = FeldUnterMaus(e.Location)
Me.Refresh()
End If
End Sub
Protected Overrides Async Sub OnMouseUp(e As MouseEventArgs)
If AktFeld IsNot Nothing Then
Me.Enabled = False
Dim r = AktFeld.Quadrat
Await Task.Run(AddressOf BewegeFeld)
AktFeld.Quadrat = r
AktFeld = Nothing
Me.Enabled = True
Me.Refresh()
GewonnenTest()
End If
End Sub
Private Function FeldUnterMaus(mp As Point) As Feld
Dim ff = Felder.Single(Function(f) Not f.Belegt)
Dim s1 = ff.Index Mod FelderX, z1 = ff.Index \ FelderX
Dim IstNachbar = Function(tf As Feld) As Boolean
Dim s2 = tf.Index Mod FelderX, z2 = tf.Index \ FelderX
Dim x = z1 - z2 = 0 AndAlso Math.Abs(s1 - s2) = 1
Dim y = s1 - s2 = 0 AndAlso Math.Abs(z1 - z2) = 1
Return x OrElse y
End Function
Return Felder.FirstOrDefault(Function(x) x.Belegt AndAlso _
x.Quadrat.Contains(mp) AndAlso IstNachbar(x))
End Function
Private Sub BewegeFeld()
Dim zf = Felder.Single(Function(x) Not x.Belegt)
Dim RectDiff = Function(ByRef r1 As Rectangle, ByRef r2 As Rectangle) As _
Point
Return New Point(r1.X - r2.X, r1.Y - r2.Y)
End Function
Dim d As Point, ar, cr As Rectangle
Do
d = RectDiff(zf.Quadrat, AktFeld.Quadrat)
AktFeld.Quadrat.Offset(Math.Sign(d.X), Math.Sign(d.Y))
cr = Rectangle.Union(ar, AktFeld.Quadrat)
cr.Inflate(2, 2)
Me.Invalidate(cr)
Me.Invoke(Sub() Update())
ar = AktFeld.Quadrat
Threading.Thread.Sleep(3)
Loop Until d.IsEmpty
AktFeld.KopieIn(zf)
End Sub
Private Sub GewonnenTest()
Zähler += 1
For i = 1 To Felder.Length
Dim f = Felder(i - 1)
If f.Belegt AndAlso Not f.Nummer = i Then Return
Next
Gestartet = False
RaiseEvent Gewonnen(Zähler)
End Sub
Beitrag wurde zuletzt am 06.09.14 um 17:38:59 editiert. |