1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice
  2. NOTICE: We will be applying a Xenforo update on Tuesday 25th of February. This means that from approximately 10:00 to 14:00 BST the forums will be offline (or possibly longer). Sorry for the inconvenience! Official Announcement here.

OFFICIAL Coffee-Break Tutorials: Parallax Scrolling

Discussion in 'Announcements' started by rmanthorp, Jan 17, 2020.

  1. rmanthorp

    rmanthorp YoYo Games Staff Admin YYG Staff

    Joined:
    Apr 15, 2016
    Posts:
    313
    Posted by Mark Alexander on 16 January 2020

    Today we're posting the first in an occasional series of "coffee-break" tutorials for GameMaker Studio 2. We know that your time is precious and not everyone has hours to spend on game dev, and so these tutorials are designed to show you how to create some effect or design some feature for your games, with as little time and effort as possible. This means that we won't be going heavily into the technical details of the subjects covered, but will instead concentrate on giving you the basic code and setup instructions so you can try things out quickly, and then in your own time you can play with the results and - if required - check the manual or search around for further information on the concepts or functions used.

    To get the ball rolling, we're going to be showing you how to quickly create a parallax scrolling effect, which is a great way to add depth and movement to your games, and is used extensively in arcade shoot-em-ups and platform games.

    [​IMG]


    SETTING UP
    For this tutorial you'll need to open GameMaker Studio 2 and create a new GML project. Don't worry if you usually use Drag and Drop™, as the code we'll be using is really simple and can be added into Execute Code actions when you want to apply it to your own projects. We'll also need some sprites, and for those we'll be using some free assets from the fabulous Kenny, which we've bundled together for you in a handy zip:

    Download: Parallax Scrolling Assets

    You will need to download and unzip all the assets from that file to a safe location as you'll need them for the next step which is to add them all into GameMaker Studio 2.

    The quickest and easiest way to add the assets to your project is to simply drag them from the folder you extracted them to and drop them on the IDE. This will add them directly to the resource tree and also open them in the workspace for you to edit if required.



    [​IMG]


    Note that the file names we have given them are used as the names of the sprites when added in this way, so with some careful naming when creating your graphics, this is a great way to very quickly add image assets (note that this will work for strip sprites with multiple frames too, as long as you add "_stripX" to the end of the sprite name, where "X" is the number of frames in the sprite!).

    Now we need to move to the Room Editor, so double click on the room "Room0" - which should be present by default in the project - to open up the room editor. Set the size of the room to 2048 width and 960 height before continuing.

    We need to create various layers in our room which we'll be using to create the parallax effect. These will be background layers and we'll be adding the sprites we just created to them. So, create the following layers in the room and name them exactly as shown:



    [​IMG]


    You should now assign one of the sprites we added to each layer, following the naming convention we've created, eg: the sprite bck_Near_Ground goes on the layer B_Near_Ground, the sprite bck_Foreground goes on the layer B_Foreground, etc...

    The final thing we need to do for the background layers is ensure that they are all set to Horizontal Tile in the layer properties:



    [​IMG]


    This will ensure that as the camera moves the backgrounds will loop seamlessly. And talking of cameras, we need to set one up too, as this effect is only possible when there is a large room and a camera used to move through it!

    So, still in the Room Editor, go to the Room Properties section and set up Viewport 0 with the following values, ensuring that both the Enable Viewports and the Visible boxes are checked:



    [​IMG]


    THE PARALLAX CODE
    Believe it or not, the bulk of the work is done, and all that's left is to add a few lines of code into a controller object that will move the backgound layers at different speeds to create our parallax effect. For that you need to create a new object and call it obj_Parallax_Control. In this object, add a Create Event with the following code:
    Code:
    background_map = ds_map_create();
    background_map[? layer_get_id("B_Clouds")] = 0.3;
    background_map[? layer_get_id("B_Distant_Ground")] = 0.2;
    background_map[? layer_get_id("B_Near_Ground")] = 0.1;
    background_map[? layer_get_id("B_Ground_Path")] = 0;
    background_map[? layer_get_id("B_Foreground")] = -0.5;
    
    What we're doing here is creating a DS Map and then adding each of the background layers into the map as individual keys. These keys are then assigned a value which is the speed multiplier we'll be using to make the different layers scroll at different speeds.

    Next we need to add a Step Event. In this event we want the following code:
    Code:
    var _cx = camera_get_view_x(view_camera[0]);
    var _xspd = 3 * (keyboard_check(vk_right) - keyboard_check(vk_left));
    _cx += _xspd
    camera_set_view_pos(view_camera[0], _cx, 0);
    
    var _b = ds_map_find_first(background_map);
    repeat(ds_map_size(background_map))
       {
       layer_x(_b, background_map[? _b] * _cx);
       _b = ds_map_find_next(background_map, _b);
       }
    
    This code first gets the current camera X position, then checks the left/right arrow keys to see if they are being held down. The value for the keyboard check will be either -1, 0, 1, and so we multiply this by 3 to get the speed that we want the camera to move at (-3, 0, or 3 pixels per-step), and then we apply this to the current camera position to move the camera.

    With that done, we can then loop through our DS map, getting the layer IDs from the map keys, and use the new camera X position multiplied by the associated multiplier value for the layer to set the layer position.

    With that done, you can now add a copy of this object into your room on the "Instances" layer and test your project. If you've done everything correctly it will look like this:



    [​IMG]


    SUMMARY
    The important thing to take away from this is that to create a parallax effect you need a camera and various layers in your room, and that you need to use values that are less than or greater than 1 to multiply the camera position by to set the different layer positions. In the example we are doing this in a long room using the X position of the camera, but you can do vertical scrolling using the Y position of the camera too in the exact same way, or you can even do full 2D scrolling using both the X and Y position!

    Thanks for reading and we hope that this short article has helped you in some way. We'll be back soon with another Coffee-break tutorial to teach you some other GameMaker tricks soon!

    https://www.yoyogames.com/blog/543/coffee-break-tutorials-parallax-scrolling
     
  2. gnysek

    gnysek Member

    Joined:
    Jun 20, 2016
    Posts:
    1,385
    It's good that it also teaches how to use ds_maps, and promotes usage of them, but in fact for something such simple a regular arrays seems to be better, especially that data structures have no Garbage Collecting (yet, and seems will have not in 2.3 too), and it's not mentioned in this tutorial, that user should be aware to free memory at end of level. Arrays would do it automatically.
    Code:
    bg_layer = ["B_Clouds", "B_Distant_Ground", "B_Near_Ground", "B_Ground_Path", "B_Foreground"];
    bg_speed = [0.3, 0.2, 0.1, 0, -0.5];
    bg_elements = array_length_1d(bg_layer);
    Code:
    var _camx = camera_get_view_x(view_camera[0]);
    _camx += 3 * (keyboard_check(vk_right) - keyboard_check(vk_left));
    camera_set_view_pos(view_camera[0], _camx, 0);
    
    for(var i=0; i<bg_elements; i++) {
      layer_x(bg_layer[i], bg_speed[i] * _camx);
    }
    - don't need to remember about garbage collector
    - less code, and easier to read (KISS)
    - probably faster by nanoseconds
     
    Last edited: Jan 17, 2020
  3. mikix

    mikix Member

    Joined:
    May 2, 2017
    Posts:
    442
    It is also possible to switch the layers z position.

    Here is an example.

    Create event: just write equals 0 on n.

    Step Event
    Code:
    
    ds_list_add(m);
    if (ds_list_size(m) > 0) - 1
    {
    ds_list_delete(m);
    }
    
    if(keyboard_check(ord("Z")))
    {
    i_list = layer_get_all_elements(lay_id2 + n);
    for (var i = 0; i < array_length_1d(i_list); i++;)
       {
       if layer_get_element_type(i_list[m]) == layerelementtype_sprite
          {
    layer_element_move(i_list[m],lay_junk);
    layer_sprite_alpha(i_list[m],0) //In case you need to make it not visible
     
          }
       }
    }
    This is what I did for my painting software experiment when I was learning ds_list.
     

Share This Page