In this post we will concentrate on different screens which are a part of a game like menus, scoreboard and gameplay. We would take our game Polar as a reference.
Before going into the screens we would make a folder called assets in Android Project. Here is the screenshot of the folder structure of the project.
Now in assets we can put all the files we want to load in our game. It is better to keep it organized so we make folders for textures, fonts, sounds, data files.
So in Assets/Textures we would put our textures.
Now back to the screens. We have these menus in our game:
- Main Menu
- High Score Mode
- Level Mode
- Options
- Instructions
- Score
All the different screens in the game extend a base abstract class Screen. This helps in maintaining a similar structure across all the pages.
Screen.java
[sourcecode language=”java”]
public abstract class Screen {
<pre>public int ScreenType; //Stores the type of screen like MainMenu,OptionMenu, GameplayScreen
public int IsDone; //Tells whether the screen is ready to be destroyed
public Application App; //Stores reference of the Application
public abstract void update (Application app);
public abstract void render (Application app);
public abstract void dispose ();
public abstract void OnPause(); //Useful for Android code to do processing when the game loses focus
public abstract void OnResume(); //Useful for Android code to do processing when the game regains focus
}
[/sourcecode]
We just extend the Screen class to get the different screen types we specify for our game like MainMenu, Instruction, Option etc.
We will take example of MainMenu.
In the constructor we call the Initialize function which is used to load the textures and setting up positions of objects.
Texture Packer:
Before we go further we would like to mention the tool Texture Packer available in libgdx project page. It is a tool using which we pack different textures in one single big file called TextureAtlas which can be used to draw parts of it for particular sprites. It is more efficient to load one texture and use parts of it while rendering different sprites in the scene.
For our project we made two TextureAtlases, one containing textures for the menu and another containing textures for the game objects.
For Textures we created a class called Assets which stores textures in static variables. Here is a code snippet.
Assets.java
[sourcecode language=”java”]
<pre>public class Assets{
static String TexturePath="Textures/";
public static TextureRegion StartButtonTexture;
private static TextureAtlas _menuScreenTextureAtlas;
// And so on
public static void Load(){
//Load textures , font, positions
String textureFile = TexturePath+"pack" ;
_menuScreenTextureAtlas = new TextureAtlas(Gdx.files.internal(textureFile), Gdx.files.internal(textureDir));
StartButtonTexture=_menuScreenTextureAtlas.findRegion("RegionName");
}
}
[/sourcecode]
TexturePath holds the path from where we load the textures. In our case it is Assets/Textures. As assets is the starting directory for libgdx we specify path as “Textures/” and name of the texture Pack generated after using Texture Packer is “pack”. TextureAtlas Constructor needs FileHandle of “pack” file and the FileHandle of the directory in which it is stored. Gdx.files.internal(String path) returns a file handle to the path specified in its argument (we are using Gdx.files.internal because our file is stored in assets folder)
TextureAtlas stores the texture. We use TextureRegion to specify the part of the sprites we require. _menuScreenTextureAtlas.findRegion(String regionName) returns the region of the name specified in regionName. When TexturePacker is run on a group of textures their filename becomes the regionName in the “pack” file. So to access the particular texture we just give that file name in the findRegion argument and we get that texture in the TextureRegion. This way we loaded the buttons required for the MainMenu
Now For Drawing Buttons we made two classes Button and TextureWrapper.
TextureWrapper.java
[sourcecode language=”java”]
<pre>public class TextureWrapper{
public Texture texture;
public Vector2 Position;
int srcX;
int srcY;
int srcWidth;
int srcHeight;
int destWidth;
int destHeight;
public boolean IsActive;
public TextureWrapper(TextureRegion tex,Vector2 pos,int destinationWidth,int destinationHeight)
{
texture=tex.getTexture();
srcX=tex.getRegionX();
srcY=tex.getRegionY();
srcWidth=tex.getRegionWidth();
srcHeight=tex.getRegionHeight();
destWidth=destinationWidth;
destHeight=destinationHeight;
Position=pos;
IsActive=true;
}
public void SetTexture(TextureRegion region)
{
texture=region.getTexture();
srcX=region.getRegionX();
srcY=region.getRegionY();
srcWidth=region.getRegionWidth();
srcHeight=region.getRegionHeight();
}
public void Draw(SpriteBatch sp)
{
if(IsActive)
{
sp.draw(texture, Position.x-destWidth/2, //Position.x-destWidth/2 gives the center of texture in x axis
Position.y-destHeight/2, //Position.y-destHeight/2 gives center of texture in y axis
destWidth,destHeight,srcX,srcY,
srcWidth,srcHeight,false,false);
}
}
}
[/sourcecode]
SpriteBatch:
Spritebatch is used to render sprites on the screen. It is used to send textures in a batch rather than one by one in the renderer pipeline, as this is more efficient.
Drawing A Texture on Screen:
For rendering Texture we made a wrapper for it. Its constructor requires TextureRegion, the position and the destination width and height. So Texture Region specifies the part of the texture we want to draw and destination width and height is used to scale the image to specified dimensions.
Lets look at how spritebatch draws a texture. There are many overloads provided by spritebatch in libgdx. The one which we are going to use will need the arguments Texture, X Coordinate (left point of the texture), Y Coordinate (top point of the texture), the width of the texture we want to show in the screen, the height of the texture we want to show in the screen, the left position of texture where region would start, the top position of texture where region would start, the width of the region in atlas, the height of the region in atlas, boolean value if we want to flip the texture horizontally and if we want to flip the texture vertically. Flipping may be helpful when the sprite has a specific direction it faces so you can specify flipping for horizontal and vertical directions .
Next Tutorial:
In the next tutorial we would be making Buttons to handle the touch events in the menu screen.
Let us know any of your doubts/suggestions; please put them in the comments section and we would try to answer them.
Thank you for the patience.
Is this Supposed to be the TextureObject Class not the TextureWrapper Class , Or i don’t get it 😀 ?!
It is a typo. Thanks for pointing it out 🙂 . We updated it to TextureWrapper class.
Shouldn’t we better use the draw function with rotation parameter?
Yes, it would be but in the game mentioned we never used texture rotation so that is why we used the draw function without rotation parameter.