Gradius ftw! Oh sweet childhood... Back on topic though...
You can use a single sprite to hold your bg image. May be slower on some systems though as you aren't able to cull what's passed by like with tiles. However I think on today's pcs this is a negligable performance loss. The first thing I made with DBP was a vertical-scrolling shooter like Raiden Trad (I tried to aproach it like qbasic and looking back my source is a mess, lol). Anyway in my scroller I used a mixture of full length backgrounds and tiles (level-depending) as it was one of the things I wanted to investigate. Well ran well - even on a laptop!
So far as how to do it, there are two options:
1: Off-screen drawing (lots of it). Position all the enviroment entities at 0 + when the appear. You can sprite off-screen btw. Then use a FOR-loop to move them -1 (or your desired speed) each cycle.
2: Off-set. Use a variable to store your ship's distance travelled. Increase this variable by a speed factor each cycle. Now subtract this from the sprite location, eg: SPRITE mybg, 0 - camOffset, 0, mybg. Full credit to Agent for this method.
Personally I prefer method 1 as I find it more flexible and easier for a game like this. If you were making platformer, I'd say option 2 would prolly be easier for a beginner level.
I'm on my phone atm but will post some example code later.
[EDIT] Have added some examples, see below[/EDIT]
// Decalaration
GLOBAL scrollspeed# AS FLOAT: scrollspeed# = 1 // Keep it a global var so you can modify it any time
DIM bgobject(10): FOR i = 1 TO 10: bgobject(i) = i: NEXT i // Initialise objects, I assigned them sprite no's 1 - 10
// but you can change this by adding a modifier, eg
// bgobject(i) = startnumber + i
LoadSprites() // Dummy function where you'd have loaded sprites for bg ents.
// Main Loop (Well, just for example purposes
DO
ScrollSprites(bgobject(1), bgobject(10), scrollspeed#) // Example of the call. Can be used on all entities
ControlBadguys() // Dummy function.
ControlPlayer() // Dummy function.
OtherCrap() // Actually did have a function called this in a QB program I made
SYNC
END
Function ScrollSprites(from, to, speed#)
// from = the first sprite in the range
// to = the last sprite in the range
// speed# the velocity it moves at. Note this is a float because although screen coord are ints, this figure is rounded off
// and when performing math functions on this, more accurate results are given.
FOR i = from TO to
IF SPRITE EXIST(i) = 1 // If you control your sprite ranges correctly, you don't need
// this check (saving cpu)
sprx = SPRITE X(i)
spry = SPRITE Y(i)
SPRITE i, sprx - speed#, spry, i // Simple place the sprite on it's location - the unit of speed
ENDIF
NEXT i
EndFunction
The above code illustrate scrolling sprite ranges with a function call. I threw in some extras on management which span across both examples.
#CONSTANT bg_start_no 100
GLOBAL camx# AS FLOAT
GLOBAL speed# AS FLOAT
DIM bgobject(10): FOR i = 1 TO 10: bgobject(i) = i + bg_start_no: NEXT i // Example of what I mentioned in my previous
// example about a modifier.
DO
INC camx#, speed# // In this game, we constantly move forward
UpdateSprites() // Updates all sprites
ControlBadguys() // Dummy function
ControlPlayer() // Dummy function
LOOP
Function UpdateSprites()
bg_last_no = ARRAY COUNT(bgobject(0)) - 1 // Gets the total number of sprite in use based on array size.
// Because we don't use array(0), we subtract 1.
FOR i = bg_start_no TO bg_start_no + bg_last_no
sprx = SPRITE X(i) // Get the location of each sprite
spry = SPRITE Y(i)
SPRITE i, sprx - camx#, spry, i // Sprite with an offset.
NEXT i
// Did this example without using a SPRITE EXIST check
// to illustrate using array size to determine the no of
// bg entities in use. Now if you use this method, you'll
// need to manage the arrays better but you'll use less cpu.
EndFunction
The above shows using an offset-type method. You'll also note that my extras example with management explains using arrays for management. This method requires that you expand, shrink and shift arrays to get accurate results. Not a good idea unless you're experienced with data structures, however something to consider for educational purposes.
Hope this helps. If something isn't clear ask (I dunno how well I explained it).
*Disclaimer: This code will not run as-is (it's not meant to, it's an example). If there is a fault in something, I'm sorry. I'm busy drinking coffee, getting dressed and coding at the same time - I'm addicted to multi-tasking.