GM:S 1.4 Smooth scrolling on mobile devices

Discussion in 'Tutorials' started by Appsurd, Feb 12, 2017.

  1. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Smooth scrolling on mobile devices


    GM version: GM: Studio 1.4.1804 Standard (2018-03-18)
    Target platform: ALL
    Download: https://marketplace.yoyogames.com/assets/5091/smooth-view-example
    Links: N/A
    Latest change: 2018-08-09
    Level: Medium



    Summary

    This mini tutorial will explain how you can enable smooth scrolling on a mobile device. In a large menu or so this could be particularly useful. The tutorial will basically explain its functionality and thereafter explore the used variables and common values used for these variables. In case you’re just interested to see/use the code, please head for the Marketplace to download it! You can find the link in the header just above this piece of text. Or you may copy-and-paste the scripts from this tutorial from chapter 2.

    Table of contents

    Introduction
    Chapter 1: The concept
    Chapter 2: The scripts and the variables
    Conclusion
    Changelog

    Introduction

    In many games a menu is something that shows up at the very beginning of your game. Many games do not require a large menu but, as your game grows larger or you have an extensive shop or so, a scrollable menu is really nice. Especially when your menu is large (e.g. more than 3 times the size of the width/height of the screen) a smooth scrollable menu really beautifies your game. In this tutorial I will cover a set of scripts used for creating a scrollable menu.

    This tutorial and all its assets are completely free, there is no need for any credit at all to Appsurd. We do appreciate if you rate the script in the Marketplace such that we know what can be improved. Thanks in advance and enjoy the tutorial!

    Chapter 1: The concept

    In order to use the menu, we will need an object to handle it. Let’s create an object called obj_smoothview to handle it all. Furthermore, it is important that you activate view 0 since this view will be used for scrolling. I expect you to know how to use views, but if you don’t, then please have a look at the manual or possibly another tutorial.

    Now, scrolling can be done in two directions: horizontally and vertically. So one parameter in the initialize script will handle this. In the tutorial, I will discuss vertical only, but the same process can be applied to the horizontal version. And don’t worry, the example and the scripts contain both :).

    We will also need a variable to handle the current scrolling speed. Let’s call it drag_speed. But the drag speed should decay slowly, such that we have a nice smooth effect. This is more or less called friction (the variable we will use is called smooth), which is another variable we will use.

    Those are the variables we will need, so we can start. We will distinguish two types of pressing/touching: the first touch (in code: mouse_check_button_pressed) or the continuous touch (mouse_check_button).

    In the first case, we will initialise the movement. We will call drag the position of the start of your mouse and of course, the speed is zero.

    Now we will look into the scrolling. Whenever we move, let’s increase the drag_speed. Using the drag_speed, we want to move the view. We can handle this in the following code:

    Code:
    if (mouse_check_button(mb_left))
        {
            //Drag
            drag_speed = (drag - mouse_x) * speed_modifier;
            view_xview += drag_speed;
        }
    
    You might find a variable called speed_modifier. This variable is used to set how fast you scroll. In general, you might want to choose 1 (such that you scroll the same as you move your finger) or maybe somewhat smaller if you can only scroll for a small distance (since for example your room is just not so large).

    But we wanted to slowly reduce the speed of the movement. So let’s implement it. If the drag_speed is larger than zero, we want it to decay slowly. In code, we have the following:

    Code:
    if (abs(drag_speed) > 0)
        {
            //Drag slow down effect
            view_xview += drag_speed;
            if (view_xview <= 0 || view_xview >= (room_width-view_wview)) then drag_speed = 0;
            drag_speed += (-drag_speed*smooth);
        }
    
    You might recognize the smooth here, which actually is the friction used. NB: The reason I’m not using the variable name friction here is that this variable is already a built-in one, so I simply can’t use it… Generally, choosing a value around 0.1 will be convenient for smoothness. Depending on the size of your scrollable room, you might want to adjust it a little.

    Notice that we also want to set the speed to zero whenever we get outside the room. Otherwise we would be able to move out without getting stopped at the boundary. However, we should also correct for going just over the edge of the room. So we will need another line just below the previous code, which is the following:

    Code:
    view_yview = max(0, min(view_yview, room_height - view_hview));
    
    This actually completes the code for the moving of the view. Now we will examine just a simple checking method to be able to scroll through the menu and while scrolling, not being able to click on the buttons. A very simple checking method is just to check whether the current drag_speed has dropped below a certain value, which we will call limit. In general, a value around 2 is convenient but again, you may want to adjust to fit your situation.

    And that’s it. It’s rather simple but it works quite well. Of course improvements can be made, such as including a timer to improve the clicking procedure. Any suggestions can be of course be posted in the comments below, but please note, I tried to keep it simple, so a very extensive set of codes is not really what I wanted to achieve. Nevertheless I definitely want to see your improvements :).

    I made a little example project in which you can see the code in practise. You can download this project from the Marketplace: https://marketplace.yoyogames.com/assets/5091/smooth-view-example .

    Chapter 2: The scripts and the variables

    The variables / parameters used are summarised in Figure 1.

    [​IMG]
    Figure 1: All variables used by the scripts and some details about them.​

    For the people who would like to see the scripts used, here they are! Of course they can also be download from the Marketplace.

    Code:
    ///smoothview_init(horizontal, speedmodifier, smoothness, limit)
    //
    // Script:      Initialises the smoothview
    // Date:        2018-08-09
    // Copyright:   Appsurd
    //
    // Arguments:
    // argument0:   Horizontal (1) or Vertical (0)
    // argument1:   Speed of the view while swiping (default: 0.33)
    // argument2:   Friction causes to slow down (default: 0.08)
    // argument3:   Limit value used for clicking (default: 2)
    
    // Initialise variables
    drag_speed = 0;
    horizontal = argument0;
    speed_modifier = argument1;
    smooth = argument2;
    limit = argument3;
    
    // Set drag direction
    if (horizontal == 1)
        drag = mouse_y;
    else
        drag = mouse_x;
    

    Code:
    ///smoothview_step()
    //
    // Script:      Handles the movement of the view
    // Date:        2018-08-09
    // Copyright:   Appsurd
    
    // Initialise the movement by pressing
    if (mouse_check_button_pressed(mb_left))
    {
        //Start position for dragging
        drag_speed = 0;
        if (horizontal == 1)
            drag = mouse_x;
        else
            drag = mouse_y;
    }
    
    // Scrolling horizontally
    if (horizontal == 1)
    {
        if (mouse_check_button(mb_left))
        {
            //Drag
            drag_speed = (drag - mouse_x) * speed_modifier;
            view_xview += drag_speed;
        }
    
        if (abs(drag_speed) > 0)
        {
            //Drag slow down effect
            view_xview += drag_speed;
            if (view_xview <= 0 || view_xview >= (room_width-view_wview)) then drag_speed = 0;
            drag_speed += (-drag_speed*smooth);
        }
    
        //Keep the screen within the room
        view_xview = max(0, min(view_xview, room_width - view_wview));
    }
    else
    {
        if (mouse_check_button(mb_left))
        {
            //Drag
            drag_speed = (drag - mouse_y) * speed_modifier;
            view_yview += drag_speed;
        }
    
        if (abs(drag_speed) > 0)
        {
            //Drag slow down effect
            view_yview += drag_speed;
            if (view_yview <= 0 || view_yview >= (room_height-view_hview)) then drag_speed = 0;
            drag_speed += (-drag_speed*smooth);
        }
    
        //Keep the screen within the room
        view_yview = max(0, min(view_yview, room_height - view_hview));
    }
    
    Code:
    ///smoothview_can_press(drag_speed, limit)
    //
    // Script:      Checks whether you may click on a moving button
    //              Used to prevent clicking while dragging
    // Date:        2018-08-09
    // Copyright:   Appsurd
    //
    // Arguments:
    // argument0:   The drag speed of the controller object
    // argument1:   Limit value of pressing
    
    return (abs(argument0) <= argument1);
    

    Conclusion

    The tutorial is finished by now, I hope you have learned how you can apply a smooth scrolling system in your game. If there are any questions or if you find anything unclear, please post your response in the comments below. Thanks for reading the mini tutorial and have fun with your smooth scrolling system!

    Changelog

    Changelog, huh? Yes, it’s actually just for me to check when and what I changed in the tutorial. Any people contributing something will be added too. :)

    V1.0.1 (2018-08-09)

    - Small text changes
    - Minor improvements in the sample project

    V1.0.0 (2017-02-08)

    First English version of the tutorial was written.
     
    Last edited: Aug 10, 2018
    Gradius and SnotWaffle Studios like this.
  2. Parzival

    Parzival Member

    Joined:
    Apr 30, 2017
    Posts:
    18
    Thank you, I think I'll find this useful.
     
    Appsurd likes this.
  3. ethanoh

    ethanoh Member

    Joined:
    Nov 13, 2017
    Posts:
    2
    Thank you, very useful. In case anyone is wondering, for Game Maker Studio 2, you have to adapt the code for the camera/viewport/view system.

    This means adding these lines to the beginning of the Step code:

    Code:
    view_xview = camera_get_view_x(view_camera[0]);
    view_yview = camera_get_view_y(view_camera[0]);
    As well as these lines at the end:

    Code:
    camera_set_view_pos(view_camera[0], view_xview, view_yview);
    And don't forget to enable viewports on your room.
     
    Appsurd and SnotWaffle Studios like this.
  4. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
  5. KLaurence

    KLaurence Member

    Joined:
    Nov 4, 2017
    Posts:
    4
    Thank you for the tutorial! I just wanna ask if you can do it (scroll) in both ways (horizontal and vertical). Thanks!
     
  6. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Hi, great you liked the tutorial! Would you mind rating it in the Marketplace? Thanks!
    https://marketplace.yoyogames.com/assets/5091/smooth-view-example

    As for your question, you can, but it is slightly more difficult. You would need a variable to see in which direction the user is scrolling. By the way, in most cases you need vertical and horizontal scrolling, you don't want scrolling but simply being able to 'drag' the view. For example, when moving over a map. If the last case is applicable to your situation, I would not recommend using this tutorial but implement the dragging yourself instead.
     
  7. VintermGames

    VintermGames Member

    Joined:
    Nov 21, 2017
    Posts:
    12
    Bookmarking this for later use. Scrolling smoothly on mobile apps is SUPER important for making it feel professional. Thank you! :)
     
    Appsurd likes this.
  8. UnknownHello

    UnknownHello Member

    Joined:
    Mar 30, 2018
    Posts:
    2
    Thanks for this tutorial!

    I was wondering if someone could help explain this code slightly more:


    if (mouse_check_button(mb_left))
    {
    //Drag
    drag_speed = (drag - mouse_x) * speed_modifier;
    view_xview += drag_speed;
    }

    In particular the drag_speed = (drag - mouse_x) * speed_modifier;

    This confuses me because as far as I'm aware drag = mouse_x so it's the value of mouse_x - mouse_x, wouldn't this just be 0?

    Thanks :)
     
  9. Appsurd

    Appsurd Member

    Joined:
    Jun 20, 2016
    Posts:
    184
    Thanks!
    As for your question, the key concept is the mouse left button pressed. Here, you set the 'drag' variable, and the mouse_x /mouse_y of course changes while dragging, i.e. the mouse left button. In this way, you can drag around the room ;)
    If you have any further questions, don't hesistate to ask them!
     
  10. UnknownHello

    UnknownHello Member

    Joined:
    Mar 30, 2018
    Posts:
    2
    Thanks :)
     
    Last edited: Mar 31, 2018
  11. JORGE VITTORI

    JORGE VITTORI Member

    Joined:
    Jan 13, 2018
    Posts:
    3
    This is amazing, so thankfull
     
    Appsurd likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice