Hey, great script. I've used a few parallax scrolling methods in the past, and this by far seems to be the best due to its flexibility and long-term ease of use. The only problem is, as stated before, that it has some major compatibility issues with Game Maker Studio 2 due to the transition to the new layer system. I've been able to work around this quite nicely and I'd like to offer up my own code, for the sake of anyone who might be trying to work it into their own GMS2 project. It's quite extensive code-wise, but in the long run it offers the same quality of life as the GMS 1.4 code.
As a bonus, not only have I made the code work with tilemaps
and backgrounds, but I've worked in auto-scroll compatibility as well -- not only can your parallax backgrounds autoscroll simultaneously, but they'll scroll in proportion to how much parallax they've been assigned.
This code should go into the Create or Room Start event of your parallax object:
Code:
/// @description Get layer, tilemap, and background properties
//Get all layers
layers = layer_get_all();
var layers_length = array_length_1d(layers);
//Get all elements
elements = 0;
tilemaps = 0;
backgrounds = 0;
for (var l = 0; l < layers_length; l++;) {
layer_elements = layer_get_all_elements(layers[l]);
var layer_elements_length = array_length_1d(layer_elements);
elements += layer_elements_length;
//Get element types
for (var e = 0; e < layer_elements_length; e++)
switch layer_get_element_type(layer_elements[e]) {
case layerelementtype_background:
//Get background
var bg = backgrounds;
background_id[bg] = layer_elements[e];
background_time[bg] = 0; //This is used to keep track of autoscrolling. We'll need it since the parallax will naturally override any autoscroll.
background_layer[bg] = layers[l];
var xo = layer_get_x(background_layer[bg]);
var yo = layer_get_x(background_layer[bg]);
background_parallax_hspeed[bg] = xo/100;
background_parallax_vspeed[bg] = yo/100;
backgrounds++;
break;
case layerelementtype_tilemap:
//Get tilemap
var tm = tilemaps;
tilemap_id[tm] = layer_elements[e];
tilemap_layer[tm] = layers[l];
var xo = layer_get_x(tilemap_layer[tm]);
var yo = layer_get_y(tilemap_layer[tm]);
tilemap_parallax_hspeed[tm] = xo/100;
tilemap_parallax_vspeed[tm] = yo/100;
tilemaps++;
break;
}
}
//Enable this line of code if you need to debug
/*show_message("Found "
+ string(layers_length) + " layers, "
+ string(elements) + " elements, "
+ string(backgrounds) + " backgrounds, and "
+ string(tilemaps) + " tilemaps."
);*/
What this code does is get all of the layer, background, and tilemap information of the current room, so that we can reference it later when we try to scroll the background.
Put this code into one of your step or draw events (I personally recommend Draw Begin):
Code:
var cx = <<<insert camera view x, or whatever you happen to be using>>>
var cy = <<<camera view y>>>
//Update background properties
for (var bg = 0; bg < backgrounds; bg++) {
var l = background_layer[bg];
//Scrolling formulas
var lx =(cx+background_time[bg]*layer_get_hspeed(l))*background_parallax_hspeed[bg];
var ly =(cy+background_time[bg]*layer_get_vspeed(l))*background_parallax_vspeed[bg];
//Perform parallax and autoscroll
layer_x(l,lx);
layer_y(l,ly);
//Update autoscroll position
background_time[bg]++; //Note: If you have a pause function or something similar, you may want to add an if statement here so that your background doesn't autoscroll when it's not supposed to.
}
//Update tilemap properties
for (var tm = 0; tm < tilemaps; tm++) {
tilemap_x(tilemap_id[tm],cx*tilemap_parallax_hspeed[tm]);
tilemap_y(tilemap_id[tm],cy*tilemap_parallax_vspeed[tm]);
}
The only thing you'll really need to do here is plug in your own views, which you may have set up differently than I do in my project. Other than that, the code should be pretty much good to go. Tell me if this helps.