Skip to content
Download

Shop with a list of items

You want a shop (or an inventory, or a level select) where the number of items comes from code, without building each row by hand.

  1. Create the Loja interface with a Texto named Moedas.
  2. Add a Painel named Itens and, under Organizar filhos, choose Coluna.
  3. Inside it, build one item: a panel named Modelo with an Imagem Icone, a Texto Nome and a Botão Comprar.
  4. Uncheck Visível on Modelo. It still shows in the tab, so you can edit it, but not in the game.
#include "Loja.hpp"
#include <format>
#include <string>
#include <vector>
using namespace brasa;
struct Item {
std::string nome;
std::string sprite;
int preco;
bool comprado = false;
};
std::vector<Item> itens = {{"Espada", "espada", 10}, {"Escudo", "escudo", 40}};
void Loja::onSpawn() {
Ui::Element loja = Ui::get("Loja");
for (std::size_t n = 0; n < itens.size(); ++n) {
Ui::Element linha = loja["Itens"]["Modelo"].clone(std::format("Item{}", n));
linha["Nome"].setText(itens[n].nome);
linha["Icone"].setSprite(itens[n].sprite);
linha["Comprar"].setText(std::format("{} moedas", itens[n].preco));
linha["Comprar"].onClick(this, [this, n] {
moedas -= itens[n].preco;
itens[n].comprado = true;
mudou = true;
});
}
mudou = true;
}
void Loja::onUpdate() {
if (!mudou) return;
mudou = false;
Ui::Element loja = Ui::get("Loja");
loja["Moedas"].setText(std::format("Moedas: {}", moedas));
for (std::size_t n = 0; n < itens.size(); ++n) {
Ui::Element botao = loja["Itens"][std::format("Item{}", n)]["Comprar"];
if (itens[n].comprado) botao.setText("Comprado");
botao.setEnabled(!itens[n].comprado && moedas >= itens[n].preco);
}
}
  • moedas (an int) and mudou (a bool) are fields of the Loja class, declared in Loja.hpp.
  • clone("Item0") copies Modelo with everything inside it, puts the copy at the end of the Itens panel and makes it visible. Since the panel arranges its children in a column, each copy lands below the previous one.
  • linha["Nome"] looks for the element inside that copy: each item has its own Nome and its own Comprar.
  • setEnabled(false) dims the button and makes it stop responding: the item that is too expensive or already bought.
  • Calling clone again with the same name rebuilds the copy instead of creating another one. That is why restarting the room doesn’t duplicate the list.
  • remove() takes an element out of the interface, and the ones below move up.
  • The shop panel captures the click: buying doesn’t make the character shoot behind it.

The Zumbis template (in Novo projeto) has a complete shop built this way, with money, weapons and ammo.

  • If the items don’t fit in the panel, check Rolar (scroll) in the panel’s Inspector: what goes past the edge is hidden and the mouse wheel scrolls the list.
  • What was bought is lost when the game closes, unless you store it with Save. See Saving data.