Ir para conteúdo

murilohaf_

Membros
  • Total de itens

    1
  • Registro em

  • Última visita

Sobre murilohaf_

Informações pessoais

  • Sexo
    Masculino
  1. Bom dia, boa tarde ou boa noite, dependendo da hora em que estiver lendo isso. Já faz um tempo que eu não acessava esse fórum e nem observava nada relacionado a desenvolvimento de plugins para servidores de Minecraft. Confesso que até fiquei surpreso pela quantidade de novas pessoas com interesse nessa área de desenvolvimento de plugins. Cresceu bastante. Enfim, deixando um pouco essa questão de lado, gostaria de deixar uma pequena contribuição: uma sistema que permita criar menus de maneira bastante simples. 1ª parte - Modelando a classe Button A classe button corresponderá aos botões disponíveis no menu. A sua modelagem é extremamente simples, mas ela facilitará muito o desenvolvimento de menus interativos. Essa classe contará com apenas uma variável, chamada de icon, que será do tipo ItemStack, duas funções controladoras para essa variável e uma outra função do tipo void chamada "onButtonClick" que será sempre chamada quando o botão for acionado. Optei por implementar dois construtores nessa classe, um sem parâmetros, e outro passando o parâmetro icon. Portanto, ficamos com a seguinte classe: public class Button { private ItemStack icon; public Button() {} public Button(ItemStack icon) { this.icon = icon; } public ItemStack getIcon() { return icon; } public void setIcon(ItemStack icon) { this.icon = icon; } public void onButtonClick(InventoryClickEvent event) { } } 2ª parte - Modelando a classe Menu Para iniciarmos o desenvolvimento desse sistema, primeiramente vamos criar uma classe, chamaremos ela, por motivos óbvios de Menu. Essa classe contará com 3 variáveis, as quais chamareis de "inventory", "cancelClick" e "buttons". Essas variáveis são dos seguintes tipo, respectivamente: Inventory, boolean, Map<Integer, Button> —. Além do mais, essa nossa classe, Menu, implementará duas interfaces, a interface InventoryHolder e a Listener. Feito isso, vamos partir ao construtor da classe. Optei por um construtor que solicite 2 valores, slots (int), title (String) e cancelClick (boolean). Sendo assim, o código da classe até o presente momento fica assim. public class Menu implements InventoryHolder, Listener { private Inventory inventory; private boolean cancelClick; private Map<Integer, Button> buttons; public Menu(int slots, String title, boolean cancelClick) { this.inventory = Bukkit.createInventory(this, Math.max(9, slots), title); this.cancelClick = cancelClick; this.buttons = new HashMap<Integer, Button>(); //Aqui você vai registrar essa classe como uma ouviente de eventos "registerEvents" } Optei por suprimir algumas etapas do construtor, mas caso fique alguma dúvida, basta comentar. Enfim, tendo estabelecido isso, vamos implementar algumas funções controladoras na classe e podemos seguir para o tratamento de eventos. A função getInventory, exigida pela interface Inventory, retornará a variável inventory presente na classe. Com isso em mente, e os controladores, ficamos assim: @Override public Inventory getInventory() { return inventory; } public boolean isCancelClick() { return cancelClick; } public void setCancelClick(boolean cancelClick) { this.cancelClick = cancelClick; } Agora, vamos implementar os controladores dos botões do menu. Essas funções de controle deverão tanto se relacionar com a variável inventory quanto com o mapa buttons. Cada botão adicionado, deverá ser apresentado no inventário e adicionado no mapa. O mesmo vale para a remoção, portanto, ficamos com as seguintes funções. public void addButton(int slot, Button button) { buttons.put(slot, button); inventory.setItem(slot, button.getIcon()); button.setIcon(inventory.getItem(slot)); } public void removeButton(int slot) { if (buttons.containsKey(slot)) { buttons.remove(slot); inventory.setItem(slot, null); } } A linha "button.setIcon(inventory.getItem(slot));" visa manter o apontamento do ItemStack da classe button para o mesmo apontado do ItemStack apresentado no inventário. Assim, certas alterações de ItemMeta podem ser realizados puxando diretamente o ItemStack da classe Button. Tendo feita essas implementações, vamos tratar os eventos. No caso, trataremos três eventos: InventoryClickEvent, InventoryDragEvent e InventoryMoveItemEvent. Sendo o InventoryClickEvent o principal, pois é nele que a mágica acontece. A primeira linha se dedica a validar se a lista de espectadores do nosso menu apresenta o jogador que disparou a interação. A segunda linha é a implementação do "cancelClick", o restante é a validação se o inventário que fora clicado é de fato o menu — lembre-se que o jogador poderia estar interagindo com seu próprio inventário, mas com o menu aperto — e posteriormente, a chamada da função onClick do botão acionado. @EventHandler(priority = EventPriority.LOWEST) public void onInventoryClick(InventoryClickEvent event) { if (inventory.getViewers().contains(event.getWhoClicked())) { if (cancelClick && (event.isShiftClick() || (event.getClickedInventory() != null && event.getClickedInventory().getName().equals(inventory.getName())))) { event.setCancelled(true); } if (event.getClickedInventory() != null && event.getClickedInventory().getName().equals(inventory.getName())) { if (buttons.containsKey(event.getSlot())) { buttons.get(event.getSlot()).onButtonClick(event); } } } } Segue as outras implementações do cancelClick nos outros dois eventos: @EventHandler(priority = EventPriority.LOWEST) public void onInventoryDrag(InventoryDragEvent event) { if (event.getInventory().getName().equals(inventory.getName()) && inventory.getViewers().contains(event.getWhoClicked())) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.LOWEST) public void onInventoryMoveItems(InventoryMoveItemEvent event) { if (cancelClick && event.getDestination().getName().equals(inventory.getName()) && inventory.getViewers().containsAll(event.getDestination().getViewers())) { event.setCancelled(true); } } Com isso, está encerrado nosso sistema de Menus. Esse sistema é um modelo simplificado do que eu usei no desenvolvimento dos menus do antigo Planeta Minecraft (https://www.youtube.com/watch?v=m5OxpGFtBuo). Gostaria de dar alguns exemplos de implementação, mas infelizmente, as estruturas utilizadas no planeta eram bastante complexas e interdependentes. De toda maneira, conto com a criatividade de vocês, e espero de alguma forma ter ajudado.
×
×
  • Criar Novo...