Legacy GM Smooth scrolling on mobile devices

Appsurd

Member
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.


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:
E

ethanoh

Guest
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.
 
K

KLaurence

Guest
Thank you for the tutorial! I just wanna ask if you can do it (scroll) in both ways (horizontal and vertical). Thanks!
 

Appsurd

Member
Thank you for the tutorial! I just wanna ask if you can do it (scroll) in both ways (horizontal and vertical). Thanks!
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.
 
V

VintermGames

Guest
Bookmarking this for later use. Scrolling smoothly on mobile apps is SUPER important for making it feel professional. Thank you! :)
 
U

UnknownHello

Guest
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 :)
 

Appsurd

Member
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!
 
Top