# How to create an endless scrolling background?

I need to add a scrolling background to a my game, the image is 512x512px. It's for a car game with two way traffic and I want to be able to cross over to the opposite side and drive against the traffic too. The game is in portrait mode and I use cocos2d.

How can I make this in the best possible way?

• Will the background wrap along x and y or only in one direction? – Ricket Aug 12 '10 at 0:48
• Also what are the screen dimensions? I.e. will the screen always be smaller than 512x512? – Ricket Aug 12 '10 at 0:49

I'd basically create a 2x2 tilemap where the tiles happen to be 512x512 and all the same. Scroll through it as you would normally but as soon as X gets over 512 subtract 512 (or do a modulo 512 - but beware of negative numbers), same for Y. So instead of one poly you draw 4, although only 1 will be visible most of the time, but on border cases all 4 are visible (when you go 400 down and 400 to the right for example). This way it should scroll on forever.

Of course you can also use 4 sprites instead of a tilemap. One at worldPos, one at worldPos+(512,0), one at worldPos + (0,512) and one at worldPos + (512,512).
Make sure worldPos is always modulo 512 and again it should scroll forever.

Edited to add some code:

Untested, not syntax checked.
Very hardcoded to solve this problem. It would be better with an actual array for a map, but for this specific problem this should work.
Assumes 0,0 to be the top left of the screen.

void DrawBG( int worldX, int worldY)
{
const int tileW = 512;
const int tileH = 320;

int worldXMod = worldX % tileW;
if (worldXMod < 0) worldXMod += tileW;   // handle negative numbers

int worldYMod = worldY % tileH;
if (worldYMod < 0) worldYMod += tileH;   // handle negative numbers

int tileLeft = -worldXMod;
int tileTop  = -worldYMod;

int spriteTopLeftY = tileLeft;
int spriteTopLeftY = tileTop;

int spriteTopRightX = spriteTopLeftX + tileW;
int spriteTopRightY = spriteTopLeftY;

int spriteBottomLeftX = spriteTopLeftX;
int spriteBottomLeftY = spriteTopLeftY + TileH;

int spriteBottomRightX = spriteTopRightX;
int spriteBottomRightY = spriteBottomLeftY;

// whatever the syntax of sprite drawing or setting its position is...
DrawSprite(spriteTopLeftX, spriteTopLeftY);
DrawSprite(spriteTopRightX, spriteTopRightY);
DrawSprite(spriteBottomLeftX, spriteBottonLeftY);
DrawSprite(spriteBottomRightX, spriteBottomRightY);
}
• In the case of modulo, negative numbers aren't an issue (at least for Objective-C; in Java, they are). – Ricket Aug 12 '10 at 1:35
• Really? Okay...it's machine dependent, I guess the iPhone is blessed. Haven't touched Objective-C for a year and a half. – Kaj Aug 12 '10 at 2:04
• Well actually, to be honest I haven't actually tried it on Objective-C. I'm making an educated guess based on the fact that AFAIK Java is the only one where % is not modulo, it's "remainder". Any other language I've seen handles % like modulo; -1 % 3 should be 2. But in Java, it's 1. I have not literally tested Objective-C but if it behaves like it's supposed to then -1 % 3 is 2 and indeed modulo will work correctly even for negative numbers. – Ricket Aug 12 '10 at 13:45
• No, in C it's (apparently, too lazy to check the standard at this ungodly hour) machine dependant. I just verified on my laptop that -5 % 3 equals -2. – Kaj Aug 12 '10 at 14:41
• Can someone post some code please, all these numbers just make me dizzy. I've been developing for almost 3 months so I'm not an expert yet. I liked the 4 sprites way Kaj talked about, it sounds like the easiest way. Can you show me a code sample for this, I learn faster from looking at code and playing around with it. I have changed the image size to 512x320px. Can anyone help me out please? David – David Holmes Aug 12 '10 at 19:55

If I understand you correctly, you can create a set of images. Each image has an entry point and an exit point. To make things easy, you can make all the entry points and exits the same location. Then, you can randomly go between different images so that the player won't encounter a completely redundant level. If you want to mix things up a bit, you could create images that have different entrance and exits. You'll just have to do a little more work to make sure the exit of one image matches the entrance of the next image.