Public Class Form1
Private ShowBitMap As New Bitmap(20, 20), BackBitMap As New Bitmap(20, 20), PreviewBitmap As Bitmap, PreviewGraphics As Graphics
Private BlockType As Integer, BlockState As Integer, NextType As Integer = 3, Blocks(,) As Integer '0 隐藏U,C1显示|,C2 静A止~
Private DrawRectangle As Rectangle = New Rectangle(2, 2, 15, 25), DrawLocation As Point = New Point(5, 0), Score As Long
Private WithEvents MyTimer As New Timer
Private Function GetPreviewPoints(ByVal nType As Integer, ByVal nState As Integer) As Point() Dim nPoints As Point(), i As Integer, m As Integer, n As Integer If nType = 1 Then
nPoints = New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(0, 1)} '左??÷L
ElseIf nType = 2 Then
nPoints = New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(2, 1)} '右EL
ElseIf nType = 3 Then
nPoints = New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(3, 0)} '长条d
ElseIf nType = 4 Then
nPoints = New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 1), New Point(1, 2)} '左??÷Z
ElseIf nType = 5 Then
nPoints = New Point() {New Point(1, 0), New Point(2, 0), New Point(0, 1), New Point(1, 1)} '右EZ
ElseIf nType = 6 Then
nPoints = New Point() {New Point(0, 0), New Point(1, 0), New Point(2, 0), New Point(1, 1)} 'T型^ Else
nPoints = New Point() {New Point(0, 0), New Point(0, 1), New Point(1, 0), New Point(1, 1)} '方u块 End If
For i = 1 To nState Mod 4 '旋u转 m = nPoints(1).Y - 1 n = nPoints(1).X - 1
nPoints(2) = New Point(nPoints(2).Y - m + n, 2 - (nPoints(2).X - n) + m) nPoints(0) = New Point(nPoints(0).Y - m + n, 2 - (nPoints(0).X - n) + m) nPoints(3) = New Point(nPoints(3).Y - m + n, 2 - (nPoints(3).X - n) + m) Next
Return nPoints 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
If nLocation.X + Right > DrawRectangle.Width Then nLocation.X = DrawRectangle.Width - Right
If nLocation.Y + Bottom > DrawRectangle.Height Then Return True For Each p As Point In nPoints
If p.Y + nLocation.Y >= 0 AndAlso 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 Then Blocks(x, y) = 0 Next Next
For Each p As Point In nPoints
If p.Y + nLocation.Y >= 0 Then 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 MyTimer.Enabled AndAlso (e.KeyCode = Keys.W OrElse e.KeyCode = Keys.Up) Then '向u上a键
BlockState += 1
If NewBlock(DrawLocation) = False Then DrawBlock()
ElseIf MyTimer.Enabled AndAlso (e.KeyCode = Keys.D OrElse e.KeyCode = Keys.Right) Then '向u右E键
If NewBlock(New Point(DrawLocation.X + 1, DrawLocation.Y)) = False Then DrawBlock() ElseIf MyTimer.Enabled AndAlso (e.KeyCode = Keys.A OrElse e.KeyCode = Keys.Left) Then '向u左??÷键
If NewBlock(New Point(DrawLocation.X - 1, DrawLocation.Y)) = False Then DrawBlock() ElseIf MyTimer.Enabled AndAlso (e.KeyCode = Keys.S OrElse e.KeyCode = Keys.Down OrElse e.KeyCode = Keys.Space) Then '向u下o键
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 '回n车键 MyTimer.Enabled = Not MyTimer.Enabled If MyTimer.Enabled Then
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
ReDim Blocks(DrawRectangle.Width, DrawRectangle.Height) Score = 0
BlockState = 0
NewBlock(New Point(5, 0)) DrawBlock()
Me.Text = \分a数?:\ & Score 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
Dim i As Integer = ClearLine(0) If i Then
Score += (i ^ 2) * 10
Me.Text = \分a数?:\ & Score DrawBlock() Else
BlockType = NextType BlockState = 0
NextType = Rnd() * 6
If NewBlock(New Point(5, 0)) = False Then Exit Sub MyTimer.Enabled = False
MsgBox(\游a戏结束c,C按A下o Enter 键重d新V开始n。B\) End If End If End Sub
Private Function ClearLine(ByVal StartIndex As Integer) As Integer '消A行s 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
If MyTimer.Interval > 100 Then MyTimer.Interval -= 1 '每消A一e行s减少-时间1毫|秒b Return ClearLine(StartIndex + 1) + 1 End Function
Private Sub DrawBlock() Dim i(5, 5) As Integer
For Each p As Point In GetPreviewPoints(NextType, 0) i(p.X + 2, p.Y + 2) = 1 Next
DrawPicture(Blocks, DrawRectangle.Location)
DrawPicture(i, New Point(DrawRectangle.Right + 2, DrawRectangle.Y)) Me.CreateGraphics.DrawImage(PreviewBitmap, New Point(0, 0)) End Sub
Private Sub DrawPicture(ByVal Picture(,) As Integer, ByVal nDrawPoint As Point) For x As Integer = 0 To Picture.GetUpperBound(0) For y As Integer = 0 To Picture.GetUpperBound(1) If Picture(x, y) = 0 Then
PreviewGraphics.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
PreviewGraphics.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()
Me.Text = \按A下o Enter 开始n新V游a戏\
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
PreviewBitmap = New Bitmap((DrawRectangle.Right + 10) * 20, (DrawRectangle.Bottom + 5) * 20)
PreviewGraphics = Graphics.FromImage(PreviewBitmap) End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Me.CreateGraphics.DrawImage(PreviewBitmap, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel) End Sub End Class