The circular buffer concept is really quite easy to work with, especially in projects that only scroll horizontally or vertically. For me, the trick was to dedicate 2 pages of RAM to house a 2-screen rolling window of collision data (I store it in $600-$7FF). The data is formatted so that every 16 bytes represents a column of 16x16 pixel metatiles in the window. No matter what direction the camera is scrolling, determining where to "dump" newly revealed columns of tiles is extremely easy. You just take the in-level X coordinate of the camera boundary (the left boundary for scrolling left, right for scrolling right), AND it with $01F0, and add $0600. So if the camera scrolls so that the right boundary is at pixel $1BC1, which reveals a new column of metatiles, that column of metatiles would be dumped at (($1BC1 AND $01F0) + $0600) = $07C0.
Collision detection is just a step beyond this logic. After calculating the address of the column of tiles with the X coordinate, you divide the Y coordinate by 16 and use this as and use this as an index to that starting address.
Code:
;XHigh/XLow/YLow represent a set of in-game X/Y coordinates. X is 16-bit, Y is 8-bit due to no vertical scrolling.
lda XHigh
and #$01
clc
adc #$06
sta TempAddH
lda XLow
and #$F0
sta TempAddL
lda YLow
lsr a
lsr a
lsr a
lsr a
tay
lda (TempAddL),y ;Your tile type