Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How can I make a background repeat infinitely?  (Read 2003 times)

0 Members and 1 Guest are viewing this topic.

Zuzanno_

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
How can I make a background repeat infinitely?
« on: January 18, 2023, 08:58:40 pm »
Hi!

I'm currently working on a game and I am trying to make the background repeat infinitely (Tiling) as the character moves towards +X or -X position. Reading the documentation and some older posts in this forum I found the SetRepeated(); function, however, it does not work as I wish it to as it will only work if the texture is smaller than a defined rectangle type, but as this is a background texture I could not make the rectangle infinitely large.

What I'm currently looking for is a way in which I could repeat the texture to the X axis infinitely as the game is supposedly infinite.

The current code that I have for the texture and the background is the following:

//BG
    sf::Texture bgText;
    sf::Sprite bg;
    sf::Vector2u TextureSize;
    sf::Vector2u WindowSize;

 if (!bgText.loadFromFile("Media/Background.jpg"))
    {
        return -1;
    }
    else
    {
        TextureSize = bgText.getSize();
        WindowSize = window.getSize();

        float ScaleX = (float)WindowSize.x / TextureSize.x;
        float ScaleY = (float)WindowSize.y / TextureSize.y;

        bg.setTexture(bgText);
        bg.setScale(ScaleX, ScaleY);
    }
 

I would appreciate any suggestions on how I could do this, many thanks

P.S: I'm doing everything in the main function without making use of any other functions.

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: How can I make a background repeat infinitely?
« Reply #1 on: January 18, 2023, 11:16:13 pm »
One idea is, instead of having one background rectangle, you have multiple side-by-side rectangles that extend beyond the bounds of the window/view. Each of these rectangles has your background texture. This assumes your background texture is seamless so that you don't notice the multiple rectangles, but it sounds like you already have that covered.

Then as your character and view move to the right, for example, you can check if the bounds of the view are close to the edge of the furthest right background rectangle. When this happens, you can create another new rectangle even further to the right. You can also delete the furthest left rectangle once it is no longer within the view. When your character moves left you can create a new rectangle to the left as needed, and delete the furthest right rectangle. This gives the illusion of an infinite background when really you're just creating and deleting background rectangles as needed.

Zuzanno_

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: How can I make a background repeat infinitely?
« Reply #2 on: January 19, 2023, 12:06:56 am »
Thank you! That sounds like a wise idea, that way it doesn't just generate a lot of tiles using up a lot of memory. While I do appreciate your suggestion I would also like to ask you if you could please show me how it would look code-wise. Thank you! :)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: How can I make a background repeat infinitely?
« Reply #3 on: January 19, 2023, 10:59:19 am »
You can enable repeating on the texture, then it will infinitely repeat the same tile.

https://www.sfml-dev.org/documentation/2.5.1/classsf_1_1Texture.php#aaa87d1eff053b9d4d34a24c784a28658

You'll then need to adjust the texture rect to expand beyond the texture itself and you'll see the texture repeating.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: How can I make a background repeat infinitely?
« Reply #4 on: January 19, 2023, 02:41:01 pm »
Here's a little one I made.
Let's say the window and the background texture are 1920x1080.
It uses a single sprite of the background set to 3 times the width of the texture (so it repeats 3 times).
It then snaps the sprite to positions that are multiples of the width (1920). So as the camera pans to the side, the background will ocassionally jump 1920 pixels so it's always filling the window.

It can actually be done with a 2 time repeating texture, but handling -X positions becomes a little trickier, so I just used 3 repeats.

Some code fragments
// Make a sprite with the background texture like normal.
// Then set it like this:
tex->setRepeated(true);
sf::Vector2u texSize = tex->getSize();
sprite->setTextureRect(sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(texSize.x * 3, texSize.y)));

// Later in your rendering code do this:
sf::View view = window.getView();
sf::Vector2f pos = view.getCenter() - view.getSize() * 0.5f; // Find top left corner of the view
pos.x = int(pos.x / texSize.x) * int(texSize.x)-int(texSize.x); // Snap the X coord to multiples of width
sprite->setPosition(pos);
window.draw(*sprite);
 

Or if I was doing it for myself, I'd probably do a shader version.

Zuzanno_

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: How can I make a background repeat infinitely?
« Reply #5 on: January 20, 2023, 04:26:12 am »
Here's a little one I made.
Let's say the window and the background texture are 1920x1080.
It uses a single sprite of the background set to 3 times the width of the texture (so it repeats 3 times).
It then snaps the sprite to positions that are multiples of the width (1920). So as the camera pans to the side, the background will ocassionally jump 1920 pixels so it's always filling the window.

It can actually be done with a 2 time repeating texture, but handling -X positions becomes a little trickier, so I just used 3 repeats.

Some code fragments
// Make a sprite with the background texture like normal.
// Then set it like this:
tex->setRepeated(true);
sf::Vector2u texSize = tex->getSize();
sprite->setTextureRect(sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(texSize.x * 3, texSize.y)));

// Later in your rendering code do this:
sf::View view = window.getView();
sf::Vector2f pos = view.getCenter() - view.getSize() * 0.5f; // Find top left corner of the view
pos.x = int(pos.x / texSize.x) * int(texSize.x)-int(texSize.x); // Snap the X coord to multiples of width
sprite->setPosition(pos);
window.draw(*sprite);
 

Or if I was doing it for myself, I'd probably do a shader version.

I tried doing as you said and it kinda worked! I guess it takes me one step further to getting this resolved but I can't figure it out yet. I tried as you did making use of pointers but the compiler did not take them so I had to declare normal variables for each thing, after that it kind of did the thing, now it does show the image a bit further but its just like stretching the last few pixels of the image. Though it only does it for what would be another additional repetition of the image, after that is just black again, thanks tho! it got me one step closer to where I want to be.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: How can I make a background repeat infinitely?
« Reply #6 on: February 01, 2023, 05:07:46 pm »
I presume the older code for this that you may have seen is this:
https://en.sfml-dev.org/forums/index.php?topic=14382#msg101088
(or this: https://en.sfml-dev.org/forums/index.php?topic=14382#msg101171)

If you have not seen that one, have a look; it should solve your issue!

If you have seen it, however, it's possible you might have misunderstood how it works...
It does use the repeated texture feature but it doesn't create an "infinitely large rectangle", it uses a rectangle just large enough to cover the background plus some spare to allow scrolling (maximum spare should be the size of the texture once).
It covers scrolling in both directions (x and y) but if you don't scroll in the y direction, it'll work just as well although you could fine-tune the y stuff if you really wanted.

Oh, and it does it all automatically! Just set your view position and it updates around that!  :)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*