DEV Community

Seung Woo (Paul) Ji
Seung Woo (Paul) Ji

Posted on • Updated on

A Simple Maze Game using 6502 Emulator Part 1

Introduction

In this post, we will use a simple maze game using the 6502 emulator that we already have experienced with before. We will incorporate the game with user input from the keyboard and display it in the 32 x 32 pixel bitmapped screen. Also, we will use the character screen to show the basic player controls.

Objectives

For this game, we will set 4 objectives to follow:

  1. The game must draw the maze in the bitmapped screen.
  2. A player must be able to use the keyboard to control.
  3. A player must find a route to reach to the goal within the maze in order to win the game.
  4. A player cannot goes through the wall.

Objective 1: Making a Maze

A maze game is meaningless without the actual maze to explore! We will use the following code to make a subroutine called drawMaze.

; zero-page variables
define  MAZE_L      $14 ; a pointer that points to where the maze will 
define  MAZE_H      $15 ; be drawn

define  DRAWN_ROW   $22 ; number of drawn rows

define  HEIGHT      7   ; height of the maze 
define  WIDTH       7   ; width of the maze

        jsr drawMaze
        brk

drawMaze:   lda #$21    ; a pointer pointing to the first pixel
            sta MAZE_L  ; of the screen
            lda #$02
            sta MAZE_H

            lda #$00    ; number of drawn rows
            sta DRAWN_ROW

            ldx #$00    ; maze data index
            ldy #$00    ; column index

draw:       lda maze_data,x
            sta (MAZE_L), y
            inx
            iny
            cpy #WIDTH  ; compare with the number of WIDTH
            bne draw    ; if not, keep drawing the column

            inc DRAWN_ROW   ; increment the number of row
            lda #HEIGHT
            cmp DRAWN_ROW   ; compare with the number of HEIGHT
            beq done

            lda MAZE_L
            clc
            adc #$20    ; add 32(0x0020) to increment the row
            sta MAZE_L  ; of the pixel
            lda MAZE_H
            adc #$00
            sta MAZE_H

            ldy #$00    ; reset the column index for the new row
            beq draw            

done:       rts     ; return from the drawMaze subroutine


maze_data:
dcb 01,00,01,00,01,01,01
dcb 01,01,01,00,00,00,01
dcb 00,00,01,00,01,00,01
dcb 01,00,01,00,01,01,01
dcb 01,00,01,00,01,00,01
dcb 01,00,01,00,01,00,01
dcb 01,01,01,01,01,00,10
Enter fullscreen mode Exit fullscreen mode

maze_size_of_7x7

The code can be intimidating at first but it is fairly straightforward to understand. In drawMaze subroutine, we first create a pointer at $10 to point the pixel (0221) that we are going to start drawing a maze. Then, we load the accumulator with the value defined in the mazeData and keep looping it until we finish drawing the entire column of the given row. After that, we add 32 to the pixel pointer (don't forget the screen size is 32 x 32) in order to increment the row. Once again, we loop this to continue drawing the shape that is set be the mazeData.

This drawMaze is made to be versatile and allows us to customize the maze size. This will help us to code the program easier by starting with relatively small maze and potentially increase the size in the future. Also, note that we set the value of wall, path, and the objective to be #00, #01, and #0a(10) respectively.
These values will be used to find if the player collides with the wall or not.

Conclusion

In this post, we made a subroutine called drawMaze that displays a maze in the screen. Using this subroutine, we will make a player to explore the path towards the goal. We will discuss about it in the next blog post.

Top comments (0)