Published on

Create a Mini Golf Game in Excel with VBA

Authors

Excel Mini Golf Game

Ever wanted to turn your spreadsheet into a golf course? In this tutorial, we'll create a simple but entertaining mini golf game using Excel and VBA. Players will aim and shoot a golf ball across various obstacles to reach the hole in as few strokes as possible.

What You'll Learn

  • Creating game elements using Excel cells and formatting
  • Implementing basic physics for ball movement
  • Building mouse interaction for aiming and power control
  • Designing multiple game levels with increasing difficulty
  • Tracking player score and game state

Final Result Preview

When you complete this tutorial, you'll have a fully playable mini golf game with:

  • A golf ball you can aim and shoot
  • Walls and obstacles that affect ball movement
  • A scoring system that tracks your strokes
  • Multiple levels with different layouts

Requirements

  • Microsoft Excel (2010 or newer)
  • Basic Excel knowledge
  • Very basic understanding of VBA (but we'll guide you through everything!)

Let's Get Started!

Step 1: Set Up Your Worksheet

First, let's create our game environment:

  1. Open a new Excel workbook
  2. Right-click on Sheet1 and rename it to "MiniGolf"
  3. Set column widths to create square cells: select all columns (Ctrl+A), then right-click and set the width to 2.5
  4. Similarly, set all row heights to 15 pixels
  5. Turn off gridlines: View tab → uncheck "Gridlines"

Step 2: Design Your First Golf Course

Let's create a simple golf course:

  1. Select cells B2 through S20 and fill them with light green (RGB: 200, 255, 200) for the grass
  2. Create walls by coloring cells D4 through D15 in dark gray (RGB: 100, 100, 100)
  3. Create the starting position by coloring cell E5 in yellow
  4. Create the hole by coloring cell P15 in black

Your course should look something like this: mini golf game

Step 3: Add Game Controls

Let's add some UI elements:

  1. In cell T3, type "Strokes:"
  2. In cell U3, enter "0" (this will track the player's strokes)
  3. In cell T5, type "Level:"
  4. In cell U5, enter "1"
  5. In cell T7, type "Aim:"
  6. Format all these cells with a larger font (14pt)

Step 4: Add the VBA Code

Now, let's add the VBA code that will power our game:

  1. Press Alt+F11 to open the VBA Editor
  2. Right-click on "VBAProject" in the Project Explorer
  3. Select Insert → Module
  4. Copy and paste the following code:
Option Explicit

' Game variables
Dim BallX As Integer, BallY As Integer
Dim InitialX As Integer, InitialY As Integer
Dim HoleX As Integer, HoleY As Integer
Dim VelocityX As Double, VelocityY As Double
Dim IsMoving As Boolean
Dim AimX As Integer, AimY As Integer
Dim Power As Double
Dim Strokes As Integer
Dim CurrentLevel As Integer
Dim IsDragging As Boolean

' Constants
Const Friction = 0.95
Const MinVelocity = 0.1
Const MaxPower = 10

Sub InitializeGame()
    ' Set up initial game state
    CurrentLevel = 1
    Strokes = 0
    Range("U3").Value = Strokes
    Range("U5").Value = CurrentLevel
    
    ' Load first level
    LoadLevel CurrentLevel
    
    ' Set up event handling
    Application.OnKey "{ESC}", "ResetBall"
    
    ' Initialize aiming variables
    IsDragging = False
    
    MsgBox "Welcome to Excel Mini Golf!" & vbCrLf & vbCrLf & _
           "Click and drag from the ball to aim." & vbCrLf & _
           "Release to shoot." & vbCrLf & _
           "Press ESC to reset the ball.", vbInformation
End Sub

Sub LoadLevel(Level As Integer)
    ' Reset game board
    ClearBoard
    
    ' Create level based on level number
    Select Case Level
        Case 1
            ' Simple straight path with a wall
            CreateGrass 2, 2, 18, 19
            CreateWall 4, 4, 4, 15
            InitialX = 5: InitialY = 5
            HoleX = 16: HoleY = 15
            
        Case 2
            ' L-shaped course
            CreateGrass 2, 2, 18, 19
            CreateWall 4, 4, 15, 4
            CreateWall 15, 5, 15, 15
            InitialX = 5: InitialY = 5
            HoleX = 16: HoleY = 16
            
        Case 3
            ' More complex with islands
            CreateGrass 2, 2, 18, 19
            CreateWall 5, 5, 5, 15
            CreateWall 10, 5, 10, 15
            CreateWall 15, 5, 15, 15
            CreateWall 7, 10, 13, 10
            InitialX = 3: InitialY = 3
            HoleX = 17: HoleY = 17
            
        Case Else
            ' If we've completed all levels, show victory message
            MsgBox "Congratulations! You've completed all levels with " & Strokes & " total strokes!", vbInformation
            Exit Sub
    End Select
    
    ' Place ball and hole
    PlaceBall InitialX, InitialY
    PlaceHole HoleX, HoleY
    
    ' Reset game state
    BallX = InitialX
    BallY = InitialY
    VelocityX = 0
    VelocityY = 0
    IsMoving = False
    
    Range("U5").Value = CurrentLevel
End Sub

Sub CreateGrass(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)
    ' Create grass (light green background)
    With Range(Cells(y1, x1), Cells(y2, x2))
        .Interior.Color = RGB(200, 255, 200)
    End With
End Sub

Sub CreateWall(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer)
    ' Create wall (dark gray background)
    With Range(Cells(y1, x1), Cells(y2, x2))
        .Interior.Color = RGB(100, 100, 100)
    End With
End Sub

Sub PlaceBall(x As Integer, y As Integer)
    ' Place the golf ball (white circle on light blue background)
    With Cells(y, x)
        .Interior.Color = RGB(255, 255, 255)
        .Font.Color = RGB(0, 0, 0)
        .Value = "●"
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
End Sub

Sub PlaceHole(x As Integer, y As Integer)
    ' Place the hole (black circle)
    With Cells(y, x)
        .Interior.Color = RGB(0, 0, 0)
        .Font.Color = RGB(255, 255, 255)
        .Value = "○"
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
End Sub

Sub ClearBoard()
    ' Clear all cell contents and formatting in the game area
    With Range("B2:S20")
        .ClearContents
        .Interior.ColorIndex = xlNone
    End With
End Sub

Sub ResetBall()
    ' Reset ball to starting position
    If IsMoving Then Exit Sub
    
    ' Clear previous ball position
    Cells(BallY, BallX).ClearContents
    Cells(BallY, BallX).Interior.Color = RGB(200, 255, 200)
    
    ' Place ball at initial position
    BallX = InitialX
    BallY = InitialY
    PlaceBall BallX, BallY
    
    ' Reset velocity
    VelocityX = 0
    VelocityY = 0
End Sub

Sub Worksheet_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    ' Handle mouse down event
    If IsMoving Then Exit Sub
    
    ' Convert mouse coordinates to cell coordinates
    Dim CellX As Integer, CellY As Integer
    CellX = ActiveSheet.HitTest(X, Y).Column
    CellY = ActiveSheet.HitTest(X, Y).Row
    
    ' Check if click is on the ball
    If CellX = BallX And CellY = BallY Then
        IsDragging = True
        AimX = CellX
        AimY = CellY
    End If
End Sub

Sub Worksheet_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    ' Handle mouse move event for aiming
    If Not IsDragging Then Exit Sub
    
    ' Convert mouse coordinates to cell coordinates
    Dim CellX As Integer, CellY As Integer
    CellX = ActiveSheet.HitTest(X, Y).Column
    CellY = ActiveSheet.HitTest(X, Y).Row
    
    ' Update aim coordinates
    AimX = CellX
    AimY = CellY
    
    ' Draw aim line (this would be better with graphics, but we'll use cell values)
    Range("U7").Value = "Angle: " & Int(GetAngle(BallX, BallY, AimX, AimY)) & "°"
    
    ' Calculate power based on distance
    Power = GetDistance(BallX, BallY, AimX, AimY)
    If Power > MaxPower Then Power = MaxPower
    
    Range("T9").Value = "Power:"
    Range("U9").Value = Int((Power / MaxPower) * 100) & "%"
End Sub

Sub Worksheet_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    ' Handle mouse up event for shooting
    If Not IsDragging Then Exit Sub
    
    ' End drag
    IsDragging = False
    
    ' Calculate velocity based on aim
    Dim Angle As Double
    Angle = GetAngle(BallX, BallY, AimX, AimY)
    
    ' Convert angle to radians
    Dim Radians As Double
    Radians = Angle * 3.14159 / 180
    
    ' Set velocity based on power and angle
    VelocityX = -Cos(Radians) * (Power / 2)
    VelocityY = -Sin(Radians) * (Power / 2)
    
    ' Increment stroke count
    Strokes = Strokes + 1
    Range("U3").Value = Strokes
    
    ' Start ball movement
    IsMoving = True
    Application.OnTime Now + TimeValue("00:00:01"), "MoveBall"
End Sub

Function GetAngle(X1 As Integer, Y1 As Integer, X2 As Integer, Y2 As Integer) As Double
    ' Calculate angle between two points
    If X2 = X1 Then
        If Y2 < Y1 Then
            GetAngle = 90
        Else
            GetAngle = 270
        End If
    Else
        GetAngle = Atn((Y1 - Y2) / (X1 - X2)) * 180 / 3.14159
        If X2 < X1 Then GetAngle = GetAngle + 180
    End If
    
    ' Ensure angle is between 0 and 360
    While GetAngle < 0
        GetAngle = GetAngle + 360
    Wend
    
    While GetAngle >= 360
        GetAngle = GetAngle - 360
    Wend
End Function

Function GetDistance(X1 As Integer, Y1 As Integer, X2 As Integer, Y2 As Integer) As Double
    ' Calculate distance between two points using Pythagorean theorem
    GetDistance = Sqr((X2 - X1) ^ 2 + (Y2 - Y1) ^ 2)
End Function

Sub MoveBall()
    ' Move the ball based on current velocity
    If Not IsMoving Then Exit Sub
    
    ' Apply friction
    VelocityX = VelocityX * Friction
    VelocityY = VelocityY * Friction
    
    ' Check if ball has stopped
    If Abs(VelocityX) < MinVelocity And Abs(VelocityY) < MinVelocity Then
        IsMoving = False
        VelocityX = 0
        VelocityY = 0
        
        ' Check if ball is in hole
        If BallX = HoleX And BallY = HoleY Then
            MsgBox "Hole in " & Strokes & " strokes!", vbInformation
            
            ' Move to next level
            CurrentLevel = CurrentLevel + 1
            LoadLevel CurrentLevel
        End If
        
        Exit Sub
    End If
    
    ' Calculate new position
    Dim NewX As Integer, NewY As Integer
    NewX = BallX + Int(VelocityX)
    NewY = BallY + Int(VelocityY)
    
    ' Check for collisions with walls
    If Cells(NewY, NewX).Interior.Color = RGB(100, 100, 100) Then
        ' Determine which direction collision occurred
        If NewX <> BallX And NewY <> BallY Then
            ' Diagonal collision - check both directions
            If Cells(BallY, NewX).Interior.Color = RGB(100, 100, 100) Then
                ' Horizontal collision
                VelocityX = -VelocityX * 0.8
                NewX = BallX
            End If
            
            If Cells(NewY, BallX).Interior.Color = RGB(100, 100, 100) Then
                ' Vertical collision
                VelocityY = -VelocityY * 0.8
                NewY = BallY
            End If
            
            ' If both directions have walls, bounce back
            If Cells(BallY, NewX).Interior.Color = RGB(100, 100, 100) And _
               Cells(NewY, BallX).Interior.Color = RGB(100, 100, 100) Then
                VelocityX = -VelocityX * 0.8
                VelocityY = -VelocityY * 0.8
                NewX = BallX
                NewY = BallY
            End If
        ElseIf NewX <> BallX Then
            ' Horizontal collision
            VelocityX = -VelocityX * 0.8
            NewX = BallX
        ElseIf NewY <> BallY Then
            ' Vertical collision
            VelocityY = -VelocityY * 0.8
            NewY = BallY
        End If
    End If
    
    ' Check if new position is out of bounds
    If NewX < 2 Or NewX > 19 Or NewY < 2 Or NewY > 19 Then
        ' Bounce off the edge
        If NewX < 2 Or NewX > 19 Then VelocityX = -VelocityX * 0.8
        If NewY < 2 Or NewY > 19 Then VelocityY = -VelocityY * 0.8
        
        ' Adjust position to stay in bounds
        NewX = Application.WorksheetFunction.Max(2, Application.WorksheetFunction.Min(19, NewX))
        NewY = Application.WorksheetFunction.Max(2, Application.WorksheetFunction.Min(19, NewY))
    End If
    
    ' Only update if position actually changed
    If NewX <> BallX Or NewY <> BallY Then
        ' Clear previous position
        Dim OldColor As Long
        OldColor = Cells(BallY, BallX).Interior.Color
        
        ' If not the hole, restore to grass color
        If Not (BallX = HoleX And BallY = HoleY) Then
            Cells(BallY, BallX).ClearContents
            Cells(BallY, BallX).Interior.Color = RGB(200, 255, 200)
        Else
            ' Restore hole appearance
            PlaceHole HoleX, HoleY
        End If
        
        ' Update ball position
        BallX = NewX
        BallY = NewY
        
        ' Draw ball at new position (unless it's in the hole)
        If Not (BallX = HoleX And BallY = HoleY) Then
            PlaceBall BallX, BallY
        End If
    End If
    
    ' Schedule next movement
    Application.OnTime Now + TimeValue("00:00:0.1"), "MoveBall"
End Sub

Sub StartGame()
    ' Entry point for the game
    InitializeGame
End Sub

Step 5: Create a Button to Start the Game

  1. Go back to Excel
  2. Go to the Developer tab (if you don't see it, go to File → Options → Customize Ribbon and check "Developer")
  3. Click "Insert" and add a Button (Form Control)
  4. Draw the button near the top of your sheet
  5. When prompted to assign a macro, select "StartGame"
  6. Right-click the button and select "Edit Text," then name it "Start Game"

Step 6: Make the Worksheet Events Work

The code we provided includes MouseDown, MouseMove, and MouseUp event handlers, but they need to be placed in the correct location:

  1. Right-click on the "MiniGolf" sheet in the Project Explorer
  2. Select "View Code"
  3. Copy these three procedures from the module we created earlier and paste them into this code window:
    • Worksheet_MouseDown
    • Worksheet_MouseMove
    • Worksheet_MouseUp
  4. Delete these procedures from the original module to avoid conflicts

Step 7: Test and Play!

  1. Go back to Excel
  2. Click the "Start Game" button
  3. Follow the instructions in the popup dialog
  4. Click and drag from the ball to aim, then release to shoot
  5. Try to get the ball in the hole with as few strokes as possible!

How It Works

Let's break down the key components of our mini golf game:

Physics Simulation

The ball movement is simulated using basic physics:

  • Velocity is calculated based on the angle and power of your shot
  • Friction gradually slows the ball down
  • Collisions with walls cause the ball to bounce in a realistic way

User Interaction

The game uses Excel's worksheet events to:

  • Detect when you click on the ball (MouseDown)
  • Calculate aiming angle and power as you drag (MouseMove)
  • Shoot the ball when you release the mouse button (MouseUp)

Game Progression

The game includes:

  • Multiple levels with increasing difficulty
  • A stroke counter to track your score
  • Level advancement when you get the ball in the hole

Customization Ideas

Once you've built the basic game, try adding these enhancements:

  1. Sand Traps: Add yellow cells that slow the ball down more than regular grass
  2. Water Hazards: Add blue cells that reset the ball if hit
  3. Par Scores: Add par scores for each level and track whether player is under/over par
  4. Sound Effects: Add sound when the ball hits a wall or goes in the hole
  5. Custom Course Designer: Create a UI for designing your own courses

Troubleshooting

If you encounter issues:

  • Make sure you've enabled macros in Excel
  • Check that the worksheet events are in the Sheet1 code module, not the general module
  • Ensure your Excel security settings allow running VBA code

Conclusion

Congratulations! You've created a fully functional mini golf game in Excel. This project demonstrates that Excel can be much more than just a spreadsheet tool—it can be a platform for creating fun, interactive games.

By building this game, you've learned about:

  • Basic game physics and collision detection
  • User interaction in Excel
  • VBA programming techniques
  • Game design principles

I hope you enjoyed this tutorial and that it inspires you to create more Excel games in the future!

Download

You can download the completed Excel Mini Golf game here.