vb.net打砖块游戏

本文介绍了一款使用VB.NET编写的打砖块游戏的实现过程。游戏包含小球、弹板和砖块等元素,地图用2维字节数组表示,并通过GDI绘制。游戏初始化、关卡设置、小球运动及碰撞检测等功能均有详细代码展示,同时游戏界面具有实时得分显示和角度虚线辅助。
摘要由CSDN通过智能技术生成

游戏截图

开始游戏时显示的帮助 :

游戏的主要变量为小球、弹板、砖块,为此需要设计相应的对象(可以设计为类,本例设计为结构体了),地图(gamemap)设计为2维字节数组,其它变量有游戏关卡、得分、刷新时间等等。游戏地图用GDI绘制,因此引用Drawing2D组件。游戏界面绘制用mydraw()。

主要代码如下:

Imports System.Drawing.Drawing2D
Imports System.Drawing.Color
Imports System.Threading

   Public Structure Qiu '定义小球
        Dim q_center As Point
        Dim q_radius As Integer
        Dim q_type As Integer
        Dim q_color As Color
        Dim q_v_sudu As Integer
        Dim q_v_fangxiang As Integer
    End Structure
    Public Structure Tanban '定义弹板
        Dim t_length As Integer
        Dim t_center As Point
        Dim t_type As Integer '1-普通弹板
    End Structure
    Public Structure teshuFK '特殊方块
        Dim tsfk_x As Integer 'x坐标
        Dim tsfk_y As Integer 'y坐标
        Dim tsfk_type As Integer '类型
        Dim tsfk_show As Boolean '是否显示
    End Structure

    Public QiuL() As Qiu '弹球集合
    Public qiuNum As Integer = 1 '弹球数量
    Public Const W As Integer = 50 '方块长度
    Public Const H As Integer = 20 '方块宽度
    Public Const mapW As Integer = 1000 '游戏区宽度
    Public Const mapH As Integer = 640 '游戏区高度
    Public gameMap As Byte(,) '游戏地图
    Public Const mapMX As Integer = 19
    Public Const mapMY As Integer = 31
    Public myTanban As Tanban '弹板
    Public mydefen As Integer = 0 ' 得分
    Public guanka As Integer = 1 '关卡
    Public qiuJDxian As Boolean = False '小球运动方向线
    Public shijianJge As Integer = 15 '刷新间隔,毫秒
    Public fnyinStr As String = My.Application.Info.DirectoryPath '程序所在目录
    Public tList As New List(Of Thread)

 Public Sub newGame() '初始化游戏
        With myTanban
            .t_center = New Point(mapW / 2, mapH - H / 2)
            .t_length = 160
            .t_type = 1
        End With
        qiuNum = 1
        ReDim QiuL(qiuNum - 1)
        For i As Integer = 0 To qiuNum - 1
            QiuL(i).q_center = New Point(myTanban.t_center.X, myTanban.t_center.Y - H)
            QiuL(i).q_radius = 7
            QiuL(i).q_type = 1
            QiuL(i).q_color = Color.Red
            QiuL(i).q_v_sudu = 0
            QiuL(i).q_v_fangxiang = Int(Rnd() * 100 + 40)
        Next
        ReDim gameMap(mapMX, mapMY)
        For i As Integer = 0 To mapMX
            For j As Integer = 0 To mapMY
                gameMap(i, j) = 0
            Next
        Next
        mydefen = 0
        guanka = 1
        setGuanka()
    End Sub

  Public Sub setGuanka() '根据关卡设置数组
        For i As Integer = 0 To 19
            For j As Integer = 0 To 31
                gameMap(i, j) = 0
            Next
        Next
        If guanka > 19 Then guanka = 1
        If guanka < 1 Then guanka = 19
        Dim RANDOM As New Random(guanka)
        For i As Integer = 1 To guanka * 17
            Dim s As String = RANDOM.Next.ToString
            gameMap(guanka * s.Substring(0, 1) Mod 20, guanka * s.Substring(1, 1) Mod 20) = Val(s.Substring(2, 1)) Mod 5
            gameMap((guanka * s.Substring(3, 1) + 13) Mod 20, guanka * s.Substring(4, 1) Mod 20) = Val(s.Substring(5, 1)) Mod 5
        Next
        For j As Integer = 1 To guanka * 3
            Dim s As String = RANDOM.Next.ToString
            gameMap(guanka * s.Substring(0, 1) Mod 20, guanka * s.Substring(1, 1) Mod 20) = 9
        Next
        For k As Integer = 1 To 5 '设置特殊方块5个
            gameMap(Int(mapMX * Rnd()), Int((mapMY - 15) * Rnd())) = Int(Rnd() * 8 + 91)
        Next
        If guanka Mod 2 = 0 Then '根据关卡设置弹板样式
            myTanban.t_type = 2
        Else
            myTanban.t_type = 1
        End If
    End Sub

 Public Function myDraw() As Bitmap '绘图
        Dim bmp As Bitmap = New Bitmap(mapW, mapH)
        Dim ea As Graphics = Graphics.FromImage(bmp)
        ea.SmoothingMode = SmoothingMode.HighQuality
        ea.Clear(Color.Black)
        For i As Integer = 0 To mapMX
            For j As Integer = 0 To mapMY
                If gameMap(i, j) = 1 Then
                    ea.FillRectangle(Brushes.Brown, New Rectangle(i * W, j * H, W, H))
                ElseIf gameMap(i, j) = 2 Then
                    ea.FillRectangle(Brushes.Teal, New Rectangle(i * W, j * H, W, H))
                ElseIf gameMap(i, j) = 3 Then
                    ea.FillRectangle(Brushes.MediumBlue, New Rectangle(i * W, j * H, W, H))
                ElseIf gameMap(i, j) = 4 Then
                    ea.FillRectangle(Brushes.LightBlue, New Rectangle(i * W, j * H, W, H))
                ElseIf gameMap(i, j) = 9 Then
                    ea.FillRectangle(Brushes.Yellow, New Rectangle(i * W, j * H, W, H))
                ElseIf gameMap(i, j) > 90 And gameMap(i, j) < 100 Then '画特殊方块
                    ea.FillRectangle(Brushes.Indigo, New Rectangle(i * W, j * H, W, H))
                End If
            Next
        Next
        If myTanban.t_type = 1 Then '画弹板
            ea.FillRectangle(Brushes.Orange, New Rectangle(myTanban.t_center.X - myTanban.t_length / 2, myTanban.t_center.Y - H / 2, myTanban.t_length, H))
        ElseIf myTanban.t_type = 2 Then
            ea.FillRectangle(Brushes.Red, New Rectangle(myTanban.t_center.X - myTanban.t_length / 8, myTanban.t_center.Y - H / 2, myTanban.t_length / 4, H))
            ea.FillRectangle(Brushes.Orange, New Rectangle(myTanban.t_center.X - myTanban.t_length / 2, myTanban.t_center.Y - H / 2, 3 * myTanban.t_length / 8, H))
            ea.FillRectangle(Brushes.LawnGreen, New Rectangle(myTanban.t_center.X + myTanban.t_length / 8, myTanban.t_center.Y - H / 2, 3 * myTanban.t_length / 8, H))
        End If
        For i As Integer = 0 To qiuNum - 1 '画小球
            If QiuL(i).q_v_sudu >= 0 Then
                ea.FillPie(New SolidBrush(QiuL(i).q_color), New Rectangle(New Point(QiuL(i).q_center.X - QiuL(i).q_radius, QiuL(i).q_center.Y - QiuL(i).q_radius), New Size(2 * QiuL(i).q_radius, 2 * QiuL(i).q_radius)), 0, 360)
            End If
        Next
        '绘制文件(块文本)
        Dim denfenStr As String = "分数:" + mydefen.ToString
        Dim textSize As SizeF
        Dim myBackBrush As Brush = Brushes.Green
        Dim myForeBrush As Brush = Brushes.GreenYellow
        Dim myFont As New Font(SystemFonts.DefaultFont.Name, 15, FontStyle.Regular)
        ' 找出绘制示例文本所需要的大小
        textSize = ea.MeasureString(denfenStr, myFont)
        Dim xLocation, yLocation As Single ' 用于位置
        ' 获取一次位置以消除冗余计算
        xLocation = mapW - textSize.Width - 10
        yLocation = 10
        Dim effectDepth As Integer = 2
        For i = effectDepth To 0 Step -1
            ea.DrawString(denfenStr, myFont, myBackBrush, xLocation + i, yLocation + i)
        Next
        ' 在黑色文本之上绘制水绿色主文本
        ea.DrawString(denfenStr, myFont, myForeBrush, xLocation, yLocation)
        If qiuJDxian Then '画角度虚线
            Dim mypen As Pen = New Pen(Color.GreenYellow, 2)
            Dim pDash() As DashStyle = {DashStyle.Dot, DashStyle.DashDot, DashStyle.Dash}
            mypen.DashStyle = pDash(2)
            For i As Integer = 0 To qiuNum - 1
                If QiuL(i).q_v_sudu > 0 Then
                Else
                    ea.DrawLine(mypen, New Point(QiuL(i).q_center.X, QiuL(i).q_center.Y), New Point(QiuL(i).q_center.X + 140 * Math.Cos(QiuL(i).q_v_fangxiang / 180 * Math.PI), _
                         QiuL(i).q_center.Y - 140 * Math.Sin(QiuL(i).q_v_fangxiang / 180 * Math.PI)))
                End If
            Next
        End If
        Return bmp
        ea.Dispose()
        bmp.Dispose()
    End Function

Public Function shifouguoguan() As Boolean '是否过关?,若数组全为0或9返回TRUE,过关
        Dim sfgg As Boolean = False
        Dim num As Integer = 0
        For Each mapV As Integer In gameMap
            If (mapV > 0 And mapV < 9) Or (mapV > 90 And mapV < 99) Then num += 1
        Next
        If num = 0 Then sfgg = True
        Return sfgg
    End Function

接下来就是小球运动时碰到方块反弹。主要是根据小球所处位置,判断是否碰撞。代码如下:

   Public Function juliPP(ByVal P1 As Point, ByVal P2 As Point) As Single '求两点距离
        Return Math.Sqrt((P1.X - P2.X) ^ 2 + (P1.Y - P2.Y) ^ 2)
    End Function
    Public Function YJpz(ByVal Yx As Integer, ByVal Yy As Integer, ByVal Jx As Integer, ByVal Jy As Integer) As Integer '检查圆与矩形碰撞
        'Yx、Yy是小球在圆心;Jx,Jy是矩形在左上角在地图上在坐标
        Dim v As Integer = 0
        Dim r As Integer = QiuL(0).q_radius '小球的半径
        Dim yc As Point = New Point(Yx, Yy) '小球的圆心
        If Jx < 0 Or Jy < 0 Or Jx > mapMX Or Jy > mapMY Then '地图数组下标超范围,不碰撞
            v = 0
        Else
            Dim Jc1 As Point = New Point(Jx * W, Jy * H) '矩形左上角
            Dim Jc2 As Point = New Point(Jx * W + W, Jy * H) '矩形右上角
            Dim Jc3 As Point = New Point(Jx * W + W, Jy * H + H) '矩形右下角
            Dim Jc4 As Point = New Point(Jx * W + W, Jy * H + H) '矩形左下角
            If gameMap(Jx, Jy) > 0 Then '地图数组不为0
                If Yx - Jc1.X > 0 And Yx - Jc1.X < W And Yy - Jc1.Y > 0 And Yy - Jc1.Y < H Then '小球在矩形内部
                    v = 9
                Else
                    If Yx < Jc1.X And Yy < Jc1.Y And juliPP(yc, Jc1) <= r Then
                        v = 1 '碰左上角
                    ElseIf Yx > Jc1.X + W And Yy < Jc1.Y And juliPP(yc, Jc2) <= r Then
                        v = 2 '碰右上角
                    ElseIf Yx > Jc1.X + W And Yy > Jc1.Y + H And juliPP(yc, Jc3) <= r Then
                        v = 3 '碰右下角
                    ElseIf Yx < Jc1.X And Yy > Jc1.Y + H And juliPP(yc, Jc4) <= r Then
                        v = 4 '碰左下角
                    ElseIf Yx >= Jc1.X And Yx <= Jc1.X + W And Yy < Jc1.Y And Jc1.Y - Yy <= r Then
                        v = 5 '碰上边
                    ElseIf Yx >= Jc1.X + W And Yy >= Jc1.Y And Yy <= Jc1.Y + H And Yx - Jc1.X - W <= r Then
                        v = 6 '碰右边
                    ElseIf Yx >= Jc1.X And Yx <= Jc1.X + W And Yy >= Jc1.Y + H And Yy - Jc1.Y - H <= r Then
                        v = 7 '碰下边
                    ElseIf Yx <= Jc1.X And Yy >= Jc1.Y And Yy <= Jc1.Y + H And Jc1.X - Yx <= r Then
                        v = 8 '碰左边
                    End If
                End If
            Else '地图数组为0,表示没砖块,不碰撞
                v = 0
            End If
        End If
        Return v
    End Function

接下来在窗体上添加Timer控件,不断检查碰撞情况。

接下来在窗体KeyDown过程中进行按键控制。

打砖块游戏基本设计完成了。

--------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值