PacMan Documentation - HeitorBRaymundo/861 GitHub Wiki
Overview
PacMan is a classical NES Game, very popular and loved by people all around the world. On this project we tried to create a variation of the game, mixing the concept with a popular game now a days, the Fortnite: Battle Royale. So, in the game you will have to use the keys of your keyboard to make the PacMan scape from the evil ghosts.
The PacMan Game
- 1 Technical Documentation
- 1.1 Graphics
- 1.2 Game Logic
- 1.3 Soundtrack
1. Technical Documentation
In this section we aim to explain, with more detail, how we developed the game using the Assembler 6502 language. Given more details about the choices that we took and how you could modify the code to make your adventure.
1.1 Graphics
We can divide the graphics of the game in two main aspects, the palettes colours and the sprites.
Palettes
Before putting any graphics on screen, you first need to set the color palette. There are two separate palettes, each 16 bytes. One palette is used for the background, and the other for sprites. The byte in the palette corresponds to one of the 64 base colors the NES can display. $0D is a bad color and should not be used. These colours are not exact and will look different on emulators and tv.
Sprites
Anything that moves separately from the background will be made of sprites. A sprite is just an 8x8 pixel tile that the PPU renders anywhere on the screen. Generally objects are made from multiple sprites next to each other. Examples would be Mario and any of the enemies like Goombas and Bowser. The PPU has enough internal memory for 64 sprites. This memory is separate from all other video memory and cannot be expanded.
On the code, we made loops to load the colours and palettes in the memory. We choose to create the sprites of the PacMan and ghosts directly at the ".asm" file, without creating a binary file with the loaded images. So, we could create the characters in the way we wanted.
You can define the palettes like this:
.db $FE,$20,$11,$15, $FE,$05,$15,$25, $FE,$08,$18,$28, $FE,$0A,$1A,$2A
The loop to load thing in the memory can be made like this:
LoadPalettesLoop:
LDA Palette, y
STA $2007
INY
CPY #$20
BNE LoadPalettesLoop
And to finish, you can create the sprites in three steps. First you define the bits at the memory, like this:
SpritePacMan:
.db %00000000
.db %11100000
.db %11111000
.db %11111100
.db %11111110
.db %11111000
.db %11100000
.db %10000000
Then, you have to define the positions and attributes, what can be made like this:
Sprites:
.db $80, $00, %00000000, $88 ; 200, 201, 202, 203
.db $80, $01, %00000000, $80 ; 204, 205, 206, 207
.db $88, $02, %00000000, $88 ; 208, 209, 20A, 20B
.db $88, $03, %00000000, $80 ; 20C, 20D, 20E, 20F
Finally, is just load at the memory.
1.2 Game Logic
The game logic is quite simple and we'll give a simple overview on how we structure it (with code 😄). In order to make easy to everyone understand what is happening, we can subdivide this topic in a few subtopics: PacMan movement, Ghosts movements and collisions.
PacMan movement
His moves are quite simple and dependent on the keys the user inputs. So, you just have to read which was the pressed key and move the character, what can be done like that:
PacUp:
LDA #%10000000
STA $202
STA $206
STA $20A
STA $20E
LDA #$09
STA $201
LDA #$0A
STA $205
LDA #$07
STA $209
LDA #$08
STA $20D
DEC $200
DEC $204
DEC $208
DEC $20C
LDA #10
STA directionPacMan
JMP FimPacMan
Ghost movement
Move the ghost is a little bit more complicated, because he is a computer character, so we have, at first, to choose a random direction, and then, move the ghost. To generate a random number you can use a code like that:
RandomSeed1:
LDA seed1
ASL A
ASL A
CLC
ADC seed1
CLC
ADC #03
STA seed1
RTS
A trick to make the generated number inside the range you want is to make an AND max_value
. So, after select the direction, you move it, doing something like that:
Ghost1Up: ;Yellow
DEC $210
DEC $214
DEC $218
DEC $21C
LDA #10
JSR CheckCollisionF1P
JMP ContinueGhost2
Collisions
Finally, we have to check if the ghost and the PacMan collide or not. To make it easy, we make the check from the ghost part of the code, doing this:
CheckCollisionF4P:
LDA $207
CMP $243
BCS justReturn4
LDA $203
CMP $247
BCC justReturn4
LDA $200
CMP $248
BCS justReturn4
LDA $208
CMP $240
BCC justReturn4
JMP collide