# 哟嗬.这不是159行的俄罗斯方块么.该如何处理

www.MyException.Cn  网友分享于：2013-03-25  浏览：7次

VB.NET code
```
Public Class Form1
Private ShowBitMap As New Bitmap(20, 20), BackBitMap As New Bitmap(20, 20), BlockType As Integer, BlockState As Integer, NextType As Integer = 3, Blocks(,) As Integer '0 隐藏，1显示，2 静止
Private DrawRectangle As Rectangle = New Rectangle(2, 2, 15, 25), DrawLocation As Point = New Point(5, 0), Score(1) As Long
Private WithEvents MyTimer As New Timer
Private Function GetPreviewPoints(ByVal nType As Integer, ByVal nState As Integer) As Point()
If nType = 1 Then
If nState Mod 4 = 0 Then Return New Point() {New Point(0, 1), New Point(1, 1), New Point(2, 1), New Point(2, 0)}
If nState Mod 4 = 1 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(0, 2), New Point(1, 2)}
If nState Mod 4 = 2 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 0), New Point(2, 0)}
If nState Mod 4 = 3 Then Return New Point() {New Point(0, 0), New Point(1, 0), New Point(1, 1), New Point(1, 2)}
ElseIf nType = 2 Then
If nState Mod 4 = 0 Then Return New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(2, 1)}
If nState Mod 4 = 1 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(0, 2), New Point(1, 0)}
If nState Mod 4 = 2 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 1), New Point(2, 1)}
If nState Mod 4 = 3 Then Return New Point() {New Point(1, 0), New Point(1, 1), New Point(1, 2), New Point(0, 2)}
ElseIf nType = 3 Then
If nState Mod 2 = 0 Then Return New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(3, 0)}
If nState Mod 2 = 1 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(0, 2), New Point(0, 3)}
ElseIf nType = 4 Then
If nState Mod 2 = 0 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 1), New Point(1, 2)}
If nState Mod 2 = 1 Then Return New Point() {New Point(0, 1), New Point(1, 0), New Point(1, 1), New Point(2, 0)}
ElseIf nType = 5 Then
If nState Mod 2 = 0 Then Return New Point() {New Point(0, 1), New Point(0, 2), New Point(1, 0), New Point(1, 1)}
If nState Mod 2 = 1 Then Return New Point() {New Point(0, 0), New Point(1, 0), New Point(1, 1), New Point(2, 1)}
ElseIf nType = 6 Then
If nState Mod 4 = 0 Then Return New Point() {New Point(0, 1), New Point(1, 0), New Point(1, 1), New Point(1, 2)}
If nState Mod 4 = 1 Then Return New Point() {New Point(0, 0), New Point(1, 0), New Point(1, 1), New Point(2, 0)}
If nState Mod 4 = 2 Then Return New Point() {New Point(0, 0), New Point(0, 1), New Point(0, 2), New Point(1, 1)}
If nState Mod 4 = 3 Then Return New Point() {New Point(0, 1), New Point(1, 1), New Point(2, 1), New Point(1, 0)}
Else
Return New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 0), New Point(1, 1)}
End If
End Function
Private Function NewBlock(ByVal nLocation As Point) As Boolean
Dim Left As Integer = 100, Right As Integer = -1, Bottom As Integer = -1, Top As Integer = 100, nPoints As Point() = GetPreviewPoints(BlockType, BlockState)
For Each n As Point In nPoints
If n.X < Left Then Left = n.X
If n.X > Right Then Right = n.X
If n.Y < Top Then Top = n.Y
If n.Y > Bottom Then Bottom = n.Y
Next
If nLocation.X + Left < 0 Then
nLocation.X = -Left
ElseIf nLocation.X + Right - Left > DrawRectangle.Width Then
nLocation.X = DrawRectangle.Width - (Right - Left)
End If
If nLocation.Y + Top < 0 Then
nLocation.Y = -Top
ElseIf nLocation.Y + (Bottom - Top) > DrawRectangle.Height Then
nLocation.Y = DrawRectangle.Height - (Bottom - Top)
Return True
End If
For Each p As Point In nPoints
If Blocks(p.X + nLocation.X, p.Y + nLocation.Y) > 1 Then Return True
Next
For y As Integer = 0 To DrawRectangle.Height
For x As Integer = 0 To DrawRectangle.Width
If Blocks(x, y) = 1 OrElse Blocks(x, y) > 5 Then Blocks(x, y) = 0
Next
Next
For Each p As Point In nPoints
Blocks(p.X + nLocation.X, p.Y + nLocation.Y) = 1
Next
DrawLocation = nLocation
End Function
Private Sub Key_Up(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyUp
If e.KeyCode = Keys.W OrElse e.KeyCode = Keys.Up Then
BlockState += 1
If NewBlock(DrawLocation) = False Then DrawBlock()
ElseIf e.KeyCode = Keys.D OrElse e.KeyCode = Keys.Right Then
If NewBlock(New Point(DrawLocation.X + 1, DrawLocation.Y)) = False Then DrawBlock()
ElseIf e.KeyCode = Keys.A OrElse e.KeyCode = Keys.Left Then
If NewBlock(New Point(DrawLocation.X - 1, DrawLocation.Y)) = False Then DrawBlock()
ElseIf e.KeyCode = Keys.S OrElse e.KeyCode = Keys.Down OrElse e.KeyCode = Keys.Space Then
For y As Integer = 0 To DrawRectangle.Height
If NewBlock(New Point(DrawLocation.X, DrawLocation.Y + 1)) Then Exit For
Next
DrawBlock()
ElseIf e.KeyCode = Keys.Enter OrElse e.KeyCode = Keys.Escape Then
MyTimer.Enabled = Not MyTimer.Enabled
If MyTimer.Enabled Then
ReDim Blocks(DrawRectangle.Width, DrawRectangle.Height)
NewBlock(New Point(5, 0))
Score(1) = 0
Me.Text = "分数:" & Score(1)
End If
End If
End Sub
Private Sub Timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyTimer.Tick
If NewBlock(New Point(DrawLocation.X, DrawLocation.Y + 1)) = False Then
DrawBlock()
Else
For y As Integer = 0 To DrawRectangle.Height
For x As Integer = 0 To DrawRectangle.Width
If Blocks(x, y) = 1 Then Blocks(x, y) = 2
Next
Next
Score(0) = ClearLine(0)
If Score(0) Then
Score(1) += (Score(0) ^ 2) * 10
Me.Text = "分数:" & Score(1)
Else
BlockType = NextType
NextType = Rnd() * 6
If NewBlock(New Point(5, 0)) Then
MyTimer.Enabled = False
MsgBox("游戏结束，按下 Enter 键重新开始。")
End If
End If
End If
End Sub
Private Function ClearLine(ByVal StartIndex As Integer) As Integer '消行
If StartIndex > DrawRectangle.Height Then Return 0
For x As Integer = 0 To DrawRectangle.Width
If Blocks(x, StartIndex) <> 2 Then Return ClearLine(StartIndex + 1)
Next
For x As Integer = 0 To DrawRectangle.Width
For y = StartIndex To 0 Step -1
If y = 0 Then
Blocks(x, y) = 0
Else
Blocks(x, y) = Blocks(x, y - 1)
End If
Next
Next
Return ClearLine(StartIndex + 1) + 1
End Function
Private Sub DrawBlock()
Dim i(4, 4) As Integer
For Each p As Point In GetPreviewPoints(NextType, 0)
i(p.X + 1, p.Y + 1) = 1
Next
DrawPicture(Blocks, DrawRectangle.Location, Me.CreateGraphics)
DrawPicture(i, New Point(DrawRectangle.Right + 2, DrawRectangle.Y), Me.CreateGraphics)
End Sub
Private Sub DrawPicture(ByVal Picture(,) As Integer, ByVal nDrawPoint As Point, ByVal DrawGraphics As Graphics)
For x As Integer = 0 To Picture.GetUpperBound(0)
For y As Integer = 0 To Picture.GetUpperBound(1)
If Picture(x, y) = 0 Then
DrawGraphics.DrawImage(BackBitMap, New Point(nDrawPoint.X * 20 + x * 20, nDrawPoint.Y * 20 + y * 20))
ElseIf Picture(x, y) = 1 OrElse Picture(x, y) = 2 Then
DrawGraphics.DrawImage(ShowBitMap, New Point(nDrawPoint.X * 20 + x * 20, nDrawPoint.Y * 20 + y * 20))
End If
Next
Next
End Sub
Private Sub Form_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Randomize()
Graphics.FromImage(ShowBitMap).FillRectangle(New System.Drawing.Drawing2D.HatchBrush(Rnd() * 52, Color.FromArgb(&HFF000000 Or &HFFFFFF * Rnd()), Color.FromArgb(&HFF000000 Or &HFFFFFF * Rnd())), New Rectangle(0, 0, 20, 20))
Graphics.FromImage(ShowBitMap).DrawRectangle(Pens.Black, New Rectangle(0, 0, 19, 19))
Graphics.FromImage(BackBitMap).FillRectangle(New System.Drawing.Drawing2D.HatchBrush(Rnd() * 52, Color.FromArgb(&HFF000000 Or &HFFFFFF * Rnd()), Color.FromArgb(&HFF000000 Or &HFFFFFF * Rnd())), New Rectangle(0, 0, 20, 20))
Graphics.FromImage(BackBitMap).DrawRectangle(Pens.Black, New Rectangle(0, 0, 19, 19))
MyTimer.Interval = 500
Me.Text = "按下 Enter 开始新游戏"
Me.SetBounds(Screen.PrimaryScreen.Bounds.X + (Screen.PrimaryScreen.Bounds.Width - (DrawRectangle.Right + 10) * 20) / 2, Screen.PrimaryScreen.Bounds.Y + (Screen.PrimaryScreen.Bounds.Height - (DrawRectangle.Bottom + 5) * 20) / 2, (DrawRectangle.Right + 10) * 20, (DrawRectangle.Bottom + 5) * 20)
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedToolWindow
Me.MaximizeBox = False
End Sub
End Class

```