2015-01-01 19:36:52 +03:00
|
|
|
---
|
|
|
|
title: HUD
|
|
|
|
layout: default
|
2018-07-15 21:36:35 +03:00
|
|
|
root: ../..
|
2018-07-15 17:28:10 +03:00
|
|
|
idx: 4.6
|
2020-07-08 12:37:19 +03:00
|
|
|
description: Learn how to display HUD elements
|
2018-07-15 21:13:16 +03:00
|
|
|
redirect_from: /en/chapters/hud.html
|
2015-01-01 19:36:52 +03:00
|
|
|
---
|
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
## Introduction <!-- omit in toc -->
|
2015-01-01 19:36:52 +03:00
|
|
|
|
|
|
|
Heads Up Display (HUD) elements allow you to show text, images, and other graphical elements.
|
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
The HUD doesn't accept user input; for that, you should use a [formspec](formspecs.html).
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Positioning](#positioning)
|
2020-12-24 16:38:26 +03:00
|
|
|
- [Position and Offset](#position-and-offset)
|
|
|
|
- [Alignment](#alignment)
|
|
|
|
- [Scoreboard](#scoreboard)
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Text Elements](#text-elements)
|
2020-12-24 16:38:26 +03:00
|
|
|
- [Parameters](#parameters)
|
|
|
|
- [Our Example](#our-example)
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Image Elements](#image-elements)
|
2020-12-24 16:38:26 +03:00
|
|
|
- [Parameters](#parameters-1)
|
|
|
|
- [Scale](#scale)
|
2019-05-31 20:32:40 +03:00
|
|
|
- [Changing an Element](#changing-an-element)
|
|
|
|
- [Storing IDs](#storing-ids)
|
|
|
|
- [Other Elements](#other-elements)
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
## Positioning
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
### Position and Offset
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
<figure class="right_image">
|
|
|
|
<img
|
|
|
|
width="300"
|
2018-07-15 21:36:35 +03:00
|
|
|
src="{{ page.root }}//static/hud_diagram_center.svg"
|
2017-12-17 19:01:29 +03:00
|
|
|
alt="Diagram showing a centered text element">
|
|
|
|
</figure>
|
|
|
|
|
|
|
|
Screens come in a variety of different physical sizes and resolutions, and
|
|
|
|
the HUD needs to work well on all screen types.
|
|
|
|
|
|
|
|
Minetest's solution to this is to specify the location of an element using both
|
|
|
|
a percentage position and an offset.
|
|
|
|
The percentage position is relative to the screen size, so to place an element
|
2018-10-27 05:10:37 +03:00
|
|
|
in the centre of the screen, you would need to provide a percentage position of half
|
|
|
|
the screen, e.g. (50%, 50%), and an offset of (0, 0).
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
The offset is then used to move an element relative to the percentage position.
|
|
|
|
|
|
|
|
<div style="clear:both;"></div>
|
|
|
|
|
|
|
|
### Alignment
|
|
|
|
|
|
|
|
Alignment is where the result of position and offset is on the element -
|
|
|
|
for example, `{x = -1.0, y = 0.0}` will make the result of position and offset point
|
|
|
|
to the left of the element's bounds. This is particularly useful when you want to
|
2018-10-27 05:10:37 +03:00
|
|
|
make a text element aligned to the left, centre, or right.
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
<figure>
|
|
|
|
<img
|
|
|
|
width="500"
|
2018-07-15 21:36:35 +03:00
|
|
|
src="{{ page.root }}//static/hud_diagram_alignment.svg"
|
2017-12-17 19:01:29 +03:00
|
|
|
alt="Diagram showing alignment">
|
|
|
|
</figure>
|
|
|
|
|
|
|
|
The above diagram shows 3 windows (blue), each with a single HUD element (yellow)
|
2018-10-27 05:10:37 +03:00
|
|
|
and a different alignment each time. The arrow is the result of the position
|
2017-12-17 19:01:29 +03:00
|
|
|
and offset calculation.
|
|
|
|
|
|
|
|
### Scoreboard
|
|
|
|
|
|
|
|
For the purposes of this chapter, you will learn how to position and update a
|
|
|
|
score panel like so:
|
|
|
|
|
|
|
|
<figure>
|
|
|
|
<img
|
2018-07-15 21:36:35 +03:00
|
|
|
src="{{ page.root }}//static/hud_final.png"
|
2017-12-17 19:01:29 +03:00
|
|
|
alt="screenshot of the HUD we're aiming for">
|
|
|
|
</figure>
|
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
In the above screenshot, all the elements have the same percentage position
|
2017-12-17 19:01:29 +03:00
|
|
|
(100%, 50%) - but different offsets. This allows the whole thing to be anchored
|
|
|
|
to the right of the window, but to resize without breaking.
|
|
|
|
|
|
|
|
## Text Elements
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-07-16 01:04:55 +03:00
|
|
|
You can create a HUD element once you have a copy of the player object:
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2017-12-17 19:01:29 +03:00
|
|
|
local player = minetest.get_player_by_name("username")
|
2015-01-01 19:36:52 +03:00
|
|
|
local idx = player:hud_add({
|
2017-12-17 19:01:29 +03:00
|
|
|
hud_elem_type = "text",
|
|
|
|
position = {x = 0.5, y = 0.5},
|
|
|
|
offset = {x = 0, y = 0},
|
|
|
|
text = "Hello world!",
|
|
|
|
alignment = {x = 0, y = 0}, -- center aligned
|
|
|
|
scale = {x = 100, y = 100}, -- covered later
|
2015-01-01 19:36:52 +03:00
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
The `hud_add` function returns an element ID - this can be used later to modify
|
|
|
|
or remove a HUD element.
|
|
|
|
|
|
|
|
### Parameters
|
|
|
|
|
|
|
|
The element's type is given using the `hud_elem_type` property in the definition
|
|
|
|
table. The meaning of other properties varies based on this type.
|
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
`scale` is the maximum bounds of text; text outside these bounds is cropped, e.g.: `{x=100, y=100}`.
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
`number` is the text's colour, and is in [hexadecimal form](http://www.colorpicker.com/), e.g.: `0xFF0000`.
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
|
|
|
|
### Our Example
|
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
Let's go ahead and place all the text in our score panel:
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2018-10-27 05:10:37 +03:00
|
|
|
-- Get the dig and place count from storage, or default to 0
|
|
|
|
local meta = player:get_meta()
|
|
|
|
local digs_text = "Digs: " .. meta:get_int("score:digs")
|
|
|
|
local places_text = "Places: " .. meta:get_int("score:places")
|
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "text",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -120, y = -25},
|
|
|
|
text = "Stats",
|
|
|
|
alignment = 0,
|
|
|
|
scale = { x = 100, y = 30},
|
|
|
|
number = 0xFFFFFF,
|
|
|
|
})
|
|
|
|
|
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "text",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -180, y = 0},
|
|
|
|
text = digs_text,
|
|
|
|
alignment = -1,
|
|
|
|
scale = { x = 50, y = 10},
|
|
|
|
number = 0xFFFFFF,
|
|
|
|
})
|
|
|
|
|
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "text",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -70, y = 0},
|
|
|
|
text = places_text,
|
|
|
|
alignment = -1,
|
|
|
|
scale = { x = 50, y = 10},
|
|
|
|
number = 0xFFFFFF,
|
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
This results in the following:
|
|
|
|
|
|
|
|
<figure>
|
|
|
|
<img
|
2018-07-15 21:36:35 +03:00
|
|
|
src="{{ page.root }}//static/hud_text.png"
|
2017-12-17 19:01:29 +03:00
|
|
|
alt="screenshot of the HUD we're aiming for">
|
|
|
|
</figure>
|
|
|
|
|
|
|
|
|
|
|
|
## Image Elements
|
|
|
|
|
|
|
|
Image elements are created in a very similar way to text elements:
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2017-12-17 19:01:29 +03:00
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "image",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -220, y = 0},
|
2018-09-24 19:16:00 +03:00
|
|
|
text = "score_background.png",
|
2017-12-17 19:01:29 +03:00
|
|
|
scale = { x = 1, y = 1},
|
|
|
|
alignment = { x = 1, y = 0 },
|
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
You will now have this:
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
<figure>
|
|
|
|
<img
|
2018-07-15 21:36:35 +03:00
|
|
|
src="{{ page.root }}//static/hud_background_img.png"
|
2017-12-17 19:01:29 +03:00
|
|
|
alt="screenshot of the HUD so far">
|
|
|
|
</figure>
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
### Parameters
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
The `text` field is used to provide the image name.
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
If a co-ordinate is positive, then it is a scale factor with 1 being the
|
2018-10-27 05:10:37 +03:00
|
|
|
original image size, 2 being double the size, and so on.
|
2019-05-31 20:32:40 +03:00
|
|
|
However, if a co-ordinate is negative, it is a percentage of the screen size.
|
2017-12-17 19:01:29 +03:00
|
|
|
For example, `x=-100` is 100% of the width.
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
### Scale
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
Let's make the progress bar for our score panel as an example of scale:
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2018-10-27 05:10:37 +03:00
|
|
|
local percent = tonumber(meta:get("score:score") or 0.2)
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "image",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -215, y = 23},
|
2018-09-24 19:16:00 +03:00
|
|
|
text = "score_bar_empty.png",
|
2017-12-17 19:01:29 +03:00
|
|
|
scale = { x = 1, y = 1},
|
|
|
|
alignment = { x = 1, y = 0 },
|
|
|
|
})
|
|
|
|
|
|
|
|
player:hud_add({
|
|
|
|
hud_elem_type = "image",
|
|
|
|
position = {x = 1, y = 0.5},
|
|
|
|
offset = {x = -215, y = 23},
|
2018-09-24 19:16:00 +03:00
|
|
|
text = "score_bar_full.png",
|
2017-12-17 19:01:29 +03:00
|
|
|
scale = { x = percent, y = 1},
|
|
|
|
alignment = { x = 1, y = 0 },
|
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2017-12-17 19:01:29 +03:00
|
|
|
|
2018-07-16 01:04:55 +03:00
|
|
|
We now have a HUD that looks like the one in the first post!
|
|
|
|
There is one problem however, it won't update when the stats change.
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
## Changing an Element
|
|
|
|
|
2020-07-08 12:37:19 +03:00
|
|
|
You can use the ID returned by the `hud_add` method to update it or remove it later.
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-01-01 19:36:52 +03:00
|
|
|
local idx = player:hud_add({
|
2017-12-17 19:01:29 +03:00
|
|
|
hud_elem_type = "text",
|
|
|
|
text = "Hello world!",
|
|
|
|
-- parameters removed for brevity
|
2015-01-01 19:36:52 +03:00
|
|
|
})
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
player:hud_change(idx, "text", "New Text")
|
|
|
|
player:hud_remove(idx)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
The `hud_change` method takes the element ID, the property to change, and the new
|
2020-07-08 12:37:19 +03:00
|
|
|
value. The above call changes the `text` property from "Hello World" to "New text".
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
This means that doing the `hud_change` immediately after the `hud_add` is
|
|
|
|
functionally equivalent to the following, in a rather inefficient way:
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-01-01 19:36:52 +03:00
|
|
|
local idx = player:hud_add({
|
2017-12-17 19:01:29 +03:00
|
|
|
hud_elem_type = "text",
|
|
|
|
text = "New Text",
|
2015-01-01 19:36:52 +03:00
|
|
|
})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
## Storing IDs
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2018-09-24 19:16:00 +03:00
|
|
|
score = {}
|
2017-12-17 19:01:29 +03:00
|
|
|
local saved_huds = {}
|
|
|
|
|
2018-09-24 19:16:00 +03:00
|
|
|
function score.update_hud(player)
|
2017-12-17 19:01:29 +03:00
|
|
|
local player_name = player:get_player_name()
|
|
|
|
|
2018-10-27 05:10:37 +03:00
|
|
|
-- Get the dig and place count from storage, or default to 0
|
|
|
|
local meta = player:get_meta()
|
|
|
|
local digs_text = "Digs: " .. meta:get_int("score:digs")
|
|
|
|
local places_text = "Places: " .. meta:get_int("score:places")
|
|
|
|
local percent = tonumber(meta:get("score:score") or 0.2)
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2017-12-17 19:01:29 +03:00
|
|
|
local ids = saved_huds[player_name]
|
|
|
|
if ids then
|
|
|
|
player:hud_change(ids["places"], "text", places_text)
|
|
|
|
player:hud_change(ids["digs"], "text", digs_text)
|
|
|
|
player:hud_change(ids["bar_foreground"],
|
|
|
|
"scale", { x = percent, y = 1 })
|
|
|
|
else
|
|
|
|
ids = {}
|
|
|
|
saved_huds[player_name] = ids
|
|
|
|
|
|
|
|
-- create HUD elements and set ids into `ids`
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-24 19:16:00 +03:00
|
|
|
minetest.register_on_joinplayer(score.update_hud)
|
2017-12-17 19:01:29 +03:00
|
|
|
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
|
|
saved_huds[player:get_player_name()] = nil
|
|
|
|
end)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-01-01 19:36:52 +03:00
|
|
|
|
|
|
|
|
2015-02-22 13:28:37 +03:00
|
|
|
## Other Elements
|
2015-01-01 19:36:52 +03:00
|
|
|
|
2020-12-24 16:38:26 +03:00
|
|
|
Read [lua_api.txt](https://minetest.gitlab.io/minetest/hud/) for a complete list of HUD elements.
|