Wiki
Clone wikiSpecGine / MainMenu
Adding main menu
Creating state hierarchy
All menus in our game will share resources like GUI. That is why we start from creating StateGroup.
Creating state group
We create empty state group in file core/src/main/scala/Menus.scala
.
#!scala package com.specdevs.ping import com.specdevs.specgine.core.StateGroup class Menus extends StateGroup { def initialize() {} def create() {} def dispose() {} }
initialize
method in Ping
class from core/src/main/scala/Ping.scala
,
so it looks like:
#!scala def initialize() { addGroup(new Menus, "Menus") }
This will register our group under name "Menus"
.
Main Menu state
Next we add an empty state representing main menu. We subclass MenuState
in file core/src/main/scala/MainMenu.scala
.
#!scala package com.specdevs.ping import com.specdevs.specgine.states.MenuState class MainMenu extends MenuState { def initialize() {} def create() {} def dispose() {} }
initialize
method in game class.
#!scala def initialize() { addGroup(new Menus, "Menus") addState(new MainMenu, "MainMenu", "Menus") }
Now we have one state called "MainMenu"
in state group "Menus"
.
Shared resources
The first resource we will add to "Menus"
group will be bitmap font. We will use default font that comes from Libgdx.
This font is in file com/badlogic/gdx/utils/arial-15.fnt
. We will apply linear texture filtering.
We add its name to Menus
class and request loading of asset in its initialize
method.
#!scala //... import com.specdevs.specgine.assets.gdx.BitmapFontDescriptor import com.badlogic.gdx.graphics.Texture.TextureFilter.{Linear=>GdxLinear} class Menus extends StateGroup { private val font = "com/badlogic/gdx/utils/arial-15.fnt" def initialize() { loadAsset(font, BitmapFontDescriptor(minFilter=Linear, magFilter=GdxLinear)) } //... }
create
method resources will be already loaded so we can use it to create default skin for the menus.
Menu skin below is based on UISimpleTest from Libgdx.
#!scala import com.specdevs.specgine.assets.Asset import com.specdevs.specgine.assets.gdx.{ImplicitBitmapFontAsset,ImplicitSkinAsset} import com.badlogic.gdx.graphics.{Pixmap=>GdxPixmap,Texture=>GdxTexture,Color=>GdxColor} import com.badlogic.gdx.graphics.Pixmap.{Format=>GdxPFormat} import com.badlogic.gdx.graphics.g2d.{BitmapFont=>GdxBitmapFont} import com.badlogic.gdx.scenes.scene2d.ui.{Skin=>GdxSkin} import com.badlogic.gdx.scenes.scene2d.ui.TextButton.{TextButtonStyle=>GdxTextButtonStyle} //... def create() { val skin = new GdxSkin val pixmap = new GdxPixmap(1, 1, GdxPFormat.RGBA8888) pixmap.setColor(GdxColor.WHITE) pixmap.fill() skin.add("white", new GdxTexture(pixmap)) skin.add("default", get[Asset,GdxBitmapFont](font)) val textButtonStyle = new GdxTextButtonStyle textButtonStyle.up = skin.newDrawable("white", GdxColor.DARK_GRAY) textButtonStyle.down = skin.newDrawable("white", GdxColor.DARK_GRAY) textButtonStyle.over = skin.newDrawable("white", GdxColor.LIGHT_GRAY) textButtonStyle.font = skin.getFont("default") skin.add("default", textButtonStyle) set[Asset,GdxSkin]("defaultSkin", skin) }
ImplicitBitmapFontAsset
and ImplicitSkinAsset
to use get
and set
methods. We also need all Libgdx related stuff
used to assemble skin. Ready resource is stored with name "defaultSkin"
. To read more about creating menus we invite you to read Libgdx
documentation about Skin.
Note: We plan to add Scala DSL for GUIs in near future, but currently you are left with Libgdx features alone.
This allows us to use stored resources in all menu states in "Menus"
group.
Implementing main menu
It remains to implement main menu itself. It will have one MenuScreen.
Creating empty menu screen
We create empty default screen in file core/src/main/scala/MainScreen.scala
.
#!scala package com.specdevs.ping import com.specdevs.specgine.states.gdx.MenuScreen class MainScreen extends MenuScreen { def initialize() {} def create() {} def dispose() {} }
MainMenu
state by registering screen inside MainMenu
's initialize
method.
#!scala def initialize() { addMenuScreen("Main", new MainScreen) }
desktop/run
from SBT.
Setting screen size
Now we can see and set screen size. For our game we selected 800 x 480 as base size, which matches default set in project template.
We still need to inform our menu system about resolution, so bitmap fonts are properly scaled.Open file core/src/main/scala/MainScreen.scala
and set width and height in constructor.
#!scala //... class MainScreen extends MenuScreen(width=Some(800), height=Some(480)) { //... }
Menu buttons
We will create two buttons in our menu. "New Game" will currently do nothing and "Quit" which will exit the game.
We place our code in create
method of MainScreen
class.
#!scala //... import com.specdevs.specgine.assets.Asset import com.specdevs.specgine.assets.gdx.ImplicitSkinAsset import com.badlogic.gdx.scenes.scene2d.{Actor=>GdxActor} import com.badlogic.gdx.scenes.scene2d.ui.{Skin=>GdxSkin,TextButton=>GdxTextButton} import com.badlogic.gdx.scenes.scene2d.utils.{ChangeListener=>GdxChangeListener} import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener.{ChangeEvent=>GdxChangeEvent} //... def create() { val skin = get[Asset,GdxSkin]("defaultSkin") val button1 = new GdxTextButton("New game", skin) table.add(button1).width(120).pad(10) table.row() val button2 = new GdxTextButton("Quit", skin) table.add(button2).width(120).pad(10) button2.addListener(new GdxChangeListener { def changed(event: GdxChangeEvent, actor: GdxActor) { quit() } }) () } //...
"Menus"
group. Next we add two buttons using standard Libgdx features.
The first button is without callback, but the second one issues quit
method that closes application. For more features of Libgdx widgets we
recommend you to check scene2d.ui documentation on Libgdx page.
Note: We plan to add Scala DSL for GUIs in near future, but currently you are left with Libgdx features alone.
Now you should have fully working main menu. In next step we will add intro to our game.
Having troubles with this step?
Here you can download project with all above steps completed.
Updated