Scrolling in BGE

Does anyone have any ideas on the methodology for implementing a scroll bar window function in the BGE? I’m looking to build a generic background that allows up/down scrolling through a list of items. My thought is to use it for an inventory list of items that are also selectable.

I haven’t written any of the code yet, but my thoughts are to loop through the list and add a UV Text object for each item. Using a standard Z offset, the UV text items would be in a single XY plane. I’d check the middle mouse scroll (don’t know if this is available via the KX_modules in 2.54) to move the camera up and down the list of UV Text objects. I’ll either need to monitor the camera position, the mouse over, and LMB to determine if an items is selected … OR … I could add the mouse over and LMB sensors to each UV Text object created and then link to a script if selected.

So … two basic questions … 1. Anyone have any ideas on how to implement? and 2. Has anyone done this before and have an example they would like to share?

Appreciate any feedback … thanks!


Why would you do that? If you’re scrolling uv text just use a UV scroll script… Get the wheel up/down and interpret that into the script that manipulates the UV’s.

Basically you’re going to make a large graphic with your whole text/dialog/quest whatever it’s for and run the UV scroll script on it.

If you want a UV script i wrote one a while ago. Go into the resources and click on the sticky “useful treads” then click on the script repository. Mine on the first page doesn’t work with 2.54 but someone rewrote it on the second page or so.

EDIT: here ya go:

I have created a scroll box, however it may not be very helpful, the code is very messy. I used Moguri’s bgui, so if you’re unfamiliar with that, the code is probably going to be even more confusing.

In my example, I have a list for the actual text objects and a list for the text that needs to go into the text objects.

Anyway, you want to check out lib\, the drag_scroll_box() is the one of interest.
The lines:

mouse = bge.logic.mouse
pos = list(mouse.position)
pos[0] *= bge.render.getWindowWidth()
pos[1] = bge.render.getWindowHeight() - (bge.render.getWindowHeight() * pos[1])
y = pos[1] - self.scroll_bar.position[1]
y /= self.scroll_bar.size[1]

c_pos = self.scroll_box.position[1] # current position
c_pos -= self.scroll_bar.position[1]
c_pos /= self.scroll_bar.size[1]

should be ignored, they are simply normalising position values.

The next line

difference = y - self.file_scroll_box_click_pos

describes how far the scroll bar has moved since it was first clicked. The ‘self.file_scroll_box_click_pos’ variable describes the position of the scroll box from the previous frame, it is used to calculate how far its traveled since.

self.scroll_box._update_position([1,min(1,13/self.file_total_files)], [0, max(0, min(1-min(1,13/self.file_total_files),c_pos+difference))])

self.file_scroll_box_click_pos = y

These lines update the display of the scroll box and the old position variable for next frame. Your code for changing the scroll box’s position may be different because the lines are represented from bottom to top in python and top to bottom graphically (like I said, messy!). The 13 is there because it is the number of lines in the scroll box.

incriment = (1-min(1,13/self.file_total_files))/(self.file_total_files-13)
if incriment == 0:

I was actually a little stumped looking at this, I had forgotten what it is for (note to self, more comments ^^). It describes how a line translates into the scroll bar, i.e how many pixels the scroll box has to move before all the lines are moved and as such, if it is 0, no line movement is needed and the function can return.

c_item = self.file_total_files - int(c_pos/incriment) - 13
if c_item != self.file_view:

The above determines which item is to be displayed at the top (c_item, an index for the text object list). Again, the -13 is there because my lines are upside down in code (and there is 13 of them). self.file_view is the item which is currently at the top of the scroll box. self.update_scroll_box_items() is a function which re-orders the scroll box, with c_item being the one at the top. That function is as follows:

def update_scroll_box_items(self, c_item):
    for n in range(13):
        if c_item + n < len(self.folders):
            text = self.folders[c_item+n]
            self.file_icons[n] = bgui.Image(self.file_rows[12-n], 'file_icon_'+str(n), bge.logic.expandPath("//textures\\folder.png"), size=[20/600, 20/25],
                pos=[80/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
        elif c_item + n < self.file_total_files:
            text = self.files[c_item + n - len(self.folders)]
            self.file_icons[n] = bgui.Image(self.file_rows[12-n], 'file_icon_'+str(n), bge.logic.expandPath("//textures\\file.png"), size=[20/600, 20/25],
                pos=[80/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
            text = ''
        self.file_items[n] = bgui.Label(self.file_rows[12-n], 'file_item_'+str(n), text, font=bge.logic.expandPath("//fonts\\MankSans.ttf"), pt_size=20, color=(0,0,0,1),
        pos=[100/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
    self.file_view = c_item

What you need to take away from that function is the c_item + n for the index of the lines list, not simply n. The rest of the code fills in all the text objects based on the c_item + n index.

I hope I didn’t confuse you too much, I also hope the steps I have described help you to create a scroll box regardless if you use the bgui or not.

My example file is here: (2.54)

Run it a select ‘Open’, its a file browser which is still a bit buggy but its a scroll box nonetheless.

I’d just do what you’ve suggested already. Stick a plane with some parented text objects in front of the camera. Move the camera or the plane up and down. If you like you can have some textured child planes that look like scroll buttons. Thats all they ever were anyway even in Windows and Visual Basic.

@Equip: The problem with that is the fact that if you’re making a game and you want to have a dialog box with scrolling content the camera scrolling would be useless.

Equip’s idea (I guess it’s actually N2B’s idea) sounds fine:

Create an overlay scene for the inventory screen.

Create a UV-Text object (or a plane with Text enabled, and with a button image behind it) for each item in the inventory, and have each one created one item height below the previous.

Create a Dialog-box image that’s behind all of the text objects, and parent the image to the camera. When you scroll the middle button, or press the up and down arrows, or move the selection box up and down past each item selection (ala Final Fantasy or other RPG games), move the camera, either
A. by a small number because you’re scrolling with the middle mouse button, or
B. for the height of each item listing. The background image should stay with the camera, and the effect should be achieved.

Sorry for the delayed response … I’ve been beating the pavement looking for a job :frowning:

@Killer - checked out your link - That’s a GREAT scroll for something like an end of movie credits and I may end up using a variation for game credits, but for now I’m looking for something more along the lines of a scrollable, selectable inventory listing. In a UV Text image, is there any way to select a single line? Thanks for the feedback!

@andrew-101 - haven’t been able to access Google Docs for your example - say’s the requested file does not exist; and I haven’t had time to go over your listing in detail. I’ve got reserve duty this weekend so I’ll check it out next week - thanks for the feedback!

@joeman16 - My initial thought was to allow a scroll by some fraction of the image height; but your idea of limiting the scroll to each entry may be the way to go … will work on it next week and holler if I have problems … thanks for the feedback!


I have changed the privacy settings, give the link a go again. If its still not working I’ll have to mirror it.