Very long, non-repeatative scrolling bakground logic

Hello Everyone,

I’m stuck with logic for my scrolling background. I already went through a lot of discussions and posts on similar topic on and off this forum. 

Basically I have around 50 background images that I want to scroll one after another. No background is same and once a background is off screen it will never come again.

I did figure out that loading all bg’s and scrolling them is not a way to go. I also tried loading three bg’s at a time and as soon as 1st is offscreen destroying it and loading the 4th one after the 3rd and so on. None of the things I tried seems to work efficiently and flawlessly.

Someone please suggest a simple and a efficient way to do it. 

Thanks.

Your problem is basically, that the amount of data you are trying to load is to big. As a result it effects the performance.

The only way I see is splitting up your background into smaller chunks, which can easier be loaded to prevent performance issues.

Thanks …

Yes I got that point but the problem is that my background is already divided into 50 chunks , each chunk being same size as the device’s screen. So how can I use them without hampering performance or exhausting texture memory. 

As I said, make the chunks smaller.

Doing so, the amount of data that has to be loaded each frame is smaller, which should prevent performance issues.

Would I be right in thinking that your game only scrolls in one direction? I’m basing that on this:

No background is same and once a background is off screen it will never come again.

If that’s the case, you only need to load 2 images at a time: the current screen plus the next screen. That way even when the current image is halfway offscreen, the second image is halfway onscreen. 

However this requires 2 full screen sized images to be loaded into memory. If you use torbenratzlaff’s suggestion and cut each image in half you could get away with having 3 “half screen” sized images loaded into memory at once instead.  

You would load 2 half sized images which make up the current screen, plus another half sized image for the upcoming screen half.

This alone would cut down the texture memory being used by 25% which is a pretty good saving.

Not sure if this example of how the images would be “chained” will be clear or not once I post it:

[curr1][curr2][next1] [devicescreen]

It means loading more individual images, but less texture memory is being used at any one time so performance should be improved. 

If you were to cut the images down even further and load more “sections” at a time, you could save even more texture memory (though how well this works will be dependant on how fast your game scrolls so that you don’t get gaps where an image has not loaded yet).

Also how big are your source images? It could be that you’ve made them bigger than they need to be (e.g. 4096 * 4096 pixels per image which would be overkill).

Hello,

The size of my images is 1140*720. I tried loading only 3 images initially (overall 1.5 screen size ) and then loading the rest later as the game progresses. However sometimes I see that due to some kind of a minute delay there is a very minute gap created between 2 images. It doesn’t happen all time but some time it does. 

Maybe I need to re design my complete background so that it gives a perfect scroll :frowning:

Also, if you’re not already using it, consider bitmap resources: TextureBitmapResource

If it’s only slight blips you’re experiencing, you might do well by loading say half or one screen in advance. The initial screen could use a different but similar strategy if, say, you could hide it behind a menu.

Just a thought, anyhow.

Thanks for the link … I hope it solve’s my issue of gap appearing between 2 screens. 

This is my code. I have used only two bg’s this time

 sceneSpeed = 12; gamePaused = false; bg1 = display.newImageRect(PLAY,"assets/images/bg/1.jpg",\_W,\_H) bg2 = display.newImageRect(PLAY,"assets/images/bg/1.jpg",\_W,\_H) bg2.x=\_W local function scrollWorld(self,event) if self.x \< -\_W then self.x = \_W elseif gamePaused == false then self.x = self.x - sceneSpeed; end end bg1.enterFrame = scrollWorld; bg2.enterFrame = scrollWorld; Runtime:addEventListener("enterFrame", bg1) Runtime:addEventListener("enterFrame", bg2)

 Using two’s bg’s also causes a gap to be created between the two. (refer attached pic)

How big (in kb or mb) are the .jpgs? If you convert them to .png, you could use a site like tinypng.com to make them much smaller.

Tried that too … reduced quality to some extent too. Same issue. Currently size is 900 kb approx

I would suggest using a single global Runtime listener to move all background images with a for loop.

There’s no need for each image having it’s own runtime. Maybe the gap (assuming the initial positioning is correct) is related to this too?

Your problem is basically, that the amount of data you are trying to load is to big. As a result it effects the performance.

The only way I see is splitting up your background into smaller chunks, which can easier be loaded to prevent performance issues.

Thanks …

Yes I got that point but the problem is that my background is already divided into 50 chunks , each chunk being same size as the device’s screen. So how can I use them without hampering performance or exhausting texture memory. 

As I said, make the chunks smaller.

Doing so, the amount of data that has to be loaded each frame is smaller, which should prevent performance issues.

Would I be right in thinking that your game only scrolls in one direction? I’m basing that on this:

No background is same and once a background is off screen it will never come again.

If that’s the case, you only need to load 2 images at a time: the current screen plus the next screen. That way even when the current image is halfway offscreen, the second image is halfway onscreen. 

However this requires 2 full screen sized images to be loaded into memory. If you use torbenratzlaff’s suggestion and cut each image in half you could get away with having 3 “half screen” sized images loaded into memory at once instead.  

You would load 2 half sized images which make up the current screen, plus another half sized image for the upcoming screen half.

This alone would cut down the texture memory being used by 25% which is a pretty good saving.

Not sure if this example of how the images would be “chained” will be clear or not once I post it:

[curr1][curr2][next1] [devicescreen]

It means loading more individual images, but less texture memory is being used at any one time so performance should be improved. 

If you were to cut the images down even further and load more “sections” at a time, you could save even more texture memory (though how well this works will be dependant on how fast your game scrolls so that you don’t get gaps where an image has not loaded yet).

Also how big are your source images? It could be that you’ve made them bigger than they need to be (e.g. 4096 * 4096 pixels per image which would be overkill).

Hello,

The size of my images is 1140*720. I tried loading only 3 images initially (overall 1.5 screen size ) and then loading the rest later as the game progresses. However sometimes I see that due to some kind of a minute delay there is a very minute gap created between 2 images. It doesn’t happen all time but some time it does. 

Maybe I need to re design my complete background so that it gives a perfect scroll :frowning:

Also, if you’re not already using it, consider bitmap resources: TextureBitmapResource

If it’s only slight blips you’re experiencing, you might do well by loading say half or one screen in advance. The initial screen could use a different but similar strategy if, say, you could hide it behind a menu.

Just a thought, anyhow.

Thanks for the link … I hope it solve’s my issue of gap appearing between 2 screens. 

This is my code. I have used only two bg’s this time

 sceneSpeed = 12; gamePaused = false; bg1 = display.newImageRect(PLAY,"assets/images/bg/1.jpg",\_W,\_H) bg2 = display.newImageRect(PLAY,"assets/images/bg/1.jpg",\_W,\_H) bg2.x=\_W local function scrollWorld(self,event) if self.x \< -\_W then self.x = \_W elseif gamePaused == false then self.x = self.x - sceneSpeed; end end bg1.enterFrame = scrollWorld; bg2.enterFrame = scrollWorld; Runtime:addEventListener("enterFrame", bg1) Runtime:addEventListener("enterFrame", bg2)

 Using two’s bg’s also causes a gap to be created between the two. (refer attached pic)