Movement Constraints
Commodore 64 • Phase 1 • Tier 1
Add boundaries and constraints to create strategic movement limitations
Learning Objectives
- Implement movement boundaries and walls
- Create invisible collision barriers
- Add level design constraints
- Build strategic movement limitations
Key Concepts
Movement Constraints
“Now my sprite respects boundaries and obstacles!”
Welcome to the world of strategic constraints! In this lesson, you’ll add boundaries, walls, and obstacles to your movement system. This is where your sprite learns to respect the game world’s rules and limitations.
The Magic You’ll Create
“Perfect! My sprite can’t move through walls!”
By the end of this lesson, your sprite will respect boundaries and obstacles. Try to move into a wall or forbidden area - your sprite will stay put, following the rules of your game world perfectly!
Why Movement Constraints Matter
“This is how games create challenges and strategy!”
Movement constraints are essential for:
- Level design - Creating walls, mazes, and boundaries
- Strategic gameplay - Forcing players to think about positioning
- Puzzle mechanics - Making certain moves impossible
- Game balance - Preventing players from going where they shouldn’t
Every game from Pac-Man to Sokoban uses movement constraints to create engaging challenges!
Understanding Constraint Systems
Before we build it, let’s understand how constraints work:
Types of Constraints
- Screen boundaries - Can’t move outside the game area
- Wall barriers - Solid obstacles that block movement
- Forbidden zones - Areas where sprites can’t enter
- Conditional barriers - Walls that appear/disappear based on game state
Constraint Checking Process
- Plan the move - Where does the sprite want to go?
- Check constraints - Is that position valid?
- Execute or block - Move if valid, stay if blocked
Building the Constraint System
Let’s add intelligent boundary checking to your movement!
Step 1: Basic Boundary Checking
“This is how we keep sprites in the game area!”
check_boundaries:
; Check if new position is within grid bounds
lda new_grid_x
cmp #8 ; Maximum X is 7 (0-7)
bcs invalid_move ; If >= 8, invalid
lda new_grid_y
cmp #6 ; Maximum Y is 5 (0-5)
bcs invalid_move ; If >= 6, invalid
; Position is valid
clc ; Clear carry = valid
rts
invalid_move:
sec ; Set carry = invalid
rts
Magic Moment: Your sprite can’t escape the game area!
Step 2: Wall Detection System
“This is how we create solid barriers!”
; Simple wall map - 1 = wall, 0 = empty
wall_map:
!byte 1,1,1,1,1,1,1,1 ; Row 0: top wall
!byte 1,0,0,0,0,0,0,1 ; Row 1: side walls
!byte 1,0,1,1,1,1,0,1 ; Row 2: inner walls
!byte 1,0,0,0,0,0,0,1 ; Row 3: side walls
!byte 1,0,1,1,1,1,0,1 ; Row 4: inner walls
!byte 1,1,1,1,1,1,1,1 ; Row 5: bottom wall
check_wall_collision:
; Calculate offset in wall map
lda new_grid_y
asl ; Multiply by 2
asl ; Multiply by 4
asl ; Multiply by 8 (8 columns per row)
clc
adc new_grid_x ; Add column offset
tax ; Use as index
; Check if position has a wall
lda wall_map,x
beq no_wall ; 0 = no wall
; Wall detected
sec ; Set carry = blocked
rts
no_wall:
clc ; Clear carry = valid
rts
Magic Moment: Your sprite bounces off walls like in a real maze!
Step 3: Complete Constraint Checking
“This is how we validate every move!”
validate_movement:
; Store proposed new position
lda grid_x
sta old_grid_x
lda grid_y
sta old_grid_y
; Calculate new position based on input
jsr calculate_new_position
; Check all constraints
jsr check_boundaries
bcs movement_blocked ; Boundary violation
jsr check_wall_collision
bcs movement_blocked ; Wall collision
; Movement is valid - update position
lda new_grid_x
sta grid_x
lda new_grid_y
sta grid_y
clc ; Clear carry = success
rts
movement_blocked:
; Movement blocked - restore old position
lda old_grid_x
sta grid_x
lda old_grid_y
sta grid_y
sec ; Set carry = blocked
rts
Magic Moment: Your sprite follows all the rules perfectly!
Step 4: Direction-Specific Constraint Checking
“This is how we handle each direction intelligently!”
calculate_new_position:
; Start with current position
lda grid_x
sta new_grid_x
lda grid_y
sta new_grid_y
; Check each direction
lda joystick_state
and #$01 ; Up
bne check_down
dec new_grid_y ; Try moving up
jmp position_calculated
check_down:
lda joystick_state
and #$02 ; Down
bne check_left
inc new_grid_y ; Try moving down
jmp position_calculated
check_left:
lda joystick_state
and #$04 ; Left
bne check_right
dec new_grid_x ; Try moving left
jmp position_calculated
check_right:
lda joystick_state
and #$08 ; Right
bne position_calculated
inc new_grid_x ; Try moving right
position_calculated:
rts
Magic Moment: Each direction is checked independently and intelligently!
Step 5: The Constrained Movement Loop
“This is how we create rule-respecting gameplay!”
game_loop:
jsr read_joystick ; Get player input
jsr validate_movement ; Check if move is legal
jsr convert_grid_to_pixels ; Convert to pixel coordinates
jsr update_sprite_position ; Update hardware
jsr display_current_position ; Show grid position
jsr wait_frame
jmp game_loop
Magic Moment: Your sprite now respects all game world rules!
Create Your Constrained Game World
Now it’s your turn to build a world with rules and boundaries!
Build Your Rule-Respecting Sprite
- Create the program: All code is in
pixel-patrol-07.asm
- Build it: Run
make clean && make all
- Experience the constraints: Execute
make run
Expected Wonder
When you run this program, you’ll experience:
- Boundary respect: Can’t move outside the game area
- Wall collisions: Sprite stops at walls and barriers
- Strategic positioning: Must plan moves around obstacles
- Rule enforcement: Game world has consistent laws
- The realization: “This feels like a real game world!”
Understanding Constraint Magic
The Power of Limitations
“Constraints create gameplay!”
Movement constraints create:
- Challenge: Players must think strategically
- Exploration: Finding paths through obstacles
- Puzzle solving: Working around barriers
- Spatial awareness: Understanding the game world
Constraint Checking Efficiency
Your constraint system is efficient:
- Pre-validation: Check before moving, not after
- Carry flag: Simple success/failure indication
- Modular checking: Each constraint type is separate
- Rollback capability: Can undo invalid moves
Level Design Possibilities
With your constraint system, you can create:
- Mazes: Complex path-finding challenges
- Rooms: Separate areas connected by doorways
- Barriers: Strategic obstacles and choke points
- Puzzles: Movement-based problem solving
Make It Even More Amazing
Ready to enhance your constraint system?
Challenge 1: Dynamic Walls
Wonder Goal: “Walls can appear and disappear!”
Add walls that change based on conditions:
; Wall appears when sprite is in certain position
; or after certain number of moves
check_dynamic_walls:
; Check game state conditions
; Modify wall_map based on conditions
Challenge 2: One-Way Barriers
Wonder Goal: “Some barriers only block certain directions!”
Create directional barriers:
; Allow movement in one direction but not the other
; Like one-way doors or force fields
Challenge 3: Visual Wall Indicators
Wonder Goal: “I can see the walls on screen!”
Draw walls using character graphics:
; Use character codes to draw wall tiles
; Show barriers visually on screen
Challenge 4: Conditional Passages
Wonder Goal: “Walls disappear when I have keys!”
Add key-based barriers:
; Track keys/conditions sprite has collected
; Allow movement through certain walls when conditions met
What You’ve Achieved
🎉 Congratulations! You’ve mastered movement constraints!
The Intelligence You Added
- ✨ Boundary checking - Automatic area limitation
- ✨ Wall collision detection - Solid barrier implementation
- ✨ Movement validation - Pre-move legality checking
- ✨ Strategic constraints - Rule-based gameplay
- ✨ Level design foundation - Tools for creating game worlds
Your Programming Journey
You’ve just implemented the constraint system that makes games challenging and strategic! This is the foundation of level design, puzzle mechanics, and tactical gameplay.
Historical Achievement
You’ve just implemented the same constraint system used in:
- Pac-Man - Maze walls and boundary checking
- Sokoban - Box and wall collision detection
- Rogue - Dungeon wall and door systems
- Adventure games - Room boundaries and barriers
Modern Relevance
This constraint system concept powers:
- Level editors - Collision layer design
- Physics engines - Collision detection systems
- Game engines - Tilemap collision systems
- AI pathfinding - Obstacle avoidance algorithms
What’s Next?
“Ready to add statistics and game state tracking?”
In the final Foundation lesson, you’ll learn how to implement a complete game loop with statistics tracking. This will teach you how to count moves, track time, and display game information - the foundation of all game state management!
Coming Up
- Implement move counting and statistics
- Add time tracking and display
- Create game state management
- Build information display systems
- Complete the Foundation phase with a full game loop
You’re about to learn how games track everything that happens and provide feedback to players!
Ready to complete the Foundation phase? Let’s add game statistics!
Technical Reference
Constraint Types
- Boundary constraints: Grid limits (0-7, 0-5)
- Wall constraints: Solid barriers in wall_map
- Conditional constraints: State-based restrictions
- Directional constraints: One-way barriers
Constraint Checking Process
- Calculate new position: Based on input direction
- Validate boundaries: Check grid limits
- Check wall collisions: Query wall_map
- Execute or block: Move if valid, stay if blocked
Wall Map Structure
- 8Ă—6 grid: Matches sprite movement grid
- 1 byte per cell: 1 = wall, 0 = empty
- Linear storage: Row-major order
- 48 bytes total: Complete level data
Validation Variables
- new_grid_x/y: Proposed position
- old_grid_x/y: Backup position
- Carry flag: Success/failure indicator
- wall_map: Level collision data
This constraint system foundation will serve you in every game that needs strategic boundaries and obstacles!