I am trying to figure out the best way to scroll through images … Basically, a bunch of movie posters in a table. I looked at the scroll example and they just have one giant image and set the region to wrap. Is there a way to draw multiple images in a region outside the screen and scroll through them or is there a better way in the 2D roku world ?
This all depends upon how many posters you have. You can quickly reach memory limits especially on the older boxes which have less than the 3 box. You can view your memory requirements using a telnet session with the ip of your box at port 8080. Then issue the command r2d2_bitmaps a couple of times and that will dump memory for you so you can see the maximum, total used, and total available. If you have a large number of posters that exceed memory then things get really complex.
There are essentially two ways to perform a grid scroll. The first and most popular I believe, is to layout your bitmaps (start with one row ) across the screen using offsets.
Generally each poster is the same size. So you start at a fixed y coordinate, say 50, and your x coordinate would be 0. assign your bitmaps to an array.
You can get the dimensions of your screen using roDeviceInfo. What you are attempting is quite a job for a noobie, especially one who does not check return values
l_width = the bitmap width + any margin between bitmaps
l_x = 0
l_y = 50
Clear screen
For each bitmap in bitmapArray
Screen.DrawObject( l_x, l_y, bitmap )
l_x = l_x + l_width
end for
Screen.SwapBuffers()
When you have that much then you can use a simple Robert Penner ease to nicely slide the bitmaps across the screen. Your really going to have to take this one step at a time. Most people start out with simple things. A grid is not simple and gets messy when you have to download images during scrolling. ROKU is a world of asynchronous operations in a single-threaded environment. It’s going to take time to get to know the API
enough to write a reliable grid. If you can load all your bitmaps without sinking memory, then the job is much simpler
Thanks for the advice “NewManLiving”, I only have to support vertical scrolling so hopefully that will make it a bit easier but still a daunting task I am sure.
If you can load all the bitmaps at once and are using a single row then it is much simpler. There is an example floating around somewhere, I’ll see if I could find it
That would be most appreciated. Thank You
I have my grid of posters drawn ( 3 posters across and multiple rows). I used the TextureManager to boost performance when downloading the bitmaps asynchronously.
The set up the grid using a variation of the code shown by NewManLiving:
l_width = the bitmap width + any margin between bitmaps
l_x = 0
l_y = 50
Clear screen
For each bitmap in bitmapArray
Screen.DrawObject( l_x, l_y, bitmap )
l_x = l_x + l_width
end for
Screen.SwapBuffers()
So now I am back to my original question how do I emulate smooth scrolling ? I only have to scroll vertically and not horizontally, so essentially moving the rows up and down with some image easing to make it look smooth. I found this in the forum, posted by NewMan Living:
' In this example we are moving the x position it would be the same for y you just move in the y direction instead of x
curr_time = 0 ' START TIME OR FRAME IS USUALLY 0 OR 1 DEPENDING ON YOUR FLAVOR
start_val = 100 ' START X OR Y POSITION DEPNDING ON MOVEMENT DIRECTION (CURRENT X POS OF YOUR SPRITE)
change_val = 800 ' WHERE WE ARE MOVING TO FROM START_VAL THIS WOULD BE X OR Y AS MENTIONED IN PREV LINE
duration = 30 ' HOW LONG SHOULD IT TAKE TO EASE THERE. To go back just use a negative ( -newX)
for i = 0 to duration
newX = CubeEaseOut(curr_time + i, start_val, change_val, duration)
end for
Function CubeEaseOut(t_from_frame As Float, d_to_frame As Float, b_from_xory As Float, c_to_xory As Float) As Integer
l_ff! = t_from_frame / d_to_frame
l_ff! = l_ff! - 1.0
l_val! = c_to_xory *(l_ff! * l_ff! * l_ff! + 1.0) + b_from_xory
l_ret% = int(l_val!)
return l_ret%
End Function
The question is when I get the newY (in my case), do I need to just redraw the whole row with the same Y and then the rows below it with a delta Y to make it look like it will scroll ? I am only using the 2D API to accomplish this and am just trying to make sense of the easing concept to accomplish this
Are you scrolling off screen and need the ability to wrap around again to bottom/top ? If so what are the size of your posters
Also what size is the space between the posters as well as the margin or space between the rows
Here are the sizes of the posters :
poster_height = 285
poster_row_pad = 50
poster_width = 201
poster_column_pad = 50
I have one row of 3 posters shown completely at the top and a row of posters cropped on underneath it. when I hit the down button obviously the intent is to have the cropped images below come into full view and the next row cropped the way it was before. When I reach the bottom the user would have to scroll all the way back up, no wrapping
how are you cropping ( not displaying all of the bitmap ) the bottom row? Are you using regions or just bitmaps and roScreen? Are you creating a region within your roScreen? Your poster height + margin * row number ( which includes the background margin at the bottom) would not crop in a 1280 * 720 resolution. ( 285 + 50 ) * 2 = 670, if you start your rows at the very top
You can create a region within roScreen and use that region to crop for you. Then you can place your region anywhere within the bounds of the roScreen. You are limited as to what you can do with that region but you can certainly drawObject with different offsets and it will crop it properly
Or simply do you have more than two rows ???
Yes, I have multiple rows.
Here is how I am drawing the images:
Function DrawPosters(screen, a_coordinates)
for each coordinate in a_coordinates
screen.DrawScaledObject( coordinate.x, coordinate.y, 0.75, 0.75, coordinate.image )
end for
End Function
So, essentially the cropping is just the bitmap being drawn partially off the screen.
Well that clears than one up. Now the big question - Are you able to load all of your posters without running out of memory ( not the same on all devices ). Or do you plan on retrieving as you go along. This is a REALLY BIG IF.
That is the big question. Currently, the plan is to grab them all at once with the texture manager but may need to change my strategy if a “lot” of movies come into inventory. I am currently developing / testing on a roku3 but as you have pointed out, each one is different
Got to leave will get back.
What you are trying to accomplish is quite an undertaking. Now if you were to restrict yourself to ROKU 3 then you would have less of a problem and more freedom to use the standard method of offsetting bitmap coordinates. However, due to the processor/disk intensive nature of the texturemanager as well as the need to update your screen constantly as bitmaps arrive, the lower-end boxes do not perform well and the response Is more jarring rather than smooth, if you allow the user to scroll while bitmaps are coming in. In my experience ( and I have tried using just regions and bitmaps ), Use of the Compositor, sprites and regions has several advantages. First, the compositor is responsible for drawing all sprites. So one call to compositor.DrawAll takes care of all drawing. Otherwise you would be in a constant loop iterating through each row to refresh the screen with the incoming bitmaps. Second, region offsetting is preferable to changing coordinates of the rows of bitmaps. Only the new row is drawn in and the other rows that are in the display are “scrolled off” by movement of the region alone. This allows you to keep the coordinates of most of the bitmaps intact and therefore your texture receiver can pop in the textures as they arrive. otherwise you would have to let the texture receiver know that all the coordinates have changed, because the user just scrolled. This becomes a big problem with easing since you are in a coordinate-changing loop. Bitmaps arrive very quickly putting you into an instant whirlpool. Composite drawing and region easing is far more optimal
A while ago I posted an example of a grid that does not use the texture manager. I have since improved on the grid itself choosing to use a display stack to wrap around instead of indexing. This is very optimal since there is only a few rows that can be displayed at one time on the screen with your standard poster sizes ( 2-3 ). So pushing and popping indexes is very fast and there is no indexing or math involved. It also is a more natural fit for easing regions. I have also added a cachemanager object which incorporates the texturemanager
While I do not mind sharing the new grid, It is useless if you cannot understand how it works, or have a bias against composite, sprites and regions as some developers seem to have. Thus I have not put the new grid out on the forum. My suggestion is to run the old grid and study my style and logic. Although I have refined many things the core is the same. If you can work at understanding it and see it as beneficial for yourself then I many consider releasing the new grid, It really is nice and performs very well at least on what I am able to test it on (3, new stick, and 2xd ) I plan on getting a 1 box (amazon) to see how it performs. The link to the old samlple grid is below
ok, thanks I will look into the “old” code and figure it out.
“NewManLiving” wrote:
or have a bias against composite, sprites and regions as some developers seem to have
Whaaaat?
Now I was not referring to y
u my friend. It was you who influenced
Me to use both screen and compositor which I now do. But I recall that my “passion” for
The compositor as you once called it did initially meet with some resistance.
After all ( as far as I can tell, you would know more) There are appears to
Be only a handful of 2d developers on this Forum. And I believe that most
Use coordinate offsetting as far as anything similar to a
Grid is concerned.
I think whether you use the compositor functions is mainly a matter of personal preference. Personally I’ve written a dozen or so significant apps using the 2D API but I’ve never used the compositor. This is mainly just because drawing without the compositor is more similar to what I’ve done on other platforms. I haven’t done any measurements but I’d be surprised if there was a significant performance difference, except perhaps for a few things like collision detection.
–Mark
