Why Keyboard & Timer Events Matter in Excel Games
Every playable Excel game relies on two pillars: responding to player input (keyboard events) and moving the game world forward automatically (timer events). Without them, a "game" is just a static spreadsheet. This tutorial shows you exactly how to wire both systems together so your Excel game feels alive.
Part 1: Capturing Keyboard Input with Application.OnKey
Application.OnKey binds any key combination to a VBA macro. Place binding calls in a Sub that you run when the game starts, and unbind them when the game ends.
Binding Keys
Sub BindControls() Application.OnKey "{LEFT}", "MoveLeft" Application.OnKey "{RIGHT}", "MoveRight" Application.OnKey "{UP}", "MoveUp" Application.OnKey "{DOWN}", "MoveDown" Application.OnKey "{SPACE}", "FireBullet" End Sub
Unbinding Keys (Always Do This!)
Forgetting to unbind keys after a game ends means arrow keys stop working in all Excel workbooks until you restart. Always clean up:
Sub UnbindControls() Application.OnKey "{LEFT}" Application.OnKey "{RIGHT}" Application.OnKey "{UP}" Application.OnKey "{DOWN}" Application.OnKey "{SPACE}" End Sub
Key Syntax Quick Reference:
{LEFT}/{RIGHT}/{UP}/{DOWN}— Arrow keys{SPACE}— Space bar^z— Ctrl+Z+{F5}— Shift+F5
Part 2: Running a Game Timer with Application.OnTime
Application.OnTime schedules a macro to run at a specific clock time. By scheduling the macro to reschedule itself at the end of each run, you create a continuous game loop.
Dim NextTick As Date Dim GameRunning As Boolean Sub StartTimer() GameRunning = True NextTick = Now + TimeValue("00:00:01") ' 1-second interval Application.OnTime NextTick, "GameLoop" End Sub Sub StopTimer() On Error Resume Next Application.OnTime NextTick, "GameLoop", , False GameRunning = False End Sub
Choosing the Right Interval:
- 1 second — Slow puzzle games (Tetris at low level)
- 0.5 second — Medium-paced action
- 0.1 second — Fast arcade (use
Now + 0.1/86400as a decimal fraction)
Part 3: The Complete Game Loop Pattern
Combine keyboard binding, the timer, and game logic into a clean start/stop pattern:
' ——— Module-level variables ——— Dim NextTick As Date Dim GameRunning As Boolean Dim PlayerRow As Integer Dim PlayerCol As Integer ' ——— Start the game ——— Sub StartGame() PlayerRow = 10 : PlayerCol = 5 GameRunning = True BindControls DrawPlayer StartTimer End Sub ' ——— Stop the game ——— Sub EndGame() StopTimer UnbindControls MsgBox "Game Over!" End Sub ' ——— Core loop (called every tick) ——— Sub GameLoop() If Not GameRunning Then Exit Sub UpdateEnemies ' Move enemies CheckCollisions ' Test for hits RefreshDisplay ' Redraw changed cells ' Schedule the next tick NextTick = Now + TimeValue("00:00:01") Application.OnTime NextTick, "GameLoop" End Sub ' ——— Player movement (triggered by key events) ——— Sub MoveLeft() If PlayerCol > 1 Then ClearPlayer PlayerCol = PlayerCol - 1 DrawPlayer End If End Sub Sub MoveRight() If PlayerCol < 10 Then ClearPlayer PlayerCol = PlayerCol + 1 DrawPlayer End If End Sub
Part 4: Preventing Flicker with ScreenUpdating
Updating many cells per frame causes visible flicker. Wrap all cell-drawing code with:
Sub RefreshDisplay() Application.ScreenUpdating = False ' Freeze the screen ' ... all your cell drawing here ... Application.ScreenUpdating = True ' Flush changes in one frame End Sub
Common Pitfalls:
- Forgetting StopTimer on workbook close — Add
StopTimerto theWorkbook_BeforeCloseevent to prevent orphaned timers crashing Excel. - Multiple timers stacking — Always store
NextTickin a module variable so you can cancel it precisely with the fourth argumentFalse. - Key bindings leaking — Call
UnbindControlsin bothEndGameandWorkbook_BeforeClose.
Summary
Master Application.OnKey for input and Application.OnTime for timing, combine them with ScreenUpdating = False for smooth rendering, and you have the complete engine that powers every Excel game — from Snake to Tetris.