8
\$\begingroup\$

I am making my own UI for my game, no libraries used, basic UI with simple controls and I am almost done. Now, let's say I need to display lots of information, controls or items which obviously won't fit in the screen space. I must use a scroll bar to achieve this task. But how does one make a scroll bar?

I just don't understand how to do it. The concept for vertical and horizontal scrollbars is the same. Virtually there is a huge plain with data, but we can only display cut of it all in a such by such screen space. We use scrollbars to move that viewable rectangle across our giant plain. The scrollbar itself is a displayed line/texture/sprite on the side of the screen which has a button inside that we can interact with by moving it across the scrollbar. The button is dynamic, its size is relative to total item count and possible item count that can be shown in given space. Our button shrinks when there are more items added, expands when items are getting removed and the whole scrollbar disappears when all the items can be successfully displayed at once.

I can't seem to find online tutorials on this matter. Perhaps it's so basic for everyone except me? Still can't wrap my head around it...

\$\endgroup\$
4
  • \$\begingroup\$ Perhaps you could start by telling everyone in your post what language you are attempting to do this in... \$\endgroup\$
    – Savlon
    Oct 29 '14 at 8:33
  • 2
    \$\begingroup\$ It does not matter. It's Pascal. What matters is how you implement it and I am sure that the code will be the same across other platforms. \$\endgroup\$ Oct 29 '14 at 8:40
  • 2
    \$\begingroup\$ It does matter cause in some languages, the solution is one line of code, maybe two (for instance if it was a javascript web game), even in ActionScript it's very simple. In Pascal, I imagine it might be rather difficult. \$\endgroup\$
    – AturSams
    Oct 29 '14 at 9:35
  • 1
    \$\begingroup\$ @Zehelvion Kable's code worked perfectly, just had to use Round function because I used Integers as coordinates instead of floats. \$\endgroup\$ Oct 29 '14 at 10:08
7
\$\begingroup\$

Let's call the content you want to scroll content and the viewable area of that content viewPort. Your scrollbars will be at the sides of the viewport.

The first step is to create a mask such that only parts within content which intersect with viewPort are visible. I can't answer exactly how to do this because it depends on your language and technologies. Search for something like 'graphics masking in your language'.

The next part is to link the scrollbar's position with the position of content. For a vertical scrollbar, as scrollbar.grip.y increases, content.y should decrease, and vice versa. The following code should set the correct position of content:

content.x = -(horizontalScrollbar.grip.y / horizontalScrollbar.width) * content.width;
content.y = -(verticalScrollbar.grip.y / verticalScrollbar.height) * content.height;

You would run this code whenever the scrollbar positions change. Also, you would need to set the sizes of each scrollbar's 'grip' (the button the user can drag to scroll):

horizontalScrollbar.grip.width = viewPort.width / content.width * horizontalScrollbar.width;
verticalScrollbar.grip.height = viewPort.height / content.height * verticalScrollbar.height;

As well as limit their positions to the scrollbar 'track':

if (horizontalScrollbar.x > horizontalScrollbar.width - horizontalScrollbar) {
    horizontalScrollbar.x = horizontalScrollbar.width - horizontalScrollbar;
}
if (verticalScrollbar.y > verticalScrollbar.height - verticalScrollbar) {
    verticalScrollbar.y = verticalScrollbar.height - verticalScrollbar;
}
\$\endgroup\$
0
3
\$\begingroup\$

A scroll bar is like a 2D camera control that controls the scroll area's viewport's contents. I will assume you know how to render your gui in its entirety. I also strongly advice against making a gui that is complex unless it truly contributes to ux. This could lead to a mediocre gaming experience. I also strongly urge you to use a UI library.

In abstract high level pseudo code:

  1. Initialization:
    1. Define the scrollable area's width and height.
    2. Define the viewport's width and height.
    3. The "handle" is the same % of the scrollbar as the viewport is of the scrollable plain.
      • The "handle" is the rectangle that travels up and down a vertical scrollbar.

Example: The scrollable area's height is 1000 pixels and the viewport's height is 200 pixels so the "handle" will be 20% of the scrollbar's height, if the scrollbar has the same height as the viewport than the handle will be 40 pixels high.

  1. Main loop:

    1. Render the entire scrollable area (if it's not gigantic).
      • Otherwise you need to smartly render only elements close the current position of the viewable area.
    2. The "handle" has an upper and lower bounds in % of the scrollbar.
    3. Blit the relevant rectangle with the same upper and lower % of the scrollable area.
    4. Place the result inside the viewport.
  2. Accepting input:

    1. When a user clicks in the scrollable area's viewport, consider the "handle's" upper bound.
    2. Adjust the click to a position % of the scrollable's area pixels lower based on upper bound.
  3. Dragging the scrollbar's "handle":

    1. Detect a mouseDown event that occurs on the scrollbar.
      • If the event occured on the handle:
        1. Remember the position.
        2. Adjust the handle and viewport with the correct offset from that position until the mouseUp event occurs.
      • If the event occurs on the scrollbar but not on the "handle":
        1. Adjust the "handle" so it's centered on that position.

The explanation is based on a vertical scrollbar but the same applies to a horizontal bar.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .