3) Your First Interactive Program
Goal: open a graphics window, create a responsive game loop, move a player, and render a heads-up display.
Time: about 30 minutes. No external assets are required.
Step 1: Create the Window
SetAppTitle("Movement Tutorial")
Graphics(800, 600, False)
SetClsColor(12, 18, 32)
SetVSync(True)
Graphics establishes a virtual 800 × 600 coordinate system. Windowed and fullscreen builds use those same game coordinates, which keeps layout code predictable.
Step 2: Add the Frame Loop
Dim running As Boolean
running = True
Do
Cls()
' Update and drawing will go here.
Flip()
If KeyHit(KEY_ESC) Then
running = False
End If
Loop Until Not running
Cls begins a clean frame. Flip presents the queued drawing and processes window events. The loop stops after Escape is pressed once.
Step 3: Distinguish Held and Pressed Input
KeyDownremains True while a key is held, so use it for movement.KeyHitreports a new press, so use it for pause, menus, or single actions.
If KeyDown(KEY_LEFT) Then
playerX = playerX - moveAmount
End If
If KeyDown(KEY_RIGHT) Then
playerX = playerX + moveAmount
End If
If KeyDown(KEY_UP) Then
playerY = playerY - moveAmount
End If
If KeyDown(KEY_DOWN) Then
playerY = playerY + moveAmount
End If
Step 4: Make Movement Frame-Rate Independent
FrameDelta returns elapsed seconds. Multiplying speed by it makes motion cover approximately the same distance at different frame rates.
Dim delta As Double
Dim moveAmount As Integer
delta = FrameDelta()
moveAmount = Round(240.0 * delta)
Positions stay integer-based at the LunarBasic game boundary. Round converts the fractional movement result into a whole number.
Step 5: Keep the Player On Screen
If playerX < 16 Then
playerX = 16
End If
If playerX > ScreenWidth() - 16 Then
playerX = ScreenWidth() - 16
End If
If playerY < 16 Then
playerY = 16
End If
If playerY > ScreenHeight() - 16 Then
playerY = ScreenHeight() - 16
End If
ScreenWidth and ScreenHeight return the virtual dimensions, so this code remains correct if you later change the resolution.
Step 6: Draw the Player and HUD
SetDrawColor(70, 210, 255)
DrawFilledRect(playerX - 16, playerY - 16, 32, 32)
SetDrawColor(255, 255, 255)
DrawCircle(playerX, playerY, 24, 32)
SetTextColor(235, 240, 255)
DrawText(fontRef, 16, 16, "Arrow keys move. ESC exits.")
DrawText(fontRef, 16, 42, _
"Position: " + Str(playerX) + ", " + Str(playerY))
Drawing calls queue work for the next Flip. Draw the world first and UI last so the UI remains visible.
Checkpoint: Complete Movement Demo
SetAppTitle("Movement Tutorial")
Graphics(800, 600, False)
SetClsColor(12, 18, 32)
SetVSync(True)
Dim fontRef As Integer
Dim playerX As Integer
Dim playerY As Integer
Dim moveAmount As Integer
Dim delta As Double
Dim running As Boolean
fontRef = LoadFont("", 20)
playerX = ScreenWidth() / 2
playerY = ScreenHeight() / 2
running = True
Do
delta = FrameDelta()
moveAmount = Round(240.0 * delta)
If KeyDown(KEY_LEFT) Then
playerX = playerX - moveAmount
End If
If KeyDown(KEY_RIGHT) Then
playerX = playerX + moveAmount
End If
If KeyDown(KEY_UP) Then
playerY = playerY - moveAmount
End If
If KeyDown(KEY_DOWN) Then
playerY = playerY + moveAmount
End If
If playerX < 16 Then
playerX = 16
End If
If playerX > ScreenWidth() - 16 Then
playerX = ScreenWidth() - 16
End If
If playerY < 16 Then
playerY = 16
End If
If playerY > ScreenHeight() - 16 Then
playerY = ScreenHeight() - 16
End If
Cls()
SetDrawColor(70, 210, 255)
DrawFilledRect(playerX - 16, playerY - 16, 32, 32)
SetDrawColor(255, 255, 255)
DrawCircle(playerX, playerY, 24, 32)
SetTextColor(235, 240, 255)
DrawText(fontRef, 16, 16, "Arrow keys move. ESC exits.")
DrawText(fontRef, 16, 42, _
"Position: " + Str(playerX) + ", " + Str(playerY))
Flip()
If KeyHit(KEY_ESC) Then
running = False
End If
Loop Until Not running
FreeFont(fontRef)
Common Mistakes
- Calling
Graphics,LoadFont, or other setup functions every frame. Initialize once before the loop. - Using
KeyHitfor movement. It only reports the initial press. - Forgetting
Flip. Queued drawing will not be presented and events will not advance. - Forgetting to free loaded handles after the loop.
Try It Yourself
Add Shift-to-sprint, change the player color while sprinting, and use MouseX()/MouseY() to draw a target under the pointer.
Functions Introduced
Graphics, Cls, Flip, FrameDelta, KeyDown, KeyHit, DrawFilledRect, DrawCircle, and DrawText.
Navigation: Previous | Course outline | Next: Drawing, Camera, and Buffers