To dynamically scroll through a very large background made up of smaller frames, there are many different solution; the main idea though is quite the same.
The main idea
Think of your fifteen background frames as sort of "panels", which you draw one along the other so that they fit the current view
width: if your view is 1280 pixels wide, and each background is 960 pixels wide, then you need at least three backgrounds per time to fit the current view
; this looks obvious if one of the "panels" fits within the current view:

Cycling through panels
With this setup, we expect background 1 in the image to disappear as soon as it lies completely out of our view
borders; later, when background 3 find itself completely within the view
borders, we need to draw the new background 4 following the number 3 seamlessly.
Make it simpler
We can tear down the global complexity of our solution by making some considerations:
- We can use a fixed number of scrolling panels (backgrounds) as long as they fit the
view
range, as showed ealier, in number equal to or greater that the minimum required;
- In GM:S, since we have a limited number of available backgrounds, instead of loosing past backgrounds and allocating new ones (not possible because background indices are fixed in GM:S), we can just shift the
background_index
es in a proper way to make the whole bigger background be drawn seamlessly.
All this realizes as follow. First, we draw the first n backgrounds; when the n-th background lies within the view
borders, thus we now need to draw the n+1-th background, we shift the n backgrounds back (for example, along the positive direction of x axis) of value n*background_width; finally, we make the n-th background equal to the first - so that it will actually be drawn in the same previous position regarding the room view
- and then assign the new backgrounds to the indices to follow.
If we make n = 5, we reach the following:
- Starting cycle: backgrounds 1 to 5;
- First iteration: backgrounds 5 to 9;
- Second iteration: backgrounds 9 to 13;
- Boss iterations: backgrounds 13, 14, 15, 12, 13
The "boss iteration" will occur through the same backgrounds continuously and seamlessly, thanks to a useful choice of numbers.
Implementation
Have one object to control directly the background movement.
In its Create Event, you assign the backgrounds and their offsets:
// Assign background indices
background_index[0] = bgFrame0;
background_index[1] = bgFrame1;
background_index[2] = bgFrame2;
background_index[3] = bgFrame3;
background_index[4] = bgFrame4;
// Shift backgrounds (otherwise they will be overlapped)
for (var i=1; i<5; i++) // bkgr0 starts at (0,0)
background_x[i] += i*bk_width; // bk_width is the width of single backgrounds
Then, in the Step Event (or similar):
// Update backgrounds' relative positions
for (var i=0; i<5; i++)
background_x[i] -= 5; // an alternative to background_hspeed[]
// Change the backgrounds stack when needed
if (background_x[4]<=0) // if the last background lies within the view
{
for (var i=0; i<5; i++) // push back all five backgrounds
background_x[i] += bk_width; // (maintaining their relative offsets)
background_index[0] = background_index[4]; // last panel becomes the first one
// change other backgrounds here
}
Final touch
Where I commented // change other backgrounds here
, you can implement a switch
statement that changes background_index[1]
to background_index[4]
upon looking up a counter variable telling you which background cycle to draw (starting, first, second, or boss).
Important thing is, before changing these background_index
es, you must always execute background_index[0] = background_index[4]
to make the transition seamless.