[4.5.9] Parallax Scrolling with Sprites

smilehero65

Well-known member
Even though parallax scrolling became a hallmark of the 16-bit era, NES devs were already experimenting with this effect. Despite the hardware not supporting multiple layers, they found multiple workarounds to make this work. One of them was moving sprites at half the speed of the camera to create the illusion of depth.

ParallaxGIF.gif
We can easily make this neat effect in NESMaker!

(Big thanks to SciNEStist, whose help was the main reason I came up with this code!)



1) We will go to either:

1769745144621.png

- doSpritePreDraw.asm (if we want to draw the sprites in front of the object's sprites)
- doSpritePostdraw.asm (if we want to draw the sprites behind the object's sprites)


2) Paste the following code:

Code:
; ----------------------------------------
; Make sprites move half the camera speed
; ----------------------------------------
LDA camX
LSR A
STA temp3

;;Store sprite tile
LDA #$23
STA tempz

;;Store sprite attribute
LDA #%00000001
STA tempA

;%10000000 = Flipped vertically
;%01000000 = Flipped horizontally
;%00100000 = Display sprite behind the background tiles
;%00000011 = What sprite palette to use
;%00000000 = Sprite palette 0
;%00000001 = Sprite palette 1
;%00000010 = Sprite palette 2
;%00000011 = Sprite palette 3


;;We will draw 8 sprites that
;;are scattered around the
;;screen
; -----------------------------
; Sprite 1
; -----------------------------
LDA #$08
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp1
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp1

DrawSprite temp1, #$10, tempz, tempA

; -----------------------------
; Sprite 2
; -----------------------------
LDA #$28
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp2
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp2

DrawSprite temp1, #$30, tempz, tempA

; -----------------------------
; Sprite 3
; -----------------------------
LDA #$48
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp3
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp3

DrawSprite temp1, #$18, tempz, tempA

; -----------------------------
; Sprite 4
; -----------------------------
LDA #$68
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp4
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp4

DrawSprite temp1, #$50, tempz, tempA

; -----------------------------
; Sprite 5
; -----------------------------
LDA #$88
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp5
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp5

DrawSprite temp1, #$08, tempz, tempA

; -----------------------------
; Sprite 6
; -----------------------------
LDA #$A8
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp6
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp6

DrawSprite temp1, #$40, tempz, tempA

; -----------------------------
; Sprite 7
; -----------------------------
LDA #$C8
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp7
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp7

DrawSprite temp1, #$28, tempz, tempA

; -----------------------------
; Sprite 8
; -----------------------------
LDA #$E8
SEC
SBC temp3
STA temp1

LDA camScreen
AND #%00000001
BEQ +NoComp8
    LDA temp1
    SEC
    SBC #128
    STA temp1
+NoComp8

DrawSprite temp1, #$60, tempz, tempA


DONE!
Now you have a very neat little effect that can easily make your game look neat.



LIMITATIONS:
- We can only make simple backgrounds like starry nights or little clouds in the sky
- We still have the 64 sprite limit at the time, so be careful.


~ EXTRA ~
If you want to go further with parallaxing, baardbi has a tutorial on how to make a static sprite to simulate a sun in the background.

 
Last edited:

SciNEStist

Well-known member
The Last arg in the drawsprite line is the attributes. the "priority" bit is which controls if your sprite is in front of or behind tiles.

76543210

10: Monster palette (00, 01, 10, 11)
2,3,4: Unimplemented
5: Priority (0: in front of background; 1: behind background)
6: Horizontal flip (0: off, 1: on)
7: Vertical flip (0: off, 1: on)
 
game_003.png

For LEGIONNAIRES (our byte off 6 entry ) we created the illusion of depth by moving 2 sprites in opposite directions. <- -> this combined with the stripes and High -Low positioning created the illusion of scrolling.

"One of them was moving sprites at half the speed of the camera to create the illusion of depth" Never heard of this technique tbh. I thought that multiple layers of scrolling where created by multiple sprite zero hits on 1 screen. Which nes games use the half speed technique ?

Very cool effect, great job.
 

smilehero65

Well-known member
View attachment 9505

For LEGIONNAIRES (our byte off 6 entry ) we created the illusion of depth by moving 2 sprites in opposite directions. <- -> this combined with the stripes and High -Low positioning created the illusion of scrolling.

"One of them was moving sprites at half the speed of the camera to create the illusion of depth" Never heard of this technique tbh. I thought that multiple layers of scrolling where created by multiple sprite zero hits on 1 screen. Which nes games use the half speed technique ?

Very cool effect, great job.

I think I saw that technique in one of the Ninja Gaiden cutscenes. Pretty neat, too. The sprite 0 hit is also valid, but it's a bit harder.

Answering your question, Mega Man 3 Gemini Stage shows parallax scrolling with sprites:

View: https://youtu.be/AoQAS2O7Nc4?si=UamHRPajQ7-pHypk
 
Top Bottom