Example: Custom Title-Screen
In this example we will make our own title-screen using Visual Novel Maker’s In-Game UI-System!
First we need to open Script Editor and open the folder"Layouts " and then select the script called"Layout_Title " which contains the layout definition for the title-screen.
Next, lets delete the already existing content to make the script completely empty. Then we will add the following JSON:
ui.UIManager.layouts.titleLayout = {
"type": "ui.FreeLayout",
"frame": [0, 0, Graphics.width, Graphics.height],
"items": []
}
If we test-play our game now we will see that our title-screen is just a black screen. That is because we didn’t add any content yet, we only added an empty layout. Lets go through this step by step.
The first line is always like:
ui.UIManager.layouts.<unique_layout_name> = {
It is not necessary for you to completely understand this line, the only important thing you have to know is that you have to select a unique name for the layout. The name shouldn’t contain any space or special characters. The name is needed to connect your layout with other layouts or to show your layout using the Scene Command"Switch To Layout ".
Before we can add any controls we always have to define at least one layout first, the main-layout. In our example it is a Free-Layout which allows us to freely position our controls at exact positions. Our layout has three properties:
type
Defines the type of the layout. In our case it is "ui.FreeLayout". There also other types of layouts available like "ui.GridLayout" or "ui.StackLayout".
frame
Defines the position and size of our layout in pixels. The first two numbers define the position, which is 0,0, the top-left corner of the screen in our case. The next two numbers are the size of the layouts. We are using two special number constants here called "Graphics.width" and "Graphics.height" referring to the current screen size. So our layout takes up the whole screen. We will see below that it is also possible to use percentage values instead of pixel coordinates.
controls
That property contains the UI controls to display. Since we added no controls yet we get a black screen. Lets change that in our next step!
ui.UIManager.layouts.titleLayout = {
"type": "ui.FreeLayout",
"frame": [0, 0, Graphics.width, Graphics.height],
"controls": [
{
"type": "ui.Image",
"image": "bg-generic",
"frame": [0, 0, "100%", "100%"]
}
]
}
If we test-play our game now we will see the default background image "bg-generic" taking up the whole screen.
Lets see next how this works:
We added an item of type "ui.Image" which is, like the name says, just an image. Lets go through the properties:
type
The type of the control. In our case its "ui.Image" to just display an image. But there are lots of other control types available and you can even define your own control-templates but we will see that in another example.
image
The name of the image resource we want to display. The resource must be in Graphics/Pictures folder by default.
frame
The position and size of the image. We put our image at the top-left corner of the screen and for the size we set "100%", "100%" which
scales the image to 100% of the layout-size. In our example, it is equivalent to Graphics.width, Graphics.height. You can play around with it and try out other percentages to see how it looks then. You can even do calculations and mix pixel-values with percentage-values like "100% - 250" for example.
Within our next step we will add five buttons for the following title-screen options:
We will use a stack-layout to order the options from top to bottom.
ui.UIManager.layouts.titleLayout = {
"type": "ui.FreeLayout",
"frame": [0, 0, Graphics.width, Graphics.height],
"controls": [
{
"type": "ui.Image",
"image": "bg-generic",
"frame": [0, 0, "100%", "100%"]
},
{
"type": "ui.StackLayout",
"orientation": "vertical",
"frame": ["35%", "60%", "30%", "30%"]
"controls": [
{
"type": "ui.Button",
"params": { "text": "New Game" },
"resizable": true,
"margin": [0, 0, 0, 10]
},
{
"type": "ui.Button",
"params": { "text": "Load Game" },
"resizable": true,
"margin": [0, 0, 0, 10]
},
{
"type": "ui.Button",
"params": { "text": "Quit" },
"resizable": true,
"margin": [0, 0, 0, 10]
}
]
}
]
}
If we test-play our game now we will see our background with three buttons on it.
After the image we added a new vertical stack-layout. If we take a look at the frame-property we only see percentage values. Like we already saw earlier, you can even use percentage-values for frame-property and also do calculations like "50% - 20". Percentage values allowing you to define position and size without knowing the exact screen or parent layout dimensions.
We also set orientation-property to "vertical" to order our buttons vertically from top to bottom like a stack. We add three button controls for each option. Lets take a closer look to it:
{
"type": "ui.Button",
"params": { "text": "New Game" },
"resizable": true,
"margin": [0, 0, 0, 10]
}
type
We used "ui.Button" to create a button control. Actually, "ui.Button" is a template defined in "Templates" sub-folder in "Template_Button" script. We will handle templates in a later example.
params
Since "ui.Button" is actually a template, we can use "params" to pass data to the template. In our case we are passing only one parameter "text" with the value "New Game" to the template. We don't need to know how the template is handling that data, all we need to know is that text defines the button's text.
resizable
Defines if our button can be automatically resized by the layout if necessary so we don't need to specify frame-propery. We set it to true so we don't need to worry about the button's size.
margin
The margin-property defines an empty space around the button. It can be use to define gaps between controls or if you just want to adjust a control a bit. The margin values are in pixels and defined as [<left>, <top>, <right>, <bottom>]. So in our example we are using 10px bottom-margin for each button.
Lets finish this example by adding actions to our button. An action describes a piece of background-logic to execute if the button is clicked.
ui.UIManager.layouts.titleLayout = {
"type": "ui.FreeLayout",
"frame": [0, 0, Graphics.width, Graphics.height],
"controls": [
{
"type": "ui.Image",
"image": "bg-generic",
"frame": [0, 0, "100%", "100%"]
},
{
"type": "ui.StackLayout",
"orientation": "vertical",
"frame": ["35%", "60%", "30%", "30%"]
"controls": [
{
"type": "ui.Button",
"params": { "text": "New Game", "action": { "name": "newGame" } },
"resizable": true,
"margin": [0, 0, 0, 10]
},
{
"type": "ui.Button",
"params": { "text": "Load Game", "action": { "name": "switchLayout", "params": { "name": "loadMenuLayout", "savePrevious": true } } },
"resizable": true,
"margin": [0, 0, 0, 10]
},
{
"type": "ui.Button",
"params": { "text": "Quit", "action": { "name": "quitGame" } },
"resizable": true,
"margin": [0, 0, 0, 10]
}
]
}
]
}
For each button we just pass a new parameter to the buttom-template called "action". An action has a unique name and optionally a set of parameters itself. Lets take a look at the action of our first button:
"action": { "name": "newGame" }
With that we define that the action "newGame" should be executed if the button is clicked. That action, like the name says, starts a new game. So if we click on our "New Game" button a new game will start.
Lets take a look at our third button "Quit" next:
"action": { "name": "quitGame" }
Its similar, we are just executing a different action "quitGame" this time which quits the game.
The second action for our "Load Game" button looks a little bit more complex at first but it is actually the same like before:
"action": { "name": "switchLayout", "params": { "name": "loadMenuLayout", "savePrevious": true } }
Here we are executing the action "switchLayout" which switches to another layout specified in the "params" property. So the difference between our two actions from before is that we have to specify some data passed to the action. The "switchLayout" expects the following parameters:
name
The name of the layout we want to switch to. In our case "loadMenuLayout" which is the unique name used for the load-menu's layout-definition. You can see that in "Layout_LoadMenu".
savePrevious
This parameter is optional, the default is false. But if set to true the previous scene, which is the title-screen in our case, is not completely erased but just
paused and hidden. We can return to it using "returnToPrevious" action. But that is not covered by this example, we just have to set it to true to so that the load-menu can return to the title-screen if we click on the back-button.
Now our own title-screen is finished!