Snake Game for 6502 Emulator

Contents

Snake Game for 6502 Emulator

Introduction

This project is a simple Snake game implemented in 6502 assembly language. The game allows the player to control a snake that moves around the screen, eating apples to grow longer. The game ends if the snake collides with itself. The direction of the snake is controlled using the W, A, S, and D keys.

Features

  • Random Apple Generation: Apples appear at random positions on the screen.
  • Snake Movement: The snake moves in four directions (up, down, left, right) controlled by the W, A, S, and D keys.
  • Collision Detection: The game checks for collisions with apples and the snake’s own body.
  • Growing Snake: Each time the snake eats an apple, it grows longer.
  • Game Over Condition: The game ends when the snake collides with itself.

Assembly Code

;  ___           _        __ ___  __ ___
; / __|_ _  __ _| |_____ / /| __|/  \_  )
; \__ \ ' \/ _` | / / -_) _ \__ \ () / /
; |___/_||_\__,_|_\_\___\___/___/\__/___|

; Change direction: W A S D

define appleL         $00 ; screen location of apple, low byte
define appleH         $01 ; screen location of apple, high byte
define snakeHeadL     $10 ; screen location of snake head, low byte
define snakeHeadH     $11 ; screen location of snake head, high byte
define snakeBodyStart $12 ; start of snake body byte pairs
define snakeDirection $02 ; direction (possible values are below)
define snakeLength    $03 ; snake length, in bytes

; Directions (each using a separate bit)
define movingUp      1
define movingRight   2
define movingDown    4
define movingLeft    8

; ASCII values of keys controlling the snake
define ASCII_w      $77
define ASCII_a      $61
define ASCII_s      $73
define ASCII_d      $64

; System variables
define sysRandom    $fe
define sysLastKey   $ff

  jsr init
  jsr loop

init:
  jsr initSnake
  jsr generateApplePosition
  rts

initSnake:
  lda #movingRight  ; start direction
  sta snakeDirection

  lda #4  ; start length (2 segments)
  sta snakeLength
  
  lda #$11
  sta snakeHeadL
  
  lda #$10
  sta snakeBodyStart
  
  lda #$0f
  sta $14 ; body segment 1
  
  lda #$04
  sta snakeHeadH
  sta $13 ; body segment 1
  sta $15 ; body segment 2
  rts

generateApplePosition:
  ; load a new random byte into $00
  lda sysRandom
  sta appleL

  ; load a new random number from 2 to 5 into $01
  lda sysRandom
  and #$03 ; mask out lowest 2 bits
  clc
  adc #2
  sta appleH

  rts

loop:
  jsr readKeys
  jsr checkCollision
  jsr updateSnake
  jsr drawApple
  jsr drawSnake
  jsr spinWheels
  jmp loop

readKeys:
  lda sysLastKey
  cmp #ASCII_w
  beq upKey
  cmp #ASCII_d
  beq rightKey
  cmp #ASCII_s
  beq downKey
  cmp #ASCII_a
  beq leftKey
  rts

upKey:
  lda #movingDown
  bit snakeDirection
  bne illegalMove

  lda #movingUp
  sta snakeDirection
  rts

rightKey:
  lda #movingLeft
  bit snakeDirection
  bne illegalMove

  lda #movingRight
  sta snakeDirection
  rts

downKey:
  lda #movingUp
  bit snakeDirection
  bne illegalMove

  lda #movingDown
  sta snakeDirection
  rts

leftKey:
  lda #movingRight
  bit snakeDirection
  bne illegalMove

  lda #movingLeft
  sta snakeDirection
  rts

illegalMove:
  rts

checkCollision:
  jsr checkAppleCollision
  jsr checkSnakeCollision
  rts

checkAppleCollision:
  lda appleL
  cmp snakeHeadL
  bne doneCheckingAppleCollision
  lda appleH
  cmp snakeHeadH
  bne doneCheckingAppleCollision

  ; eat apple
  inc snakeLength
  inc snakeLength ; increase length
  jsr generateApplePosition

doneCheckingAppleCollision:
  rts

checkSnakeCollision:
  ldx #2 ; start with second segment

snakeCollisionLoop:
  lda snakeHeadL,x
  cmp snakeHeadL
  bne continueCollisionLoop

maybeCollided:
  lda snakeHeadH,x
  cmp snakeHeadH
  beq didCollide

continueCollisionLoop:
  inx
  inx
  cpx snakeLength ; got to last section with no collision
  beq didntCollide
  jmp snakeCollisionLoop

didCollide:
  jmp gameOver

didntCollide:
  rts

updateSnake:
  ldx snakeLength
  dex
  txa

updateloop:
  lda snakeHeadL,x
  sta snakeBodyStart,x
  dex
  bpl updateloop

  lda snakeDirection
  lsr
  bcs up
  lsr
  bcs right
  lsr
  bcs down
  lsr
  bcs left

up:
  lda snakeHeadL
  sec
  sbc #$20
  sta snakeHeadL
  bcc upup
  rts

upup:
  dec snakeHeadH
  lda #$1
  cmp snakeHeadH
  beq collision
  rts

right:
  inc snakeHeadL
  lda #$1f
  bit snakeHeadL
  beq collision
  rts

down:
  lda snakeHeadL
  clc
  adc #$20
  sta snakeHeadL
  bcs downdown
  rts

downdown:
  inc snakeHeadH
  lda #$6
  cmp snakeHeadH
  beq collision
  rts

left:
  dec snakeHeadL
  lda snakeHeadL
  and #$1f
  cmp #$1f
  beq collision
  rts

collision:
  jmp gameOver

drawApple:
  ldy #0
  lda sysRandom
  sta (appleL),y
  rts

drawSnake:
  ldx snakeLength
  lda #0
  sta (snakeHeadL,x) ; erase end of tail

  ldx #0
  lda #1
  sta (snakeHeadL,x) ; paint head
  rts

spinWheels:
  ldx #0

spinloop:
  nop
  nop
  dex
  bne spinloop
  rts

gameOver:

support

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦