65.9K
CodeProject 正在变化。 阅读更多。
Home

桌上足球(游戏教程)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2017年8月18日

CPOL

4分钟阅读

viewsIcon

16530

downloadIcon

800

简单的“桌上足球”游戏,您可以轻松创建并与您的朋友和家人一起玩

引言

我将向您展示如何创建一个非常著名的桌上足球游戏。当然,你们每个人在无聊的时候都曾抓住机会玩过这样简单而有趣的游戏。我还创建了一个游戏,展示了如何使用下面的代码创建一个可玩的游戏。下面展示的游戏不是我自己的广告。下面的游戏展示了如何使用代码,本教程只展示游戏引擎,即游戏的精髓。如果您有任何疑问,例如“为什么我的面板会发光而您的游戏中的面板不会”或“您是如何做到...”,请在下面的评论中提问,我会回答您。当我在准备教程时,我总是希望创造一个机会让您测试技能,给您一个挑战。尝试基于此代码创建您自己的游戏,您会看到您的技能得到提高。

pilkarzykiico

Using the Code

游戏界面不会有太多的元素,因为它们将在游戏过程中自动生成

pilkarzyki1

元素类型 元素名称 设置
表单 Form1

名称:Form1

文本: 桌上足球

尺寸: 654; 468

Panel Panel1

名称: Panel1

尺寸: 613; 407

位置: 12; 12

背景色: SeaGreen

锚定: 顶部, 底部, 左侧, 右侧

PictureBox Main_panel

名称: Main_panel

尺寸: 100; 50

位置: 58; 0

背景色: SeaGreen

正如我之前写的,所有物品都会实时生成,所以我们只有三个物品。主元素将是PictureBox,我们将在其中玩游戏,而它下面的面板只是为了美观的背景。

Public Class Form1
    'Main board size (pitch size)
    Dim pHeight As Integer = 7
    Dim pWidth As Integer = 11
    'The variable holds currently selected panel
    Dim CurrentlySelectedPanel As Panel
    'variable stores game graphics
    Dim PitchBitmap As Bitmap
    Dim PitchGrapfic As Graphics

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'We set the size and position of the playing field
        Main_panel.Size = New Size(pWidth * 49 + 50, pHeight * 49 + 50)
        Main_panel.Location = New Point((Panel1.Width - Main_panel.Width) / 2, _
                                        (Panel1.Height - Main_panel.Height) / 2)
        'We create a bitmap and generate graphics on it
        PitchBitmap = New Bitmap(Main_panel.Width, Main_panel.Height)
        PitchGrapfic = Graphics.FromImage(PitchBitmap)

        'Generate playground graphics
        ''     GeneratePitchLine()
        'Generates active game elements (points on the board to click)
        ''     GenerateMainPanels()

        'Selects the center of the board as the starting point
        ''     CurrentlySelectedPanel = 
        ''     LocationList(Math.Ceiling((pWidth - 1) / 2))(Math.Ceiling((pHeight) / 2))
        'Activates the points where we can pass the ball
        ''    UnlockPanel(CurrentlySelectedPanel)
        'Adds the goal panels
        ''    AddGoal()

        Dim start As New System.Drawing.SolidBrush_
                     (System.Drawing.Color.Black) ' StartPoin color
        ''     PitchGrapfic.FillEllipse(start, 
        ''     New Rectangle(CurrentlySelectedPanel.Location.X + 5, 
        ''  CurrentlySelectedPanel.Location.Y + 5, 10, 10)) 'dodaje grafikę punktu startowego
        'Gives background to our picturebox (our graphics)
        Main_panel.Image = PitchBitmap
    End Sub
End Class

首先,设置PictureBox的大小并居中其位置,然后生成棋盘上的图形和可点击元素。我们将从游乐场网格生成开始,解锁元素

        'Generate playground graphics
        GeneratePitchLine()

Pitch 元素我们将使用绘制

PitchGrapfic.DrawLine("color","start point","end point") - draw line
PitchGrapfic.FillEllipse("color", _
     New Rectangle("x position, "y position", "width", "height")) -draw filled circle

此方法代码如下所示

#Region "Generate pitch graphic"
    Private Sub GeneratePitchLine()
        'Pitch center
        Dim pCenter_W As Integer = Math.Floor((pHeight) / 2)
        Dim pCenter_H As Integer = Math.Ceiling((pWidth) / 2)

        'pitch lines
        Dim thinLine As Pen = New Pen(Color.FromArgb(191, 218, 229), 1) 'thin line
        Dim ThickLine As Pen = New Pen(Color.White, 3) 'thick line

        'pitch background
        Dim pitchColor As New System.Drawing.SolidBrush(System.Drawing.Color.MediumSeaGreen)
        PitchGrapfic.FillRectangle(pitchColor, _
           New Rectangle(0, 0, PitchBitmap.Width, PitchBitmap.Height))

        'Generate lines
        For i As Integer = 0 To pWidth + 1
            For j As Integer = 0 To pHeight + 1
                PitchGrapfic.DrawLine(thinLine, 0, i * 49, Main_panel.Width, i * 49)
                PitchGrapfic.DrawLine(thinLine, i * 49, 0, i * 49, Main_panel.Height)
            Next
        Next
        'Generate sidelines
        PitchGrapfic.DrawLine(ThickLine, 49, 0, Main_panel.Width - 49, 0)
        PitchGrapfic.DrawLine(ThickLine, 49, (pHeight + 1) * 49, _
                              Main_panel.Width - 49, (pHeight + 1) * 49)

        PitchGrapfic.DrawLine(ThickLine, 49, 0, 49, pCenter_W * 49)
        PitchGrapfic.DrawLine(ThickLine, Main_panel.Width - 49, 0, _
                              Main_panel.Width - 49, pCenter_W * 49)
        PitchGrapfic.DrawLine(ThickLine, 49, (pHeight + 1 - pCenter_W) * 49, _
                              49, (pHeight + 1) * 49)
        PitchGrapfic.DrawLine(ThickLine, Main_panel.Width - 49, _
        (pHeight + 1 - pCenter_W) * 49, Main_panel.Width - 49, (pHeight + 1) * 49)

        PitchGrapfic.DrawLine(ThickLine, 0, pCenter_W * 49, 49, pCenter_W * 49)
        PitchGrapfic.DrawLine(ThickLine, 0, (pCenter_W + 2) * 49, 49, (pCenter_W + 2) * 49)
        PitchGrapfic.DrawLine(ThickLine, Main_panel.Width - 49, _
                              pCenter_W * 49, Main_panel.Width, pCenter_W * 49)
        PitchGrapfic.DrawLine(ThickLine, Main_panel.Width - 49, _
                             (pCenter_W + 2) * 49, Main_panel.Width, (pCenter_W + 2) * 49)

        PitchGrapfic.DrawLine(ThickLine, pCenter_H * 49, 0, pCenter_H * 49, (pHeight + 1) * 49)

        'generate pitch points
        Dim pola As New System.Drawing.SolidBrush(Color.FromArgb(150, Color.White))
        Dim aut As New System.Drawing.SolidBrush(System.Drawing.Color.White)
        For i As Integer = 1 To pWidth
            For j As Integer = 0 To pHeight + 1
                If i = 1 Or i = pWidth Or j = 0 Or j = (pHeight + 1) Then
                    If j = Math.Ceiling(pHeight / 2) Then
                        PitchGrapfic.FillEllipse(pola, _
                         New Rectangle(i * 49 - 5, j * 49 - 5, 10, 10))
                    Else
                        PitchGrapfic.FillEllipse(aut, _
                         New Rectangle(i * 49 - 5, j * 49 - 5, 10, 10))
                    End If
                Else
                    PitchGrapfic.FillEllipse(pola, _
                         New Rectangle(i * 49 - 5, j * 49 - 5, 10, 10))
                End If
            Next
        Next

        'generate goal points
        Dim bramka As New System.Drawing.SolidBrush(System.Drawing.Color.Red)
        PitchGrapfic.FillEllipse(bramka, New Rectangle(0 - 5, _
                                (pCenter_W + 1) * 49 - 5, 10, 10))
        PitchGrapfic.FillEllipse(bramka, New Rectangle((pWidth + 1) * 49 - 5, _
                                (pCenter_W + 1) * 49 - 5, 10, 10))
    End Sub
#End Region

这是一个干净的绘图,您可以输入代码,然后运行程序观看它出现在哪里:]。激活后,您已经可以看到格子,就像在棋盘格上一样

pilkarzyki2

现在它有点像桌上足球了。您可以进行实验并更改颜色,在球场上添加一些圆圈,使视图更令人愉快。
现在我们添加棋盘上的活动元素,为此,我们需要稍微划分一下

  • 球门处的面板 (三个允许射门的黄色面板)
  • 边线面板 (球场边缘的面板,绿色)

如果您为面板添加颜色,我会得到以下效果

pilkarzyki3

LocationList 将保存球场上的所有面板,但它们可以存放在具有自己特殊属性的特殊列表中,例如边线特殊反弹元素。
此元素的代码如下所示

#Region "Generate pitch points"
    'Keeps lists of all fields
    Dim LocationList As New List(Of List(Of Panel))
    'Keeps lists of sidelines points
    Dim SpecialLocationList As New List(Of Panel)
    'keeps special panels at the goal
    Dim SpecialGoalLocationList_leftGoal As New List(Of Panel)
    Dim SpecialGoalLocationList_RightGoal As New List(Of Panel)

    Private Sub GenerateMainPanels()
        For i As Integer = 1 To pWidth
            Dim PanelList As New List(Of Panel)
            For j As Integer = 0 To pHeight + 1
                Dim ManiPanel As New Panel
                With ManiPanel
                    .Location = New Point(i * 49 - 10, j * 49 - 10)
                    .Size = New Size(20, 20)
                    .BackColor = Color.Transparent
                    .Name = "panL_" + i.ToString + j.ToString
                    .Cursor = Cursors.Hand
                    ''    AddHandler .Click, AddressOf pan_Click
                End With

                If i = 1 Or i = pWidth Or j = 0 Or j = (pHeight + 1) Then
                    If j = Math.Ceiling(pHeight / 2) Then
                        PanelList.Add(ManiPanel) 'Adds a single panel at the goal 
                                          '(bright green color in the tutorial picture)
                    Else
                        'Add sidepanels (green color in the tutorial picture)
                        If (i = 1 And j = 0) Or (i = 1 And j = (pHeight + 1)) Or _
                         (i = pWidth And j = 0) Or (i = pWidth And j = (pHeight + 1)) Then
                            ManiPanel.Visible = False
                            ManiPanel.Enabled = False
                            'If the panel is on the corner of the pitch, we block him
                        End If
                        SpecialLocationList.Add(ManiPanel)
                        PanelList.Add(ManiPanel)
                    End If
                Else
                    PanelList.Add(ManiPanel) 'Adds all panels (red color in the tutorial image)
                End If
                'Adds points at the goal (yellow color in the tutorial image)
                If i = 1 Or i = pWidth Or j = 0 Or j = (pHeight + 1) Then
                    If j = Math.Ceiling(pHeight / 2) Or j = Math.Ceiling(pHeight / 2) - 1 _
                        Or j = Math.Ceiling(pHeight / 2) + 1 Then
                        If i = 1 Then
                            SpecialGoalLocationList_leftGoal.Add(ManiPanel)
                        Else
                            SpecialGoalLocationList_RightGoal.Add(ManiPanel)
                        End If

                    End If
                End If
                Main_panel.Controls.Add(ManiPanel) ' place elements at the pitch
            Next
            LocationList.Add(PanelList)
        Next
    End Sub
#End Region

您现在可以在 Form_Load 中激活此方法

        'Generates active game elements (points on the board to click)
        GenerateMainPanels()
(...)
        'Selects the center of the board as the starting point
        CurrentlySelectedPanel = LocationList(Math.Ceiling((pWidth - 1) / 2))_
                                             (Math.Ceiling((pHeight) / 2))
(...)
         Dim start As New System.Drawing.SolidBrush_
                         (System.Drawing.Color.Black) ' StartPoin color
         PitchGrapfic.FillEllipse(start, New Rectangle(CurrentlySelectedPanel.Location.X + 5, _
                         CurrentlySelectedPanel.Location.Y + 5, 10, 10)) 

这将标记球场中间的面板,并向游戏中添加一个球 (黑点)。

pilkarzyki4

球门面板将单独添加,因为我们创建了锁定机制,如果我们离球门足够近,球门区域将被激活,然后我们就能进球。在 Form_Load 中解锁

        'Adds the goal panels
        AddGoal()

将球门面板添加到球场上的代码

#Region "Add goals"
    Dim Goal_1 As New Panel
    Dim Goal_2 As New Panel

    Private Sub AddGoal()

        Dim Mid As Integer = Math.Floor((pHeight) / 2)
        With Goal_1
            .Location = New Point(0 - 10, (Mid + 1) * 49 - 10)
            .Size = New Size(20, 20)
            .BackColor = Color.Transparent
            .Name = "gol1"
            .Cursor = Cursors.Hand
            .Visible = False
            AddHandler .Click, AddressOf Goal_Click
        End With
        With Goal_2
            .Location = New Point((pWidth + 1) * 49 - 10, (Mid + 1) * 49 - 10)
            .Size = New Size(20, 20)
            .BackColor = Color.Transparent
            .Name = "gol2"
            .Cursor = Cursors.Hand
            .Visible = False
            AddHandler .Click, AddressOf Goal_Click
        End With

        Main_panel.Controls.Add(Goal_1)
        Main_panel.Controls.Add(Goal_2)
    End Sub

    Public Sub Goal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Main_panel.Enabled = False 'block main panel
        '' DrawLine(DirectCast(sender, Panel))
        MsgBox("You won!!")
    End Sub
#End Region

球门是那些高亮的黄色面板

pilkarzyki5

我们有了球门,有了球场,有了球,现在是时候开始游戏了。

GenerateMainPanels()Goal_Click() 方法中解锁

AddHandler .Click, AddressOf pan_Clic 
'and
DrawLine(DirectCast(sender, Panel))

pan_Click 的外观如下

    Public Sub pan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
       '' UnlockPanel(DirectCast(sender, Panel))
        DirectCast(sender, Panel).Visible = False
        DrawLine(DirectCast(sender, Panel))
    End Sub

绘制线条的方法相当复杂

    Dim Count As Integer ' variable check if you have place to move
    Dim LinesList As New List(Of Tuple(Of Panel, Panel))

    Private Sub DrawLine(ByVal pane As Panel)

        PitchBitmap = New Bitmap(Main_panel.Width, Main_panel.Height)
        PitchGrapfic = Graphics.FromImage(PitchBitmap)

        CurrentlySelectedPanel.Visible = False

        GeneratePitchLine()
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'Unlock the goal of the ball is in nearest zone.
        If SpecialGoalLocationList_RightGoal.Contains(pane) Then
            Goal_2.Visible = True
        Else
            Goal_2.Visible = False
        End If
        If SpecialGoalLocationList_leftGoal.Contains(pane) Then
            Goal_1.Visible = True
        Else
            Goal_1.Visible = False
        End If
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        If SpecialLocationList.Contains(pane) Then
            'block special panels when the ball is in the sideline
            Dim mojindeks As Integer = SpecialLocationList.IndexOf(pane)
            If Not mojindeks - 2 < 0 Then
                SpecialLocationList(mojindeks - 2).Visible = False
            End If
            SpecialLocationList(mojindeks + 2).Visible = False
            SpecialLocationList(mojindeks - 1).Visible = False
            SpecialLocationList(mojindeks + 1).Visible = False
            Count -= 2
        End If
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

        LinesList.Add(Tuple.Create(CurrentlySelectedPanel, pane))
        ' Blocks linked panels (ie those lines are already added)
        For i As Integer = 0 To LinesList.Count - 1
            If LinesList(i).Item1.Name = pane.Name _
                Or LinesList(i).Item2.Name = pane.Name Then
                LinesList(i).Item2.Visible = False
                LinesList(i).Item1.Visible = False
                Count -= 1
            End If
        Next
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Dim myPen As Pen = New Pen(Color.Black, 2) ' kolor lini już dodanych
        'Draws already added lines
        For i As Integer = 0 To LinesList.Count - 1
            PitchGrapfic.DrawLine(myPen, LinesList(i).Item1.Location.X + 10, _
            LinesList(i).Item1.Location.Y + 10, LinesList(i).Item2.Location.X + 10, _
            LinesList(i).Item2.Location.Y + 10)
        Next
        PitchGrapfic.DrawLine(myPen, CurrentlySelectedPanel.Location.X + 10, _
        CurrentlySelectedPanel.Location.Y + 10, pane.Location.X + 10, pane.Location.Y + 10)
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'draw the ball
        PitchGrapfic.FillEllipse(New System.Drawing.SolidBrush(Color.Gray), _
        New Rectangle(pane.Location.X + 5, pane.Location.Y + 5, 10, 10))
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        Main_panel.Image = PitchBitmap
        CurrentlySelectedPanel = pane
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        If Count <= 1 Then
            MessageBox.Show("You have no place to move, you lost the game!!", _
                            " You have no place to move !!")
            Main_panel.Enabled = False
        End If
    End Sub

首先,我们生成图形并锁定我们当前所在的面板。然后,我们添加球场的图形。我们检查玩家是否靠近球门,并解锁相应的球门。下一个阶段是特殊位置,具有额外的限制 (您不能沿着边线移动,但可以从边线上弹开 (当我们分成两人游戏时很有用))。下一步是将绘制的线条添加到列表中,并锁定已选定的面板 (已绘制的线条),将已绘制的线条添加到图形和当前线条中。最后,我们添加球并将球场的图形更改为当前图形。效果

pilkarzyki6

游戏还没有限制,这导致了很多bug,其中之一是球场上所有面板的可用性,所以线条可以任意绘制。我们的限制在 UnlockPanel() 方法中,所以请解锁它

UnlockPanel(DirectCast(sender, Panel))

它限制了可用字段的范围,减少了棋盘的闪烁,并允许您设置游戏规则。

    Private Sub UnlockPanel(ByRef WybranyPanel As Panel)
        Dim pozycjax As Integer = 0
        Dim pozycjay As Integer = 0
        Count = 0
        'Get the current panel position
        For i As Integer = 0 To LocationList.Count - 1
            For j As Integer = 0 To LocationList(i).Count - 1
                If LocationList(i)(j).Name = WybranyPanel.Name Then
                    pozycjax = i
                    pozycjay = j
                End If
            Next
        Next
        'It unlocks the nearby panels, then draws the method and puts restrictions
        For i As Integer = 0 To LocationList.Count - 1
            For j As Integer = 0 To LocationList(i).Count - 1
                If i >= pozycjax - 1 And i <= pozycjax + 1 Then
                    If j >= pozycjay - 1 And j <= pozycjay + 1 Then
                        LocationList(i)(j).Visible = True
                        Count += 1
                    Else
                        LocationList(i)(j).Visible = False
                    End If
                Else
                    LocationList(i)(j).Visible = False
                End If
            Next
        Next
    End Sub

您会注意到,UnlockPanel 方法在 draw 方法之前,因为第一个方法会阻止所有面板并解锁所有 +1 和 -1 的面板,然后 draw 方法会设置限制。这两个结合的方法使游戏变得可玩。:]

pilkarzyki7

在这个游戏中,您可以和朋友一起玩,也可以更进一步,创建一个 AI 来和您一起玩。所有这些都在这一步可用,所以您可以轻松地为游戏添加新功能。我将这项工作留给您,如果您遇到任何麻烦,请留下评论。

历史

  • 2017 年 8 月 18 日:初始版本
© . All rights reserved.