After creating our splash screen using scene2D, it's time to also create a simple menu with a play button. After that, we will finally start creating our game world! First, start by downloading the background image of our tutorial. I have to remind you that every graphic i am creating is for the purpose of these tutorials and only.
Menu background |
Now you will have to download a simple button and pack it.
Note;; To download the images at the original resolution you must first click on the image you want to download and then download it.
Texture packer
After you are done you will have to pack those buttons into one image. It's not necessary to do it for 2 images only (we pack graphics to save space) but it's a nice opportunity to learn how to do it. Download the libGDX texture packer executable (you can find different versions if that doesn't suit you, but don't worry, the result is the same). You just have to create a file and place inside the two buttons (don't forget to name them " playNorm " and " playPushed "), then create a new pack with the name " mainManuPack ", choose the file you have just created as an input file and finally choose an output folder and pack them. It is essential to choose linear filters. Here is an image of the options you must select;Texture packer options |
If you have done everything correctly, the result should be 2 files, the first one with the name " mainMenuPack.png " and the second one with the name " mainMenuPack.atlas ". If you are using a different texture packer then the second file sometimes is named " mainMenuPack.pack ".
In the assets folder of our project create a folder with name " skins " and inside copy and paste those 2 files.
LibGDX main menu screen using scene2D
Now to the code. Inside the " screens " package where we previously created our splash screen, create a java class with the name " MainMenuScreen " and implement gdx Screens. In the show method, place this code;@Override
public void show() {
WIDTH = 1280;
HEIGHT = 720;
mainmenuTexture = new Texture("mainMenu/mainMenu.png");
mainmenuTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
mainmenuImage = new Image(mainmenuTexture);
mainmenuImage.setSize(1280,720);
mainmenuStage = new Stage(new FitViewport(WIDTH,HEIGHT, new AndroidCamera(WIDTH,HEIGHT)));
mainmenuTablePlay = new Table();
mainmenuSkinPlay = new Skin(Gdx.files.internal("skins/play.json"), new TextureAtlas(Gdx.files.internal("skins/mainMenuPack.atlas")));
mainmenuimagebuttonPlay = new ImageButton(mainmenuSkinPlay);
mainmenuTablePlay.bottom().add(mainmenuimagebuttonPlay).size( 152F, 164F).padBottom(20F);
mainmenuStage.addActor(mainmenuImage);
mainmenuStage.addActor(mainmenuTablePlay);
Gdx.input.setInputProcessor(mainmenuStage);
mainmenuTablePlay.addAction(Actions.sequence(Actions.moveBy(0.0F, -250F), Actions.delay(1.0F), Actions.moveBy(0.0F, 250F, 1.0F, Interpolation.swing)));
mainmenuImage.addAction(Actions.sequence(Actions.alpha(0.0F), Actions.fadeIn(1.0F)));
mainmenuimagebuttonPlay.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
((Game)Gdx.app.getApplicationListener()).setScreen(new SplashScreen());
}
});
}
In the first lines we did exactly the same as in the creation of our splash screen. Created a texture which we filtered, created an image from this texture to be the actor in our stage, which has a FitViewport and our camera with a virtual resolution of 1280 x 720. We don't care for the black bars, because our background has black colour itself. Don't forget to create a folder with the name " mainMenu " in the assets file of our project, to rename the background image you downloaded and to place it inside this folder.
Then we create a table in which we will place our button. This table with our button inside will be the second actor in our stage. To create an image button we first have to create a skin and to create a skin we need a .json file and a texture atlas. We have already placed the " mainMenuPack.atlas " file in our skins folder inside the assets and this file will act as the texture atlas. Now we must create a .json file. To do so, create a " play.txt " file, put the code below and save it as " play.json ". Then place this " play.json " file inside the skins folder.
Then we create a table in which we will place our button. This table with our button inside will be the second actor in our stage. To create an image button we first have to create a skin and to create a skin we need a .json file and a texture atlas. We have already placed the " mainMenuPack.atlas " file in our skins folder inside the assets and this file will act as the texture atlas. Now we must create a .json file. To do so, create a " play.txt " file, put the code below and save it as " play.json ". Then place this " play.json " file inside the skins folder.
{
"com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle": {
"default": {
"up": "playNorm",
"down": "playPushed",
"unpressedOffsetY":-10,
}
}
}
From this skin we create our image button, and upon clicking this button we will have a simple click animation, defined by the .json file and our texture atlas.
We add the button to our table and then we align the table to be at the bottom of our screen, we define it's size and we pad it a little bit from bottom. Then we add the table and the background to our stage to be our actors.
" What else can we do? "
The final touch is to add actions to our actors. In this case we added a simple fade in animation for our background and a simple animation for our button. I used exactly these for Black Dodger too. But there is something more missing. In order to be able to interact with our stage, like clicking the buttons inside, we have to set an input processor to our stage and to add a click listener to our button. This way, when clicking the button we can define an action. So for now, when clicking the play button we will go back to the splash screen.
The whole class will be like this;
package com.getest.game.screens;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.getest.game.camera.AndroidCamera;
public class MainMenuScreen implements Screen {
private Stage mainmenuStage;
private Skin mainmenuSkinPlay;
private ImageButton mainmenuimagebuttonPlay;
private Table mainmenuTablePlay;
private Texture mainmenuTexture;
private Image mainmenuImage;
private float WIDTH,HEIGHT;
public MainMenuScreen() {
}
@Override
public void show() {
WIDTH = 1280;
HEIGHT = 720;
mainmenuTexture = new Texture("mainMenu/mainMenu.png");
mainmenuTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
mainmenuImage = new Image(mainmenuTexture);
mainmenuImage.setSize(1280,720);
mainmenuStage = new Stage(new FitViewport(WIDTH,HEIGHT, new AndroidCamera(WIDTH,HEIGHT)));
mainmenuTablePlay = new Table();
mainmenuSkinPlay = new Skin(Gdx.files.internal("skins/play.json"), new TextureAtlas(Gdx.files.internal("skins/mainMenuPack.atlas")));
mainmenuimagebuttonPlay = new ImageButton(mainmenuSkinPlay);
mainmenuTablePlay.bottom().add(mainmenuimagebuttonPlay).size( 152F, 164F).padBottom(20F);
mainmenuStage.addActor(mainmenuImage);
mainmenuStage.addActor(mainmenuTablePlay);
Gdx.input.setInputProcessor(mainmenuStage);
mainmenuTablePlay.addAction(Actions.sequence(Actions.moveBy(0.0F, -250F), Actions.delay(1.0F), Actions.moveBy(0.0F, 250F, 1.0F, Interpolation.swing)));
mainmenuImage.addAction(Actions.sequence(Actions.alpha(0.0F), Actions.fadeIn(1.0F)));
mainmenuimagebuttonPlay.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
((Game)Gdx.app.getApplicationListener()).setScreen(new SplashScreen());
}
});
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mainmenuStage.act();
mainmenuStage.draw();
}
@Override
public void resize(int width, int height) {
mainmenuStage.getViewport().update(width,height,true);
mainmenuTablePlay.invalidateHierarchy();
mainmenuTablePlay.setSize(WIDTH, HEIGHT);
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
dispose(); }
@Override
public void dispose() {
mainmenuStage.dispose();
mainmenuTexture.dispose();
mainmenuSkinPlay.dispose();
}
}
In our render, hide and dispose methods we did exactly the same as we did while creating our splash screen. But here, we also wrote some more code inside the resize method. We always have to inform our viewport when a resize event occurs. You will understand the next 2 lines of code in the upcoming tutorials.
splashimage.addAction(Actions.sequence(Actions.alpha(0.0F), Actions.fadeIn(1.25F),Actions.delay(1F), Actions.fadeOut(0.75F)));
with this one;
splashimage.addAction(Actions.sequence(Actions.alpha(0.0F), Actions.fadeIn(1.25F),Actions.delay(1F), Actions.fadeOut(0.75F), Actions.run(new Runnable() {
@Override
public void run() {
((Game)Gdx.app.getApplicationListener()).setScreen(new MainMenuScreen());
}
})));
Now, after the fade out of the splash screen our main menu screen will be called. Run the game and you will get the final result, a fully responsive and cool splash and main menu screen.
This is it for today's tutorial, feel free to ask any questions in the comments below!
Comments
Post a Comment