5

Grid Position System

Commodore 64 β€’ Phase 1 β€’ Tier 1

Add a logical grid coordinate system to track sprite position

βšͺ easy
⏱️ 30-45 minutes
πŸ’» Code Examples
πŸ› οΈ Exercise
🎯

Learning Objectives

  • Create an 8Γ—6 grid coordinate system
  • Calculate grid position from pixel position
  • Track dual positioning systems
  • Display grid information on screen
🧠

Key Concepts

Coordinate system mapping - logical vs physical Bit shifting for division - fast math tricks Dual position tracking - pixels and grid Integer division by powers of 2

Grid Position System

β€œMy sprite knows where it is on the grid!”

Welcome to the world of organized movement! In this lesson, you’ll add intelligence to your sprite by creating a grid system that tracks logical positions alongside the smooth pixel movement. This is the foundation for all game mechanics!

The Magic You’ll Create

β€œNow I can see exactly where my sprite is in game terms!”

By the end of this lesson, your sprite will display its current grid position on screen. While it moves smoothly in pixels, you’ll also see its logical position like β€œPOS: 3,2” - the beginning of real game intelligence!

Screenshot of completed lesson

Why Grid Systems Matter

β€œThis is how games think about position!”

While pixel movement looks smooth, games need logical positions for:

  • Collision detection - β€œAm I touching that wall?”
  • Level design - β€œWhat’s in grid square 5,3?”
  • Game rules - β€œCan I place a piece here?”
  • AI pathfinding - β€œHow do I get from here to there?”

Every classic game from Pac-Man to Tetris uses grid systems to organize gameplay!

Understanding the Grid

Before we build it, let’s understand what we’re creating:

Our 8Γ—6 Grid System

Screen divided into 8 columns Γ— 6 rows
Each cell is 32Γ—32 pixels

β”Œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”
β”‚ 0,0 β”‚ 1,0 β”‚ 2,0 β”‚ 3,0 β”‚ 4,0 β”‚ 5,0 β”‚ 6,0 β”‚ 7,0 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
β”‚ 0,1 β”‚ 1,1 β”‚ 2,1 β”‚ 3,1 β”‚ 4,1 β”‚ 5,1 β”‚ 6,1 β”‚ 7,1 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
β”‚ 0,2 β”‚ 1,2 β”‚ 2,2 β”‚ 3,2 β”‚ 4,2 β”‚ 5,2 β”‚ 6,2 β”‚ 7,2 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
β”‚ 0,3 β”‚ 1,3 β”‚ 2,3 β”‚ 3,3 β”‚ 4,3 β”‚ 5,3 β”‚ 6,3 β”‚ 7,3 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
β”‚ 0,4 β”‚ 1,4 β”‚ 2,4 β”‚ 3,4 β”‚ 4,4 β”‚ 5,4 β”‚ 6,4 β”‚ 7,4 β”‚
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€
β”‚ 0,5 β”‚ 1,5 β”‚ 2,5 β”‚ 3,5 β”‚ 4,5 β”‚ 5,5 β”‚ 6,5 β”‚ 7,5 β”‚
β””β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”˜

The Mathematical Magic

To convert from pixels to grid coordinates:

  • Grid X = Pixel X Γ· 32
  • Grid Y = (Pixel Y - 50) Γ· 32

But the 6502 has no division instruction! We’ll use bit shifting instead.

Building the Grid System

Let’s add grid intelligence to your sprite!

Step 1: Define Grid Constants

β€œThis is how we set up our logical world!”

; Grid dimensions
GRID_WIDTH = 8                 ; 8 columns
GRID_HEIGHT = 6                ; 6 rows

; Each cell is 32Γ—32 pixels
; This divides 256 pixels evenly (8 Γ— 32 = 256)
; And provides good game-sized cells

Magic Moment: These constants define the logical structure of your game world!

Step 2: The Division Trick

β€œThis is how we do fast math without division!”

calculate_grid_position:
        ; Calculate grid X from sprite X
        ; grid_x = sprite_x / 32
        lda sprite_x
        lsr                    ; Divide by 2
        lsr                    ; Divide by 4
        lsr                    ; Divide by 8
        lsr                    ; Divide by 16
        lsr                    ; Divide by 32
        sta grid_x

Magic Moment: Five LSR instructions = divide by 32! The 6502’s secret math trick!

Step 3: Complete Position Calculation

β€œThis is how we track both pixel and grid position!”

        ; Calculate grid Y from sprite Y
        ; grid_y = (sprite_y - 50) / 32
        lda sprite_y
        sec
        sbc #50                ; Subtract Y offset for screen position
        lsr                    ; Divide by 2
        lsr                    ; Divide by 4
        lsr                    ; Divide by 8
        lsr                    ; Divide by 16
        lsr                    ; Divide by 32
        sta grid_y
        
        rts

Magic Moment: Now your sprite knows its logical position in the game world!

Step 4: Display Grid Information

β€œThis is how we show the intelligence!”

display_current_position:
        ; Display "POS: X,Y"
        ldx #0
display_pos_label:
        lda pos_label,x
        beq pos_label_done
        sta $0400 + 40*5 + 2,x ; Row 5, column 2
        inx
        jmp display_pos_label
pos_label_done:

        ; Display grid X
        lda grid_x
        clc
        adc #48                ; Convert to ASCII ('0' = 48)
        sta $0400 + 40*5 + 7   ; After "POS: "
        
        ; Display comma
        lda #44                ; ASCII comma
        sta $0400 + 40*5 + 8
        
        ; Display grid Y
        lda grid_y
        clc
        adc #48                ; Convert to ASCII
        sta $0400 + 40*5 + 9
        
        rts

pos_label:
        !text "POS: "
        !byte 0                ; Null terminator

Magic Moment: Your sprite’s grid position appears on screen in real-time!

Step 5: Integration with Movement

β€œThis is how we keep everything synchronized!”

game_loop:
        jsr read_joystick          ; Get input
        jsr move_sprite            ; Move by pixels
        jsr calculate_grid_position ; Update grid position
        jsr update_sprite_position ; Update hardware
        jsr display_current_position ; Show grid coords
        jsr wait_frame
        jmp game_loop

Magic Moment: Your sprite now tracks both smooth pixel movement AND logical grid position!

Create Your Grid-Aware Sprite

Now it’s your turn to add intelligence to your sprite!

Build Your Smart Sprite System

  1. Create the program: All code is in pixel-patrol-05.asm
  2. Build it: Run make clean && make all
  3. Experience the intelligence: Execute make run

Expected Wonder

When you run this program, you’ll see:

  • Your sprite moving smoothly in pixels (as before)
  • β€œPOS: X,Y” displaying the current grid position
  • The grid coordinates updating as you move
  • The realization: β€œMy sprite understands its logical position!”

Understanding the Grid Magic

The Power of Bit Shifting

β€œThis is 6502 math at its finest!”

Why does bit shifting work for division?

Original: 10101000 (168 pixels)
LSR #1:   01010100 (84)  Γ· 2
LSR #2:   00101010 (42)  Γ· 4
LSR #3:   00010101 (21)  Γ· 8
LSR #4:   00001010 (10)  Γ· 16
LSR #5:   00000101 (5)   Γ· 32 = Grid position 5!

Grid Position Mapping

Key relationships in our system:

  • Pixels 0-31 β†’ Grid position 0
  • Pixels 32-63 β†’ Grid position 1
  • Pixels 64-95 β†’ Grid position 2
  • Pixels 96-127 β†’ Grid position 3
  • And so on…

Dual Position Tracking

Your sprite now maintains:

  • sprite_x, sprite_y: Smooth pixel positions
  • grid_x, grid_y: Logical grid positions
  • Both updated every frame for perfect synchronization

Make It Even More Amazing

Ready to enhance your grid intelligence?

Challenge 1: Grid Boundaries

Wonder Goal: β€œI can see the grid boundaries!”

Change the border color based on grid position:

; Add to calculate_grid_position:
lda grid_x
adc grid_y
and #$0f               ; Keep in color range
sta $d020              ; Set border color

Challenge 2: Grid Visualization

Wonder Goal: β€œI can see the grid on screen!”

Add markers at grid intersections:

; Place a dot every 32 pixels
; Use character graphics or sprites

Challenge 3: Center Positioning

Wonder Goal: β€œMy sprite snaps to grid centers!”

Modify movement to center sprites in grid cells:

; After moving, center in grid cell
lda grid_x
asl                    ; Multiply by 2
asl                    ; Multiply by 4
asl                    ; Multiply by 8
asl                    ; Multiply by 16
asl                    ; Multiply by 32
adc #16                ; Add half cell size
sta sprite_x

Challenge 4: Grid Information Display

Wonder Goal: β€œI can see more grid information!”

Display more details:

; Show both pixel and grid positions
; "PIX: 156,98 GRID: 4,2"

What You’ve Achieved

πŸŽ‰ Congratulations! You’ve created a dual-position tracking system!

The Intelligence You Added

  • ✨ Grid coordinate system - Logical position tracking
  • ✨ Bit shifting division - Fast mathematical operations
  • ✨ Dual position tracking - Pixel and grid synchronization
  • ✨ Real-time display - Visual feedback of position data
  • ✨ Game intelligence foundation - The basis for all game mechanics

Your Programming Journey

You’ve just implemented the foundation of game intelligence! Every game that involves positioning, collision detection, or level design uses exactly this kind of dual-position system. You’re thinking like a game programmer now!

Historical Achievement

You’ve just implemented the same position tracking used in classic games like:

  • Pac-Man - Grid-based movement with smooth animation
  • Frogger - Pixel movement with grid-based collision
  • Tetris - Grid logic with smooth piece movement
  • Lode Runner - Grid-based levels with pixel-perfect movement

Modern Relevance

This dual-position concept powers:

  • Game engines - Unity, Unreal Engine coordinate systems
  • Physics engines - Collision detection and spatial organization
  • UI systems - Layout grids and responsive design
  • 3D graphics - World coordinates and screen coordinates

What’s Next?

β€œReady to make your sprite move in discrete grid steps?”

In the next lesson, you’ll reverse the process! You’ll convert grid positions back to pixel positions, creating grid-based movement where your sprite snaps perfectly from cell to cell. This is the foundation for puzzle games, RPGs, and strategy games!

Coming Up

  • Convert grid positions to pixel positions
  • Create snap-to-grid movement
  • Build discrete grid-based controls
  • Experience the precision of grid movement
  • Set up the foundation for grid-based game mechanics

You’re about to discover how games like Pac-Man and Sokoban achieve their precise, grid-perfect movement!

Ready to master grid-based movement? Let’s make your sprite snap to the grid!


Technical Reference

Grid System Constants

  • GRID_WIDTH: 8 columns
  • GRID_HEIGHT: 6 rows
  • Cell size: 32Γ—32 pixels
  • Total coverage: 256Γ—192 pixels

Position Calculation

  • Grid X: sprite_x >> 5 (divide by 32)
  • Grid Y: (sprite_y - 50) >> 5 (divide by 32)
  • Bit shifting: 5 LSR instructions = divide by 32

Grid Position Range

  • X coordinates: 0-7 (8 columns)
  • Y coordinates: 0-5 (6 rows)
  • Total cells: 48 grid positions

Variables

  • grid_x: Current grid column (0-7)
  • grid_y: Current grid row (0-5)
  • sprite_x/y: Pixel positions (unchanged)

This grid system foundation will serve you in every game that needs organized positioning!