Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags
(2 edits)

Graphic update : scrolling background

There remains only 12 days until the end of the libGDX Jam, and I still have A LOT of work to do, mainly on the graphics and the sounds. As the time pass, my code is less and less clean. I do things as they come and don't really take time to go back on my code to optimize or clean it. So this is it. I prefer to warn you, I'll present more and more dirty code ! hahaha.
Yesterday I posted a youtube video showing the graphic updates of Cosmonaut. Maybe we don't see it very well in the video, but through the different windows and holes, we can see stars scrolling in background.


To obtain this effect, I use a 100px x 100px image of stars that I repeat all over the level surface, and I scroll it slowly. The problem with that code is that I draw the background also outside the camera viewport. That's definitely a waste of GPU time, but, as I said, I definitely don't have time to look for a better option.

All the code is added to the GameScreen.java.

In the creator of the GameScreen.java you need to declare a Texture and make it repeatable :

backgroundTexture = new Texture(Gdx.files.internal("Images/Stars.jpg"), true);
backgroundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);

Still in the creator, I calculate the screen dimensions :

levelPixelWidth = Float.parseFloat(tiledMap.getProperties().get("width").toString()) * GameConstants.PPT * GameConstants.MPP;
levelPixelHeight = Float.parseFloat(tiledMap.getProperties().get("height").toString()) * GameConstants.PPT * GameConstants.MPP;

Then in the render() of the GameScreen.java I draw the Texture with the right SpriteBatch method:

game.batch.begin();
    game.batch.draw(backgroundTexture,               //Texture to load
                    0,                               //X position of the Texture
                    0,                               //Y position of the Texture
                    levelPixelWidth,                 //Width of the Texture
                    levelPixelHeight,                //Height of the Texture
                    (int)(backgroundTime * 8),       //X offset of the texture
                    0,                               //Y offset of the texture
                    (int)(levelPixelWidth * 20),     //I have no fucking idea how to rationnalize these 2 factors but
                    (int)(levelPixelHeight * 20),    //the higher value, the smaller the size of a single Background Texture
                    false,                           //Flip horizontal
                    false);                          //Flip vertical
game.batch.end();

You noticed in this method that in the X offset I entered (int)(backgroundTime * 8). backgroundTime is simply a float that I update in the render with this line :

backgroundTime += Gdx.graphics.getDeltaTime();

And that's it ! I now have stars scrolling in background !



Just in case you are interested :

I talked about the bad optimization of my code. With the previous code I draw the background even outside the viewport. Actually, I worked a lot on this issue, I even think too much for such a detail, at such a time of the Jam. I came up with that code, that draws the background with exactly the viewport size. The background also follows the camera position :

Vector3 posBackground = new Vector3(0,0,0);
camera.project(posBackground);

game.batch.begin();      
game.batch.draw(backgroundTexture, 
                -posBackground.x * camera.viewportWidth / Gdx.graphics.getWidth(),      //Follows the camera
                -posBackground.y * camera.viewportHeight / Gdx.graphics.getHeight(),    //Follows the camera
                camera.viewportWidth,                                                   //Camera viewport width
                camera.viewportHeight,                                                  //Camera viewport height
                (int)(backgroundTime * 8), 
                0, 
                (int)(levelPixelWidth * 10), 
                (int)(levelPixelHeight * 10), 
                false, 
                false);
game.batch.end();

Here is the result

This is okay for the optimization, but not for the rendering. Once I draw the tiles over this background, it's very weird as the tiles "slide" over the background, when we look through windows, we have the feeling that the stars scroll very fast. To compensate, I have to take the camera speed into account in the Offset argument of the draw method, but I don't know how yet.