Appsurd
Member
Smooth scrolling on mobile devices
GM version: GMStudio 2.3.2
Target platform: ALL
Download: https://marketplace.yoyogames.com/assets/5091/smooth-scrolling-example
Links: N/A
Latest change: 2021-08-25
Level: Medium
Summary
This mini tutorial will explain how you can enable smooth scrolling on a mobile device. This is particularly useful in a large menu or for large pieces of text. The tutorial will first explain its functionality and thereafter the scripts are shown. In case you’re just interested to see/use the code, please head for the Marketplace to download it! Of course you can also 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
Many games have a starting menu at the very beginning of your game. Most menus are very small, 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 three times the width/height of the screen) a smooth scrollable menu really beautifies your game. In this tutorial I will discuss a set of scripts for creating a scrollable menu.
This tutorial and all its assets are completely free, there is no need for any credit. 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 smooth scrolling system, we will need an object to handle it. Let’s create an object called obj_smoothview to handle it all. We do not need any advanced camera function for this project, because we can use the build-in views. We need to activate view 0 since this view will be used for scrolling. You can activate a view by going to the room editor of your room. In the left panel, under Properties -> Viewports and Cameras, you need to select "Enable viewports". Then you need to go to "Viewport 0" and select "visible". I expect you to know what views are and how they work, 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 direction. 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).
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 drag_speed is zero.
GML:
// Initialise the movement by pressing using the left mouse button
if (mouse_check_button_pressed(mb_left))
{
drag_speed = 0;
if (drag_horizontally)
drag = mouse_x;
else
drag = mouse_y;
}
GML:
// Dragging
if (mouse_check_button(mb_left))
{
drag_speed = (drag - mouse_y) * speed_modifier;
camera_set_view_pos(view_camera[0], 0, camera_get_view_y(view_camera[0]) + drag_speed);
}
But we wanted to slowly reduce the speed of the movement, so we get a nice scrolling effect. 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:
GML:
// Drag slow down effect
if (abs(drag_speed) > 0)
{
camera_set_view_pos(view_camera[0], 0, camera_get_view_y(view_camera[0]) + drag_speed);
if (camera_get_view_y(view_camera[0]) <= 0 || camera_get_view_y(view_camera[0]) >= (room_height-camera_get_view_height(view_camera[0]))) then drag_speed = 0;
drag_speed += (-drag_speed*smooth);
}
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 make sure that we strictly remain inside the room. So we will need another line just below the previous code, which is the following:
GML:
// Keep the screen within the room
camera_set_view_pos(view_camera[0], 0, round(max(0, min(camera_get_view_y(view_camera[0]), room_height - camera_get_view_height(view_camera[0])))));
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 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-scrolling-example .
Chapter 2: The scripts and the variables
All variables used for the smooth scrolling are summarised in Figure 1.
Figure 1: All variables for smooth view scrolling.
For the people who would like to see the scripts used, here they are! Of course they can also be download from the Marketplace.
GML:
/// @function smoothview_init(drag_horizontally, speed_modifier, smoothness, limit)
/// @param {boolean} drag_horizontally Horizontal (1) or Vertical (0)
/// @param {real} speedmodifier Speed of the view while swiping (default: 0.33)
/// @param {real} smoothness Friction causes to slow down (default: 0.08)
/// @param {real} limit Limit value used for clicking (default: 2)
///
/// @description Initialises the smoothview
/// @date 2021-08-25
/// @copyright Appsurd
function smoothview_init(argument0, argument1, argument2, argument3) {
// Initialise variables
drag_speed = 0;
drag_horizontally = argument0;
speed_modifier = argument1;
smooth = argument2;
limit = argument3;
// Set drag direction
if (drag_horizontally)
drag = mouse_x;
else
drag = mouse_y;
}
GML:
/// @function smoothview_step()
///
/// @description Handles the movement of the view
/// @date 2021-08-25
/// @copyright Appsurd
function smoothview_step() {
// Initialise the movement by pressing using the left mouse button
if (mouse_check_button_pressed(mb_left))
{
//Start position for dragging
drag_speed = 0;
if (drag_horizontally)
drag = mouse_x;
else
drag = mouse_y;
}
// Scrolling horizontally
if (drag_horizontally)
{
//Drag
if (mouse_check_button(mb_left))
{
drag_speed = (drag - mouse_x) * speed_modifier;
camera_set_view_pos(view_camera[0], camera_get_view_x(view_camera[0]) + drag_speed, 0);
}
//Drag slow down effect
if (abs(drag_speed) > 0)
{
camera_set_view_pos(view_camera[0], camera_get_view_x(view_camera[0]) + drag_speed, 0);
if (camera_get_view_x(view_camera[0]) <= 0 || camera_get_view_x(view_camera[0]) >= (room_width-camera_get_view_width(view_camera[0]))) then drag_speed = 0;
drag_speed += (-drag_speed*smooth);
}
// Keep the screen within the room
camera_set_view_pos(view_camera[0], round(max(0, min(camera_get_view_x(view_camera[0]), room_width - camera_get_view_width(view_camera[0])))), 0);
}
else
{
// Dragging
if (mouse_check_button(mb_left))
{
drag_speed = (drag - mouse_y) * speed_modifier;
camera_set_view_pos(view_camera[0], 0, camera_get_view_y(view_camera[0]) + drag_speed);
}
// Drag slow down effect
if (abs(drag_speed) > 0)
{
camera_set_view_pos(view_camera[0], 0, camera_get_view_y(view_camera[0]) + drag_speed);
if (camera_get_view_y(view_camera[0]) <= 0 || camera_get_view_y(view_camera[0]) >= (room_height-camera_get_view_height(view_camera[0]))) then drag_speed = 0;
drag_speed += (-drag_speed*smooth);
}
// Keep the screen within the room
camera_set_view_pos(view_camera[0], 0, round(max(0, min(camera_get_view_y(view_camera[0]), room_height - camera_get_view_height(view_camera[0])))));
}
}
GML:
/// @function smoothview_can_press(drag_speed, limit)
/// @param {real} drag_speed The drag speed of the controller object
/// @param {real} limit Limit value of pressing
///
/// @description Checks whether you may click on a moving button
/// Used to prevent clicking while dragging
/// @date 2021-08-25
/// @copyright Appsurd
function smoothview_can_press(drag_speed, limit) {
return (abs(drag_speed) <= limit);
}
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 this mini tutorial and have fun with your smooth scrolling system!
Changelog
V1.0.0 (2017-02-08)
First English version of the tutorial was written.
V1.0.1 (2018-08-09)
- Small text changes
- Minor improvements in the sample project
V1.1.1 (2021-08-25)
- Update to GMS 2.3+
- Improved variable names
- Improved tutorial explanation
First English version of the tutorial was written.
V1.0.1 (2018-08-09)
- Small text changes
- Minor improvements in the sample project
V1.1.1 (2021-08-25)
- Update to GMS 2.3+
- Improved variable names
- Improved tutorial explanation
Last edited: