Introduction
I will show you how to create a very well known table football game. Surely, each of you at the moment of boredom took advantage of the opportunity to play such a simple and nice game. I also made a game which shows how you can use the code below to create a playable game. The game presented below is not an advertisement for myself. The game below shows how you can use code, this tutorial has to show only game engine, hearth of the game. If you have any questions like "why does my panel glow and panel in your game not" or "how did you do ...." just ask in the comments below and I will answer you. When I prepare a tutorial, I always want to create an opportunity for you to test skills, give you a challenge. Try to create your own game based on this code and you will see your skills improve.
Using the Code
Game form will not have too many elements, because they will be generated automatically during the game:
Element type | Element name | Settings |
Form | Form1 | Name: Form1
Text: Table football
Size: 654; 468
|
Panel | Panel1 | Name: Panel1
Size: 613; 407
Location: 12; 12
BackColor: SeaGreen
Anchor: Top, Bottom, Left, Right
|
PictureBox | Main_panel | Name: Main_panel
Size: 100; 50
Location: 58; 0
BackColor: SeaGreen
|
As I wrote earlier, all items will be generated in live, so we only have three items. The main element will be PictureBox
, where we will play the game, and the panel under it is just aesthetic background.
Public Class Form1
Dim pHeight As Integer = 7
Dim pWidth As Integer = 11
Dim CurrentlySelectedPanel As Panel
Dim PitchBitmap As Bitmap
Dim PitchGrapfic As Graphics
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
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)
PitchBitmap = New Bitmap(Main_panel.Width, Main_panel.Height)
PitchGrapfic = Graphics.FromImage(PitchBitmap)
Dim start As New System.Drawing.SolidBrush_
(System.Drawing.Color.Black)
Main_panel.Image = PitchBitmap
End Sub
End Class
First, set the PictureBox
's size and centered his position, then generate the graphics and clickable elements on the board. We will start with the grid generation of the playground, unlock the element:
GeneratePitchLine()
Pitch
elements we will draw using:
PitchGrapfic.DrawLine("color","start point","end point") - draw line
PitchGrapfic.FillEllipse("color", _
New Rectangle("x position, "y position", "width", "height")) -draw filled circle
This method code looks like this:
#Region "Generate pitch graphic"
Private Sub GeneratePitchLine()
Dim pCenter_W As Integer = Math.Floor((pHeight) / 2)
Dim pCenter_H As Integer = Math.Ceiling((pWidth) / 2)
Dim thinLine As Pen = New Pen(Color.FromArgb(191, 218, 229), 1)
Dim ThickLine As Pen = New Pen(Color.White, 3)
Dim pitchColor As New System.Drawing.SolidBrush(System.Drawing.Color.MediumSeaGreen)
PitchGrapfic.FillRectangle(pitchColor, _
New Rectangle(0, 0, PitchBitmap.Width, PitchBitmap.Height))
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
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)
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
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
This is a clean drawing, you can type the code, then fire the program and watch where it appears :]. Once activated, you can already see the boxes as on a checkered sheet:
Now it's a bit like table football. You can experiment and change the colors, add some circles to the pitch to make this view more enjoyable.
Now we add the active elements of the board to do it, we have to divide it a little:
- the panels at the goal (three that allow the shot to the goal (in yellow))
- the sideline panels (those at the edge of the field (in green))
If you add colors to your panels, I got the following effect:
LocationList
will keep all the panels on the pitch, but they could be in special lists with their own special qualities like sideline special bounced element.
The code for this element is shown below:
#Region "Generate pitch points"
Dim LocationList As New List(Of List(Of Panel))
Dim SpecialLocationList As New List(Of Panel)
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
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)
Else
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
End If
SpecialLocationList.Add(ManiPanel)
PanelList.Add(ManiPanel)
End If
Else
PanelList.Add(ManiPanel)
End If
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)
Next
LocationList.Add(PanelList)
Next
End Sub
#End Region
You can now activate this method in Form_Load
:
GenerateMainPanels()
(...)
CurrentlySelectedPanel = LocationList(Math.Ceiling((pWidth - 1) / 2))_
(Math.Ceiling((pHeight) / 2))
(...)
Dim start As New System.Drawing.SolidBrush_
(System.Drawing.Color.Black)
PitchGrapfic.FillEllipse(start, New Rectangle(CurrentlySelectedPanel.Location.X + 5, _
CurrentlySelectedPanel.Location.Y + 5, 10, 10))
This will mark the center panel of the field and add a ball to the game (black dot).
The goal panels will be added separately because of the lock that we create, if we are close enough to the goal, the field in the goal will be activated and then we will be able to score a goal. Unlock in Form_Load
:
AddGoal()
The code that will add the goal panels to the pitch:
#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
MsgBox("You won!!")
End Sub
#End Region
Goals are those highlighted yellow panels:
We have goals, we have the field, we have the ball so time to start the game.
Unlock in GenerateMainPanels()
and Goal_Click()
method:
AddHandler .Click, AddressOf pan_Clic
DrawLine(DirectCast(sender, Panel))
pan_Click
would look like this:
Public Sub pan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
DirectCast(sender, Panel).Visible = False
DrawLine(DirectCast(sender, Panel))
End Sub
Method drawing lines is quite complicated:
Dim Count As Integer
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()
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
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))
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)
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)
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
First, we generate graphics and block the panel where we are currently located. Then, we add the graphics of the pitch. We check that the player is near the goal and we unlock the corresponding goal. The next stage is a special location that has additional restrictions (you cannot move along the lines of the sideline, but you can bounce off the line (useful when we split the game into two players)). The next step is to add the line we have drawn to the list and block already selected panels (lines drawn), adding already drawn lines to the graphic and the current line. At the very end, we add the ball and change the graphic of the pitch to the current one. Effect:
The game does not yet have its limitations, which causes many bugs, one of them is the availability of all the panels at pitch, so the lines can be made as you like. Our restriction sits in the method UnlockPanel()
, so unlock it:
UnlockPanel(DirectCast(sender, Panel))
It limits the range of available fields, reduces the blinking of the board, and allows you to put in rules of the game.
Private Sub UnlockPanel(ByRef WybranyPanel As Panel)
Dim pozycjax As Integer = 0
Dim pozycjay As Integer = 0
Count = 0
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
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
As you have noticed, the UnlockPanel
method is before the draw
method, because the first method blocks all panels and unlocks all the +1 and -1 panels, and then the draw
method puts restrictions. Two combined methods make the game playable. :]
In this game, you can play with a friend or go one step further and create an AI that will play with you. Everything is available in this step, so you can easily add new things to the game. I leave it to you to do, if you have any trouble, just leave a comment.
History
- 18th August, 2017: Initial version