Domine o Godot UI: personalizando interfaces com nós de controle | Thomas Yanuziello | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Domine o Godot UI: personalizando interfaces com nós de controle

teacher avatar Thomas Yanuziello, Indie Game Developer

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Vídeo promocional

      1:31

    • 2.

      Olá, mundo

      8:03

    • 3.

      Constantes e variáveis

      9:11

    • 4.

      Declarações e condições

      9:46

    • 5.

      Loops e operadores

      9:23

    • 6.

      Arrays e For loops

      10:32

    • 7.

      Pilhas e funções

      10:53

    • 8.

      Combinação e retorno

      9:34

    • 9.

      Árvore de cenas e herança

      10:21

    • 10.

      Abstração e encapsulação

      10:41

    • 11.

      Polimorfismo

      8:01

    • 12.

      Dicionário

      8:54

    • 13.

      Depuração

      9:08

    • 14.

      Configuração

      3:52

    • 15.

      Etiqueta A

      9:46

    • 16.

      Etiqueta B

      6:10

    • 17.

      Textura direta

      8:54

    • 18.

      Botão A

      9:24

    • 19.

      Botão B

      7:43

    • 20.

      Botão do link

      10:05

    • 21.

      Variação do tipo de tema

      4:33

    • 22.

      Painel

      7:30

    • 23.

      Reto de cores

      7:23

    • 24.

      Barra de menu

      6:20

    • 25.

      Menu pop-up

      10:00

    • 26.

      Sinais

      10:32

    • 27.

      Salvar dados

      8:50

    • 28.

      Contador

      8:18

    • 29.

      Edição de linha A

      10:50

    • 30.

      Edição de linha B

      7:46

    • 31.

      Botão de opção

      13:06

    • 32.

      Recipiente horizontal dividido

      3:28

    • 33.

      Recipiente de guias

      10:45

    • 34.

      Árvore A

      12:45

    • 35.

      Árvore B

      9:47

    • 36.

      Recipiente de rolagem

      12:30

    • 37.

      Botão de rádio

      9:52

    • 38.

      Botão de verificação

      4:01

    • 39.

      Controle deslizante vertical

      5:39

    • 40.

      6 4 Barra de progresso

      7:32

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

54

Estudantes

--

Projeto

Sobre este curso

Tudo pronto para começar a criar seu primeiro jogo no motor de jogos Godot?
Você tem dificuldade em usar os nós de controle da interface gráfica do usuário (GUI) do Godot?
Ou você quer se desafiar a construir um jogo inteiro em uma única cena usando apenas nós de controle?

Neste curso, vamos explorar tudo o que os nós de controle de GUI do Godot têm a oferecer, construindo um jogo completo do zero.

O início do curso se concentra em como escrever scripts e na linguagem GDScript.
Se você já estiver familiarizado com o Godot e o GDScript, pode pular essas aulas e ir direto para a aula Configuração.

Clique no link do meu site no meu perfil para participar do nosso servidor do Discord!

Conheça seu professor

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Professor
Level: All Levels

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Vídeo promocional: Você está pronto para começar a criar seu primeiro jogo no motor de jogo Gudo? Ou você quer aprender mais sobre como usar os nós de controle da interface gráfica de usuário do GDO Ou você quer se desafiar a criar um jogo inteiro em uma única cena usando apenas nós de controle? Neste curso, exploraremos tudo o que nós do Godo Gui Control têm a oferecer criando um jogo completo do É recomendável que você crie seu próprio jogo para este projeto. Seu jogo deve ter apenas uma cena e usar apenas notas de controle Gooey Começaremos criando uma tela de título, contendo um título, uma imagem de fundo, um botão Iniciar e links para redes sociais, explorando a grande variedade de opções disponíveis para cada tipo de nó. Em seguida, faça a transição para o jogo principal, adicionando uma barra de menu com vários estilos diferentes de opções de menu, incluindo ícones, teclas de atalho e submenus, escrevendo scripts que podem criar e gerenciar dados e configurações do jogador na linguagem de script nativa de Godo script Continuando com o desenvolvimento da mecânica de jogo, específica para o meu design, exploraremos o restante dos nós de controle do Gudo'Guy em detalhes à medida que avançarmos, para que você possa descobrir como aplicá-los ao Se você ficar preso, nosso servidor do Discord está cheio de outros estudantes, amadores e desenvolvedores profissionais de jogos que podem ajudá-lo Clique no link do site no meu perfil de professor para participar. Vamos começar a criar nosso jogo. 2. Olá, mundo: Olá amigos. você precisará baixar o GDOGameEngine em gdongine.org Se ainda não tiver feito isso, você precisará baixar o GDOGameEngine em gdongine.org . O motor é gratuito, mas você pode doar para apoiar o projeto, se quiser Não há processo de instalação. Você pode simplesmente extrair o arquivo compactado e abri-lo. Certifique-se de realocar o executável para um local melhor. A janela de lançamento inicial é uma lista dos seus projetos atuais. Mas se você ainda não tiver nenhum projeto, você será solicitado a explorar projetos de demonstração Podemos ignorar isso e simplesmente criar nosso próprio novo projeto clicando nesse botão na lista de projetos ou no botão Criar na parte superior da janela. Aqui podemos dar um nome ao nosso projeto, que normalmente seria o nome do seu jogo. Vou apenas introduzir a programação. O projeto precisa ser armazenado no disco rígido do nosso computador e criaremos uma nova pasta com o mesmo nome do projeto. Por padrão, ele deseja armazenar tudo na pasta de documentos, mas seria melhor criar uma nova subpasta para projetos Godot O renderizador altera a forma como certos dois objetos D e três D são renderizados, mas não vamos desenhar nada, então podemos ignorar essas opções O renderizador também pode ser alterado posteriormente. E a compatibilidade do controle de versão com o Github está incluída por padrão se você quiser usá-la para fazer backup do seu projeto ou compartilhá-lo com outras pessoas. Quando estiver pronto para começar, clique em Criar e editar. A janela do GdoEditor abrirá nosso projeto vazio recém-criado O editor está dividido em cinco docks principais. Uma prévia do nosso jogo está no centro. O dock inferior esquerdo contém um navegador de arquivos mostra o conteúdo da pasta do projeto que acabamos de criar. Atualmente, ele contém apenas o ícone Gado. O encaixe superior esquerdo contém a árvore de cenas, uma lista de tudo o que está em nossa cena atual, que está vazia no momento, então ele quer que criemos uma raiz para a árvore de cenas. Não vamos desenhar nada, então não precisamos especificar se essa cena tem dois D ou três D ou uma interface de usuário. Então, podemos simplesmente selecionar outro nó. Podemos criar muitos nós diferentes, mas só estamos interessados em aprender a escrever scripts, então usaremos apenas um nó padrão. Podemos renomear nosso novo nó clicando nele depois selecionado ou clicando com o botão direito do mouse para abrir o menu de contexto e selecionando renomear Vamos chamar esse nó de Lição 1. Selecionar qualquer nó na árvore da cena revelará suas propriedades no inspetor, que está encaixado no lado direito da janela Podemos ver o nome do nó selecionado e suas propriedades organizadas em categorias expansíveis, mas nenhuma dessas propriedades aplicável ao que estamos fazendo Antes de fazer qualquer outra coisa, devemos salvar nossa nova cena, selecionando salvar cena no menu de cena ou usando o atalho Control S ou Command S. Isso abre uma caixa de diálogo onde podemos especificar um nome para nossa cena com o TSCNetension e uma pasta devemos salvar nossa nova cena, selecionando salvar cena no menu de cena ou usando o atalho Control S ou Command S. Isso abre uma caixa de diálogo onde podemos especificar um nome para nossa cena com o TSCNetension e uma pasta de destino. Vamos criar uma nova pasta para a Lição 1 e depois salvar a cena nessa pasta. Agora podemos ver na guia do sistema de arquivos que nossa nova pasta foi criada para a Lição 1 e contém a cena da Lição 1, marcada com o ícone Clapperboard Em seguida, anexaremos um script ao nó raiz da nossa cena, selecionando o nó raiz e clicando no do script anexado ou clicando com o botão direito nele e selecionando o script anexado. A linguagem é GD Script, que é a linguagem de programação que vamos aprender Cada script herdará do tipo de nó ao qual está anexado por padrão Como o nó raiz é um tipo de nó padrão, nosso script herda do nó Não estamos usando um modelo nem um script incorporado, e podemos especificar onde esse script será armazenado no projeto. Vamos colocar isso na mesma pasta. Lição um. Ao nomear scripts, é importante não ser arbitrário, mas descrever o tipo de objeto ou comportamento que estamos criando por meio do Então, vamos chamar isso de olá. Os scripts têm a extensão de arquivo dotGD. Em seguida, clique em Criar para criar o script. Isso mudará nossa visualização para visualização de script, exibindo nosso script de saudação recém-criado. Também podemos ver nosso script na guia do sistema de arquivos indicada com um ícone de engrenagem, e o nó raiz da lição 1 tem o ícone do script para nos mostrar que ele tem um script anexado que, quando passarmos o mouse sobre ele , nos dirá o nome do Clicar nesse ícone também abrirá o script, caso ele ainda não esteja aberto. Nosso script tem apenas uma linha, que descreve sua herança do tipo de nó básico usando a palavra-chave extends Isso significa apenas que nosso script pode fazer tudo o um nó pode fazer, além de tudo o que escrevemos aqui. Também nos permite substituir os comportamentos do nó que já existem por novos comportamentos próprios Por exemplo, os nós têm uma função chamada ready, mas ela não faz nada. Então, se quisermos que nosso script substitua esse comportamento de não fazer nada, podemos declarar nossa própria função o mesmo nome usando a palavra-chave Funk é então seguido pelo nome da função, normalmente escrito em minúsculas, o que significa todas as letras minúsculas separando palavras com sublinhados que significa todas as letras minúsculas separando Muitas das funções definidas pelos nós são precedidas por um sublinhado, e o nome deve ser uma correspondência exata para substituir o comportamento O nome da função deve ser seguido por parênteses e Examinaremos o porquê mais tarde. Pressionando Enter após essa linha, a próxima linha é automaticamente recuada em um nível É assim que o GD Script sabe quais linhas estão contidas na função e onde ela termina A linha é destacada em vermelho porque as funções não podem ficar vazias. Portanto, é uma boa ideia escrever a palavra pass para dar às novas funções um corpo que não faz nada. Agora que o erro desapareceu, podemos ver esse ícone de seta azul aparecer na frente da declaração da função, que é o símbolo de substituição, indicando que esse script agora está substituindo o comportamento pronto do nosso Em vez de não fazer nada, queremos que nosso nó diga olá, o que podemos fazer com uma declaração de impressão, substituindo a linha que dizia passar anteriormente. A instrução print é semelhante a uma declaração de função com um nome seguido por parênteses porque está chamando uma função incorporada Essa função requer um argumento, que é o que está dentro dos parênteses E esse argumento é o que será impresso. Usando aspas, podemos escrever o que quisermos e isso será impresso pelo nosso script quando o nó estiver pronto Como o script se chama hello, o comportamento que queremos criar é que o nó diga hello. Com nosso script pronto, podemos executar nosso jogo usando o botão executar cena atual no canto superior direito ou usando o atalho F six Isso exibirá uma janela vazia, já que nosso jogo não desenha nada, mas também abre o quinto dock, exibindo o painel de saída. E em nossa saída, podemos ver que nosso nó imprimiu as palavras hello world quando estava pronto. Podemos finalizar essa simulação fechando a janela, clicando no botão parar ou usando o atalho F oito Podemos alterar o texto impresso para dizer o que quisermos e executá-lo novamente para ver se nosso nó pode imprimir tudo o que pedimos. Agora sabemos como anexar scripts aos nós e executá-los. Na próxima lição, aprenderemos sobre constantes e variáveis Te vejo na próxima aula. 3. Constantes e variáveis: Olá, amigos. Começaremos cada lição criando primeiro uma nova pasta para a lição. Em seguida, criando uma nova cena nessa pasta com o mesmo nome. Clique duas vezes em uma cena na guia do sistema de arquivos para abri-la. Com várias cenas abertas, podemos alternar entre elas clicando em suas guias no documento de visualização Hoje, discutiremos as diferenças entre constantes e variáveis usando dias como nosso quadro de referência Então, vamos anexar um novo script ao nó raiz da cena e nomear seus dias. Vamos começar com constantes e declarar uma na parte superior do script usando a palavra-chave const, seguida pelo nome da nossa nova constante, seguida pelo nome da nossa nova constante, que é convencionalmente escrita Uma constante é como um contêiner onde podemos armazenar informações, mas essas informações nunca podem ser alteradas. Algo que consideraríamos constante pode ser o número de dias na semana. Como não pode ser alterado, ele deve receber um valor imediatamente, é por isso que temos um erro. Devemos seguir o nome com um sinal de igual, o operador de atribuição para dar um valor à constante O número de dias na semana é sete. É razoável supor que sempre serão sete e que seja o mesmo para todos. Portanto, ele nunca deve precisar alterar seu valor. Por outro lado, temos variáveis, que também são contêineres para armazenar informações, mas projetadas para serem alteradas Podemos declarar uma variável da mesma forma usando a palavra-chave VR e, em seguida, atribuindo a ela um nome convencionalmente escrito em minúsculas Isso facilita a visualização da diferença entre constantes e variáveis em nossos scripts Algo que muda com frequência pode ser o valor de hoje. Ao contrário das constantes, as variáveis podem ficar vazias. Vamos substituir a função ready do nosso nó base e imprimir os valores do número de dias da semana e de hoje Podemos ver que o número de dias na semana é sete, mas o valor de hoje é impresso como nulo, o que significa vazio ou nenhum valor Vamos corrigir isso inicializando hoje como quinta-feira. E podemos tornar nossa saída mais legível adicionando algum contexto, começando com algo como hoje, deixando um espaço depois de um sinal de adição e, em seguida, nossa variável Nesse caso, o sinal de mais está sendo usado para acrescentar duas partes da frase se tentarmos fazer a mesma coisa No entanto, se tentarmos fazer a mesma coisa com nossa constante, isso causará um erro porque nossa constante é um número, não uma palavra. Quando declaramos nossa constante, atribuímos a ela um valor de sete, que é um número sem nenhum ponto decimal, que em matemática é chamado de inteiro Portanto, nossa constante tem um tipo de número inteiro. Hoje, por outro lado, foi atribuído um valor de alguns caracteres entre aspas Em programação, chamamos isso de string. Portanto, nossa variável tem um tipo de string. O operador plus só pode ser usado quando os tipos de ambos os operandos são compatíveis Podemos contornar isso usando uma função embutida para alterar o tipo que está sendo usado aqui para uma string, passando a constante como argumento para a função. Isso não mudará o tipo da constante original, apenas como ela está sendo usada aqui no contexto da operação de acréscimo. E também podemos continuar adicionando mais contexto com outra string anexada, lembrando de adicionar um espaço extra na frente Agora podemos imprimir nossa constante e variável usando-as em frases fáceis de entender. Depois dessas linhas, vamos fingir que um dia passa. Podemos adicionar contexto extra aos nossos scripts que nunca serão vistos pelos jogadores mas que existem apenas para nos ajudar, como desenvolvedores entender nosso próprio código ou código escrito por outras pessoas. Eles são chamados de comentários e são criados usando o sinal ou hashtag OctathorpPound Qualquer texto escrito após esse símbolo será colorido em cinza e não afetará de forma alguma a forma como o script é executado. Eles podem estar em suas próprias linhas ou no final de uma linha de código. Então, vamos usar um comentário para explicar que estamos fingindo que passou um dia entre o código acima dessa linha e o código abaixo Mudaremos o valor de hoje para sexta-feira e imprimiremos outra frase. Hoje é mais Hoje, que agora tem um valor diferente. Podemos ver que o valor de hoje foi impresso primeiro como quinta-feira e depois alterado e impresso como sexta-feira na próxima linha. O comentário não teve efeito na execução do script. Se tentarmos alterar o valor da nossa constante, obviamente, isso causará um erro porque as constantes não podem ser alteradas Se não quisermos mais usar algumas linhas de código em nosso script, podemos alterá-las facilmente para comentários destacando-as e pressionando Control K ou Command K, adicionando o símbolo de comentário na frente de cada linha destacada Pressionar novamente removerá os comentários. Podemos especificar o tipo de variável ou constante adicionando dois pontos após o nome Seguido pelo nome do tipo, também queremos restringir essa constante ou variável. Vamos restringir nossa constante para ser do tipo int e hoje do tipo string. Além de strings e números inteiros, existem dois outros tipos primitivos que podemos usar para armazenar Se um número tiver pontos decimais, ele não será mais um número inteiro e em vez disso, um tipo diferente chamado número de ponto flutuante, que usa o nome de tipo Vamos adicionar outra variável para a data de hoje e atribuir a ela um tipo de número de ponto flutuante com um valor de 12,05, que é a data de hoje, 5 de dezembro E o último tipo é chamado Boolean usando o nome abreviado Boole, que pode ser verdadeiro ou Então, adicionaremos outra variável para determinar se hoje é feriado ou não. Vou restringir isso para ser um booleano, mas não vou dar a ele um valor inicial Vamos adicionar mais duas instruções de impressão para imprimir os valores dessas variáveis com contexto. A data de hoje é mais uma data e hoje é feriado. Colon plus é feriado. Quando executamos isso agora, podemos ver nossa data impressa, mas se um feriado diz falso, apesar de não lhe dar um valor. Isso ocorre porque todos os tipos primitivos têm um valor padrão, mas o valor padrão só pode ser atribuído se especificarmos o tipo de variável Como especificamos que um feriado é um booleano, ele foi atribuído ao valor padrão um booleano, que é falso O valor padrão para um número inteiro e um número de ponto flutuante são zero, e o valor padrão para uma string é apenas uma string vazia, que não é o mesmo que null, mas é uma string sem caracteres Se não especificarmos o tipo de uma variável, seu valor padrão será nulo, mas ela poderá receber um valor de qualquer tipo, e seu tipo poderá mudar a qualquer momento Vamos remover o tipo da data. Em seguida, atribua um novo valor de 13 de dezembro e imprima-o pela segunda vez. A variável começa recebendo um valor de um número de ponto flutuante, é usada pela instrução print e, em seguida, recebe um valor de string antes de ser impressa novamente. Isso é permitido porque o GD Script é uma linguagem de digitação livre Isso oferece maior flexibilidade ao escrever nossos scripts, mas também maior responsabilidade de evitar erros de compatibilidade de tipos, como vimos com o operador plus. É recomendável que você sempre forneça um tipo às variáveis, não apenas para evitar erros, mas também para melhorar a eficiência da execução de seus scripts. Se o mecanismo souber o tipo de suas variáveis , ele também saberá exatamente quanta memória precisa ocupar. Isso também se aplica ao uso constantes no lugar de variáveis Se o motor souber que o valor não pode mudar, ele poderá ser usado com mais eficiência. Na próxima lição, aprenderemos sobre como controlar o fluxo de nossos scripts. Te vejo na próxima aula. 4. Declarações e condições: Olá, amigos. Eu já criei uma nova cena em uma nova pasta para esta lição. Hoje, aprenderemos como controlar o fluxo de nossos scripts para executar diferentes linhas de código, fazendo escolhas sobre se podemos ou não ver. Então, vamos anexar um novo script ao nó raiz da nossa cena e chamá-lo de visão. Começaremos nosso script substituindo a definição dos nós básicos da função pronta O método mais básico de controlar o fluxo de nossos scripts é a instrução I, que começa com a palavra-chave I. I é seguida por uma declaração condicional que deve ser verdadeira ou falsa Por enquanto, vamos colocar verdadeiro, que é seguido por dois pontos Semelhante aos dois pontos no final de nossa declaração de função, isso marca o final da declaração e, continuando até a próxima linha, ela é automaticamente recuada em outro nível Qualquer linha de código após essa instrução if, que esteja indentada, só será executada se a condição da instrução if for verdadeira Então, vamos imprimir algo como se a condição fosse verdadeira e, em seguida, executar a cena atual para ver nossa declaração impressa funcionando. Se alterarmos verdadeiro para falso, podemos ver que a declaração de impressão é ignorada dessa vez Podemos adicionar outra linha após o corpo recuado das declarações if no mesmo nível de recuo instrução I simplesmente com a palavra-chave s seguida por dois pontos Isso cria outro corpo condicional que será executado somente se a condição da instrução I original não for atendida Vamos duplicar a declaração impressa e alterá-la para dizer algo diferente Como a condição era falsa, o bloco se foi executado em vez do bloco I. E se mudarmos a condição para verdadeira, o inverso acontecerá. Isso não é muito útil se sempre soubermos que o resultado da declaração condicional é verdadeiro ou falso, mas podemos substituí-lo por uma variável Vamos declarar uma variável booleana, que é se a luz está acesa ou não na sala Os booleanos são convencionalmente nomeados tal forma que implicam seu uso Nesse caso, a luz acesa está implícita como verdadeira ou falsa com base na forma como é nomeada Agora, nossa declaração if pode definir sua condição para ser se o valor de nossa variável é igual ou não a verdadeiro. Ao comparar dois valores para ver se eles são iguais, usamos um sinal de igual duplo, conhecido como operador de igual, que é diferente de um único sinal de igual, como usamos anteriormente como operador de atribuição. Em seguida, imprimiremos se consigo ver ou não consigo ver, como resultado de a luz estar acesa ou não ser igual à verdadeira. Como o valor padrão de um booleano é falso, podemos ver a saída como eu não consigo ver Mas se definirmos a variável como verdadeira, ela muda para Eu posso ver. Como a variável em si é um booleano, verdadeiro ou falso, podemos remover completamente a operação de comparação e apenas usar o booleano como condição e obter exatamente o Podemos reverter o valor de qualquer booleano, ou seja, se for verdadeiro, ele se torna falso ou, se for falso, ele se tornará verdadeiro usando a palavra-chave not Assim como a função STR que usamos na lição anterior, isso só muda a forma como ela está sendo usada no contexto local e, na verdade, não altera o valor armazenado na variável Então, se nada, a luz está acesa, então não podemos ver e então podemos ver Nada também pode ser representado por um ponto de exclamação. Vamos alterar o valor das luzes acesas e executá-las novamente. Em seguida, reverterei essas mudanças para o que eram antes Podemos tornar nossas condições muito mais complexas combinando várias condições usando operadores lógicos. Vamos criar outra variável chamada Tem visão escura. Essa variável implica que devemos ser capazes ver mesmo que a luz não esteja acesa. Portanto, podemos adicionar às nossas declarações if a condição que a luz esteja acesa ou que tenhamos uma visão escura. E se alguma dessas condições for verdadeira, então podemos ver. Somente se ambas as condições forem falsas, isso resultará na impossibilidade de enxergarmos? E se, em vez de ter visão escura, usássemos óculos de visão noturna, pois eles só nos permitem ver no escuro, mas não na luz Alterando o nome da variável, a condição da nossa declaração I precisa mudar. Uma vez que, se ambas as condições forem verdadeiras, não deveríamos ser capazes de ver. Somente se os valores dessas duas condições forem diferentes, devemos considerar a condição a ser atendida? Podemos usar o operador não é igual para verificar se os dois valores não são iguais entre si Se você estiver familiarizado com operações lógicas, isso é conhecido em outras linguagens como exclusivo ou. Agora, somente se a luz estiver acesa ou se estivermos usando óculos de visão noturna e não ambos, seremos capazes de ver Em seguida, vamos considerar que nossa pessoa hipotética pode não ser humana e adicionar uma variável para o número de Is que ela tem, que deve ser representada como um Por enquanto, atribuiremos o valor de dois olhos. Ignorando as outras variáveis, qual seria a condição que definimos para poder ver com base nessa variável Se o número de olhos que temos for maior que zero, então devemos ser capazes de ver. Também podemos expressar isso usando outro operador, maior ou igual a, e mudar o lado direito para um. Portanto, eles devem ter olhos maiores ou iguais a um. Esses são operadores de comparação que retornarão um resultado booleano comparando o valor dos números nos lados esquerdo e direito Podemos concluir logicamente que deveria ser impossível para qualquer criatura humana ou não ter um número negativo de olhos O valor da nossa variável deve ser apenas zero ou algo maior que zero. E a condição para poder ver realmente se resume a essas duas opções Temos olhos zero ou olhos diferentes de zero? Assim como a variável booleana pode ser usada implicitamente como uma condição, um inteiro também pode ser usado dessa forma, com zero sendo considerado uma condição falsa e qualquer coisa diferente de zero sendo A mesma lógica também é aplicada aos números de ponto flutuante. Podemos declarar uma variável flutuante, vamos chamá-la de alcance de visão e atribuir ela um valor arbitrário de Podemos usar nossos operadores de comparação para determinar se esse número é maior que menor ou igual a um determinado valor, ou podemos usá-lo implicitamente em sua própria condição com zero sendo considerado falso e qualquer outra coisa sendo considerada verdadeira E quanto às cordas? Vamos mudar um pouco as coisas e declarar uma variável de string para o que ouvimos e atribuir a ela o valor de solavancos durante a noite Então, podemos logicamente usar isso como uma declaração if como se o que eu ouvi não fosse uma string vazia, então podemos dizer, eu ouvi alguma coisa Caso contrário, não ouvi nada. E, assim como os outros tipos de variáveis, podemos descartar a comparação e usar a própria variável como condição. Com todas as variáveis, seus valores padrão são considerados falsos, e qualquer outra coisa é sempre considerada verdadeira quando usada como condição. Se declararmos uma variável sem um tipo, vamos chamá-la do que estou vendo, mas não atribuirmos um valor a ela, então já sabemos que seu valor padrão será nulo Mesmo sem um tipo ou valor, qualquer variável pode ser usada como condição de bullying Qualquer variável vazia, o que significa que seu valor é nulo, é considerada falsa Se preenchêssemos essa variável com um objeto , seu valor como condição seria considerado verdadeiro No momento, não temos outros objetos com os quais brincar, mas sempre podemos nos usar. Então, vamos definir o valor do que eu estou vendo como a palavra-chave self. E isso resulta em ser capaz de ver. Na próxima lição, usaremos loops para repetir linhas de código várias vezes. Te vejo na próxima aula. 5. Loops e operadores: Olá, amigos. Hoje, aprenderemos a repetir linhas de código várias vezes com loops, imaginando uma senhora que se apaixonou pela primeira vez segurando uma flor Então, vamos escrever um novo roteiro e chamá-lo de flor. Em seguida, substitua a definição dos nós básicos da função pronta Nossa senhora imaginada está segurando uma flor com várias pétalas, que armazenaremos em uma variável e restringiremos seu tipo a um Em seguida, atribua um valor de algum número arbitrário, digamos cinco Também declararemos outra variável chamada He Loves Me, como booleana, na qual acreditamos ter seu valor padrão de false Podemos começar nosso roteiro imprimindo uma história sobre a mulher apaixonada segurando sua Ela remove cada pétala da flor, uma por uma, afirmando que ele me ama ou não me ama Primeiro, precisamos reduzir o número de pétalas na flor em uma Então, começaremos com a variável número de pétalas e, em seguida, usaremos o operador de atribuição para atribuir um novo valor à variável O valor que queremos atribuir é o número que ele já tem menos um Em seguida, queremos alterar o valor da variável booleana. Ele adora que eu seja o oposto. Então, ele me ama, é designado para não me amar, revertendo o valor da falsa verdade ou vice-versa. Em seguida, podemos imprimir os resultados. Ele me ama. Talvez queiramos encapsular essa parte entre aspas, mas se tentarmos colocar uma aspa dentro de nossa string, ela marcará o final da Alguns caracteres especiais, como aspas, podem ser criados dentro de uma string usando uma barra invertida Se escrevermos aspas de barra invertida, isso agora representa um caractere de aspa, não o final da string E podemos incluir outro após a declaração das senhoras. Vamos duplicar essa linha e mudar a declaração para dizer: Ele não me ama Outro exemplo de caractere especial que podemos escrever usando a barra invertida é a própria barra invertida Também podemos combinar as duas linhas acima e separá-las com a barra invertida N, que representa uma nova Portanto, eles são impressos em duas linhas de saída a partir de uma única declaração de impressão. Agora temos duas possibilidades que queremos imprimir com base no valor da nossa variável booleana Portanto, parece que devemos envolvê-los em uma declaração if. Se ele me ama, então imprima isso. Se ele não me ama, então imprima isso. Mas nos casos em que as declarações dependem de uma única variável booleana para fazer uma pequena alteração, existe um método mais eficiente Então, vamos voltar ao formato original. Nossa declaração será que ele me ama, se ele me ama, contrário, ele não me ama. Isso não é o mesmo que uma instrução if, apesar de usar as mesmas palavras-chave, mas é chamado de operação ternária Como ele não cria um novo bloco de código com um recuo, ele é executado com mais eficiência e é recomendado para ser usado em casos simples como este Na verdade, podemos reduzir ainda mais o tamanho da variação alterando-a apenas para um ponto de exclamação ou um espaço seguido pela palavra não e depois pelo ponto de exclamação Isso funciona no caso de ele me amar, mas se alterarmos o valor para verdadeiro por padrão , só veremos o que não acontece no outro caso. Assim como na matemática, há uma ordem específica de operações na qual nossos scripts executarão várias operações na mesma linha. Como tanto a string append quanto o ternário I são operadores, um deve ser executado antes do outro e, nesse caso, será o string append E, assim como na matemática, os colchetes são sempre os primeiros a serem executados Assim, podemos colocar qualquer operação entre colchetes para garantir que ela seja executada primeiro na ordem das operações Colocando nossa declaração ternária entre colchetes, ela agora será executada antes da sequência ser anexada e nos dará o resultado e Agora temos nosso bloco de código que precisa ser repetido enquanto a flor ainda tiver pétalas. Usando a palavra-chave WOW, assim como uma declaração if, podemos repetir um bloco de código recuado , desde que a condição permaneça verdadeira A condição neste caso é que o número de pétalas na flor não seja zero Qualquer que seja o número de pétalas na flor, ele será reduzido em uma a cada vez Depois da instrução de impressão, o fluxo lógico desse script retornará ao início do loop do WoW para verificar a condição novamente. Quando o número de pétalas chega a zero, a condição não é mais atendida e o loop é interrompido, continuando com o restante do script, se houver Então, vamos escrever uma breve conclusão para nossa história com base nos resultados. Ela se levanta com lágrimas nos olhos. Mas com base no valor final de Ele me ama, ela está feliz ou triste, e imprimiremos a frase final diferente. Executando essa cena, podemos ver nossa história impressa no painel de saída e, com cinco pétalas, a senhora está feliz Se mudarmos o número de pétalas para seis, obteremos um resultado diferente, pois o loop se repetiu seis vezes em vez de cinco Mas o que acontece se mudarmos o número de pétalas da flor para zero O ciclo não funciona de jeito e o amor estava condenado desde o Não recomendo seguir este exemplo, mas observe o que acontece se dermos à flor um número negativo de pétalas. Embora isso seja realisticamente impossível, em nosso código, é muito Como a condição de nosso laço de parede nunca será atendido, ele nunca se quebrará e o script ficará preso dentro dele, nunca terminando Esse é um loop infinito e deve ser evitado a todo custo. Nesse caso, podemos evitar o loop infinito alterando nossa condição para ser se o número de pétalas for maior que zero, pois um número negativo ainda quebrará o loop Podemos usar outro operador ao reduzir o número de pétalas como atalho Eliminando a necessidade de escrever o nome de nossa variável duas vezes, podemos realizar operações matemáticas simples em nosso número de variáveis usando um operador de atribuição especial Nesse caso, o operador menos igual a um pode alterar essa linha de código para número de pétalas menos igual a número de pétalas Esses atalhos existem para todas as operações aritméticas básicas mais multiplicar é igual ou dividir é igual e podem ser usados com qualquer número ou variável como e podem ser todas as operações aritméticas básicas mais iguais, multiplicar é igual ou dividir é igual e podem ser usados com qualquer número ou variável como o outro operando. Também existe mais um operador para aritmética básica, o operador de módulo, representado pelo Modulus executa uma operação de divisão, mas não retorna o quociente como resultado, como faz o operador de divisão Em vez disso, ele retorna o restante da divisão. Todo esse roteiro, além da história que está sendo contada, está apenas determinando se o número de pétalas na flor é um número par ou ímpar, mas está fazendo isso da maneira mais ineficiente possível, contando cada Então, vamos comentar todo o loop da parede e, em vez disso, usar o módulo para acelerar o processo Sabendo que todos os números pares são divisíveis por dois, podemos usar o módulo do número de pétalas O único resultado possível como restante dessa divisão será zero se o número de pétalas for par ou um se o número de pétalas for ímpar Portanto, nosso script pode ser simplificado para que, se o número de pétalas do módulo dois for igual a um, a senhora Caso contrário, ela está triste. E como entendemos como números inteiros são interpretados como condições, nem precisamos realizar a operação de comparação aqui e podemos simplesmente encurtá-la para I, número de pétalas O resultado da operação do módulo pode ser atribuído diretamente à variável booleana para obter o mesmo resultado sem a necessidade de uma instrução if, e o zero ou um será automaticamente convertido em falso ou verdadeiro de acordo E poderíamos ir mais longe removendo a variável e usando apenas a operação de módulo diretamente dentro da instrução turny Na próxima lição, aprenderemos sobre coleções de variáveis relacionadas. Te vejo na próxima aula. 6. Arrays e For loops: Olá, amigos. Hoje, consideraremos como podemos organizar grandes quantidades de variáveis, especialmente quando elas contêm informações relacionadas. Eu já criei um script chamado censo e substituí definição de nós básicos da função pronta Para nosso cenário hipotético nesta lição, estamos imaginando um funcionário do censo que precisa registrar quantas pessoas moram em cada casa em uma única estrada em Podemos declarar uma única variável para conter todas essas informações, vamos chamá-la de Main Street E o tipo dessa variável será uma matriz. Uma matriz pode conter uma lista de variáveis de qualquer um dos outros tipos. Nesse caso, o tipo de variável que procuramos são números inteiros, representando o número de pessoas que moram em cada casa Podemos especificar o tipo de conteúdo de uma matriz usando colchetes após a matriz do nome do tipo e colocando o tipo do conteúdo dentro dos colchetes Agora, essa matriz só pode conter números inteiros como seu conteúdo. Antes de podermos acessar o conteúdo de uma matriz, ela precisa ter um tamanho, o número de variáveis contidas nela. Ao contrário de outras variáveis, as matrizes são mais complexas e têm suas próprias funções Podemos acessar essas funções seguindo o nome da variável com um ponto e, em seguida, o nome da função. Nesse caso, a função de redimensionamento, que define o número de endereços dentro dessa matriz, representando o número de casas na Main Street, que diremos que é seis Nossa cidade imaginária é um pouco incomum, pois os números das casas na Main Street começam em zero Então, nosso funcionário do censo começa na casa, no zero da Main Street, e bate na porta para perguntar ao morador da casa quantas pessoas moram na Podemos armazenar um valor em uma matriz começando com seu nome e, em seguida, usando colchetes para marcar o endereço do inteiro específico, nesse caso, endereço zero e, em seguida, usando o operador de atribuição Podemos atribuir um número inteiro a esse endereço. Então, digamos que a casa número zero na Main Street tenha cinco pessoas morando nela. Passando para a próxima casa no endereço número um da Main Street, alguém atende a batida na porta e diz ao funcionário do censo que há duas pessoas morando naquela Na próxima casa, endereço número dois, a casa está em construção e tem uma placa de venda, que significa que esta casa está claramente desocupada, e nosso funcionário do censo registra o número de residentes como zero No número três da rua principal, ninguém abre a porta, apesar do fato de haver um carro na garagem e sinais de ocupação O que podemos considerar os funcionários do censo deveriam registrar como o número de residentes Podemos pensar que pode ser zero. Mas como diferenciaríamos entre um número desconhecido de ocupantes e uma casa desocupada Se considerarmos que o número de ocupantes de uma casa nunca deve ser considerado um número negativo, poderíamos usar o número menos um para significar que o número de ocupantes da casa é um valor desconhecido E no número quatro da Main Street, novamente, não há resposta na porta. Mas a casa também parece estar abandonada e, provavelmente, ninguém mora lá há algum Podemos assumir que o número de ocupantes é zero talvez usar o mesmo valor de menos um para um número desconhecido de ocupantes ou criar mais códigos de valor negativos para situações diferentes, como usar menos dois para significar provavelmente desocupado, mas O endereço número cinco na Main Street nem tem uma casa, mas é apenas um terreno baldio Então, novamente, isso pode ser representado com um zero ou outro valor negativo para codificar algum tipo de reunião Vamos imprimir os resultados do censo e ver como eles se parecem Podemos ver nossa matriz representada como uma lista separada por vírgulas de números encapsulados Isso representa um trabalho decente ao representar o número de pessoas que moram em cada casa na Main Street. Mas e se quiséssemos usar esses dados para obter um número total de ocupantes de todas as casas na Main Street ou em média Se calculássemos a soma de todos esses números, os números desconhecidos representados como negativos distorceriam os resultados Um dos melhores benefícios de usar matrizes para armazenar informações relacionadas dessa forma é a facilidade de percorrê-las Usando a palavra-chave quatro, escrevemos em seguida o nome de uma nova variável, que representará cada elemento individual dentro da matriz, seguida pela palavra-chave in e, em seguida, pelo nome da matriz. Como as funções, se as instruções forem loops wa, isso será seguido por dois pontos e um bloco de código recuado que será repetido Essas linhas de código serão repetidas uma vez para cada uma de nossas seis casas na Main Street, e podemos nomear a variável house, pois ela será usada para acessar cada casa individual dentro do loop. Digamos que primeiro queremos encontrar o número médio de ocupantes que moram em uma casa ocupada Isso significaria somar todos os números positivos e depois dividir pelo número de casas ocupadas Então, precisaremos de três novas variáveis, uma para o número total de ocupantes, outra para o número de casas ocupadas, ambas como números inteiros, e um número de ponto flutuante para a média Para cada casa na Main Street, podemos verificar se a casa está ocupada, se o número armazenado na matriz desse endereço agora armazenado na variável casa é algo maior que zero. Se isso for verdade, o número total de ocupantes em casas ocupadas pode ser aumentado por casa e o número de casas ocupadas incrementado Depois que todas as seis casas na Main Street foram verificadas, o circuito é interrompido e temos nossos dois números inteiros Assim, podemos calcular a média dividindo o número total de ocupantes pelo número de casas ocupadas Em seguida, imprima os resultados. Há mais casas ocupadas, mais casas ocupadas na Main Street, com uma média de mais ocupantes médios mais ocupantes Mas se executarmos esse código, a média é representada como um número inteiro, três, que sabemos que não está correto, já que há um total de sete ocupantes em duas casas ocupadas, a média deve ser 3,5 Isso aconteceu porque realizamos uma operação de divisão com dois números inteiros, e o resultado da operação também será um número inteiro, mesmo que o estejamos atribuindo a uma variável de número de ponto flutuante Godot também fornece um aviso contra o uso de números inteiros em operações de divisão Para resolver isso, podemos alterar nossas variáveis inteiras para números de ponto flutuante em suas declarações ou podemos alterar seu tipo localmente antes de realizar a divisão Da mesma forma que transformamos números inteiros em strings antes de anexá-los, podemos transformar um inteiro em um número de ponto flutuante antes de realizar uma Alterando também o resultado da divisão para um número de ponto flutuante. Alterar o tipo de uma variável dessa maneira é chamado de conversão. Estamos convertendo um número inteiro em um flutuador. Agora podemos ver os resultados que esperávamos com uma média de 3,5 ocupantes por casa ocupada Uma vantagem do GD Script, por ser uma linguagem de tipos vagos, é que não precisamos especificar os tipos de nossas variáveis, incluindo os tipos contidos em Se permitirmos que nossa matriz contenha qualquer tipo de variável, podemos alterar a forma como nosso funcionário do censo registra as informações Vamos supor que o endereço zero permaneça o mesmo com cinco ocupantes Mas o endereço um também forneceu os nomes dos dois residentes que moram lá. Em vez de registrar os ocupantes como número dois, poderíamos gravar seus nomes em uma string Portanto, o endereço número um da Main Street é ocupado por Jordan e Ashley Smith A casa número dois estava desocupada, o que poderíamos representar como zero Mas também podemos considerar registrá-la como um booleano e atribuir a ela um valor falso para significar que a casa está em construção e não pode ter ocupantes No número três, ninguém estava em casa, mas definitivamente há pessoas morando lá. Nós simplesmente não sabemos quantos. Também podemos armazenar esse valor como um booleano e atribuir a ele um valor verdadeiro No número quatro, realmente parece que ninguém mora lá. Talvez queiramos comercializar com zero ocupantes. No endereço número cinco, como não há nem mesmo uma casa lá, podemos realmente considerar o uso de nulo como valor, já que nulo representa a ausência de qualquer Podemos usar a palavra-chave null para atribuir isso à matriz no endereço cinco Agora, nossa matriz impressa parece bem diferente, contendo variáveis de todos os tipos diferentes em vez de apenas números inteiros, e podemos discernir mais informações a partir dela As matrizes podem até conter outras matrizes como conteúdo. Então, vamos mudar nossa lista de nomes de uma única string para uma matriz de strings. Podemos criar essa matriz ao mesmo tempo em que ela está sendo atribuída usando colchetes e, em seguida, preenchendo-a com uma lista de strings separada por vírgulas Então, se quiséssemos saber quantas pessoas estão morando no endereço um na Main Street, poderíamos imprimir isso como Mainstreet one dot Na próxima lição, aprenderemos mais usos de matrizes para criar coleções de dados mais dinâmicas Te vejo na próxima aula. 7. Pilhas e funções: Olá, amigos. Hoje, continuaremos trabalhando com matrizes de maneiras diferentes configurando um jogo antigo Eu já criei um script chamado Old Made e substituí a definição de nós básicos da função ready Para jogar antiquado, precisamos de um baralho de cartas, que é uma coleção de variáveis que podemos manter dentro de uma matriz. Como o jogo Old Made realmente não se importa com os naipes das cartas, podemos ignorar essa informação, e cada elemento da matriz só precisa conter as cartas classificadas do ás ao rei como um número inteiro Para gerar nosso deck, podemos usar quatro loops. Mas, em vez de usar o loop de quatro para percorrer uma matriz, ele pode ser usado apenas para contar a classificação de nossas cartas Começando com quatro, podemos declarar uma variável para representar a classificação de uma carta, seguida pela palavra-chave in e, em seguida, especificar um número Se considerássemos King um número, seria o 13º posto Por enquanto, vamos apenas imprimir a classificação para que possamos ver o que acontece. O quatro loop começa com um valor de classificação em zero e conta até 12, repetindo esse loop e imprimindo a declaração 13 vezes Por uma questão de sanidade, pode ser uma boa ideia considerar que a carta número dois seja representada pelo nível dois e, portanto, Ás seria um e rei seria 13 Embora iniciar um loop de quatro em zero seja realmente útil para iterar por meio de matrizes, já que o primeiro número de índice é zero, não é muito útil nesse caso Podemos mudar a forma como um loop de quatro é contabilizado substituindo o 13 por uma chamada de função, range. As chamadas de função são seguidas por parênteses contendo argumentos. Os argumentos para essa função são os limites inferior e superior do intervalo. O limite inferior será incluído no intervalo, mas o limite superior não será incluído. Portanto, o intervalo 114 conterá todos os números de 1 a 13, e podemos ver que isso está impresso na saída Outra forma de adicionar informações a uma matriz em vez de usar os colchetes e número do índice é usar uma função chamada append Essa função de acréscimo aceita um argumento do valor que está sendo adicionado à matriz Isso posicionará o valor que está sendo adicionado ao final da matriz, onde quer que esteja. E como há quatro de cada valor em um baralho de cartas, um para cada naipe, devemos repetir essa linha de código quatro vezes para cada valor. Podemos fazer isso com mais quatro voltas, desta vez começando em zero e contando até, mas sem incluir quatro. Imprimindo o baralho, podemos ver que nossa matriz tem quatro de cada número de 1 a 13, totalizando 52 cartas Mas para jogar antiquado, queremos remover três das rainhas, ou neste caso, 12 Então, em nossos quatro ciclos que percorrem os naipes das cartas, vamos verificar se a classificação é 12 E nesse caso específico, queremos permitir que apenas 112 seja adicionado, usando a palavra-chave break para sair instantaneamente desse loop. quebra encerrará apenas o loop mais recuado em que se encontra atualmente Então, terminaremos o naipe por loop, mas não o rank por loop. Isso aumentará a classificação para 13 e prosseguirá com a adição de quatro treze ao baralho E testando isso, podemos ver que há apenas 112. A primeira coisa que acontece em nosso jogo é embaralhar o baralho de cartas, que no script GD é uma simples de rayse Só precisamos chamar essa função e podemos ver que as cartas são embaralhadas em nosso baralho Também precisaremos de outra variável, uma série de mãos de cartas para representar nossos jogadores. Cada mão dentro da matriz de mãos precisa conter várias cartas, então elas também são matrizes, que precisaremos inicializar antes de podermos usá-las Portanto, contando de zero a quatro, mas não incluindo quatro, podemos acrescentar uma nova mão à matriz Nossa mão começa como uma matriz vazia representada por colchetes. Se imaginarmos nosso baralho de cartas, a frente das cartas sendo o lado com o anel e o naipe, o verso da carta em branco, então também podemos imaginar o baralho virado para baixo A frente da matriz é a parte inferior da plataforma e a parte de trás da matriz é a parte superior da plataforma. O processo de distribuição das cartas pode ser feito iterando nosso baralho, mas na verdade não precisamos referenciar cartas específicas, pois na verdade não importa o que sejam, apenas que a carta seja retirada do topo do baralho e entregue a um jogador Então, para remover uma carta do topo do baralho, podemos chamar outra função. Este se chama Pop back. Ele não apenas retorna o último elemento na matriz, mas também o remove da matriz. Em seguida, queremos adicionar essa carta à mão do jogador e começaremos com o jogador um, supondo que o jogador zero seja o dealer Assim como podemos usar o pop-back para remover um cartão, também podemos adicionar um cartão com pushback A carta que estamos colocando na parte de trás da mão do jogador é a mesma carta que estamos tirando da parte de trás do baralho Então, podemos simplesmente colocar essa chamada de função dentro dos colchetes da chamada de função e usar seu valor de retorno como argumento para a função push Usar pushback é exatamente o mesmo que anexar. A função append é um legado de strings, já que elas geralmente são armazenadas como matrizes de caracteres, enquanto push e pop vêm do uso de pilhas ou cues Para distribuir nossa próxima carta, precisaremos incrementar a mão que está sendo distribuída. Então, vamos armazenar isso em uma variável como um número inteiro e atribuir a ela o valor inicial de um Substituindo aquele em nosso índice de matriz por nossa variável, precisaremos incrementá-lo um após cada carta ser distribuída Mas, obviamente, isso contará apenas até 51, e não há tantas mãos. Então, precisaremos que esse número retorne a zero toda vez que chegar a quatro. Isso pode ser feito usando nosso operador de módulo fiduciário, atribuindo mão como módulo igual a quatro Mas se quisermos permitir que nosso código funcione com qualquer número de jogadores, seria melhor substituir quatro pelo tamanho da nossa matriz de mãos. Para ver onde estamos até agora, vamos imprimir nossas mãos iterando a matriz de mãos e imprimindo cada uma Em seguida, imprima o baralho. Podemos ver nossas quatro matrizes e o baralho está vazio Podemos até mudar o número de jogadores e as cartas serão distribuídas para o número correto de mãos. Nossa função pronta está ficando bem grande. Podemos organizar melhor nosso código declarando nossas próprias funções Separando nossa lógica em pequenos pedaços, temos uma seção que cria nosso baralho inicial de cartas, uma que cria as mãos do jogador e outra que distribui as cartas. Usando a palavra-chave funk, podemos dar a cada um desses blocos de código um nome seguido por parênteses Inicializou o baralho, inicializou as mãos e negociou. Então, a função ready pode chamar cada uma dessas funções em sequência. Nossas funções também podem aceitar argumentos, como o número de mãos que queremos ter. Vamos passar quatro como argumento. Para escrever nossa função para aceitar o argumento, precisamos adicionar um parâmetro correspondente dentro dos parênteses da declaração da Assim como declarar uma variável, ela tem um nome e, opcionalmente, também um Como estamos usando isso para redimensionar uma matriz, é uma boa ideia restringi-la a um número inteiro Podemos então usar o parâmetro dentro da função da mesma forma que usaríamos qualquer outra variável. A última coisa que precisamos fazer para começar a jogar seria remover todos os pares da mão de cada jogador. Então, iterando cada mão na matriz de mãos, podemos chamar outra função para remover os pares dessa mão, passando a mão como argumento Dando uma definição a essa função, podemos então aceitar uma mão como um parâmetro de matriz. Precisaremos iterar com a mão com uma variável. Vamos chamá-lo de cartão um. Mas podemos parar antes de chegarmos à última carta. Então, vamos apenas de zero até o tamanho da mão menos um Podemos então iterar uma segunda vez da mesma forma, mas desta vez, começar com a carta após a primeira carta e ir até o final do tamanho da mão Dentro desses 24 loops, carta um e a carta dois agora contêm cada par de cartas exclusivo em nossa mão, então podemos comparar facilmente as duas cartas para ver se elas combinam Se estiverem, eles podem ser removidos da mão, começando com a carta dois. Se removêssemos a carta um primeiro , o índice da carta dois realmente mudaria como resultado, já que todas as cartas se moveriam em uma posição. Se encontrarmos uma correspondência, não queremos continuar esse loop ou qualquer um deles. Mas queremos reiniciar todo o processo novamente. Uma maneira simples de fazer isso seria com um loop while, uma variável booleana para determinar se encontramos ou não um par com um valor padrão verdadeiro Embora um par tenha sido encontrado, podemos defini-lo imediatamente como falso. Isso nos permite entrar no loop, mas não ficar aqui, a menos que um par seja encontrado. Em outras linguagens, você pode fazer isso com um loop do Wile em vez disso Se encontrarmos um par, podemos definir a variável como verdadeira e, em seguida, sair dos dois loops, redefinindo o loop Wile Se os quatro loops concluídos sem encontrar um par correspondente, par encontrado será falso e o loop Wa será interrompido Podemos executar nossa simulação repetidamente e ver que nenhuma das mãos de nossos jogadores jamais conterá pares iguais, e os jogadores estão prontos para começar a jogar o velho jogo Mad Na próxima lição, usaremos outra forma de controle de fluxo. Te vejo na próxima aula. 8. Combinação e retorno: Olá, amigos. Hoje, usaremos outra forma de controle de fluxo para simplificar condições complexas. Eu já criei um script chamado months e substituí a definição dos nós básicos da função ready Vamos começar declarando uma variável para manter o mês atual e defini-la janeiro e uma segunda variável para manter o número de dias no mês, que será deixado como zero por padrão Podemos imprimir uma frase simples informando que o número de dias em janeiro é 31 Mas primeiro, queremos preencher nossa variável com o número de dias com base no valor do mês Então, vamos escrever uma função que pode fazer exatamente isso. Atribua o número de dias do mês a serem retornados de uma função que escreveremos, que aceitará o mês como argumento. Dando uma definição a essa função, aceitando o mês como um parâmetro do tipo string, ela também precisa de mais uma informação, um tipo de retorno. O tipo de valor retornado por uma função é definido após os parênteses com um hífen e um sinal maior, uma seta, seguido pelo Nesse caso, é um número inteiro, representando o número de dias no mês Se não especificarmos um tipo de retorno, o tipo de retorno para qualquer função que escrevermos será nulo por padrão Dentro de nossa função, precisamos retornar um número inteiro, o que significa que devemos declarar um inteiro no topo dela, e ele precisará conter o número de dias do mês Em seguida, na parte inferior da função, retornaremos o valor mantido nessa variável. Entre essas duas linhas, precisamos preencher nossa variável com o número correto de dias com base no mês Se o mês for janeiro, o número de dias será 31. Aprendemos anteriormente que podemos fornecer uma alternativa com a palavra-chave se, mas isso só nos fornece duas opções das 12 de que precisamos. Podemos usar outra palavra-chave, if, abreviação de if, para fornecer outra condição que será verificada se a condição original era falsa. Caso contrário, se o mês for fevereiro, o número de dias será 28. E podemos repetir isso quantas vezes precisarmos, fornecendo um caso para cada possibilidade. Mas muitas dessas opções têm o mesmo resultado, 30 dias ou 31 dias. Poderíamos melhorar consideravelmente a eficiência dessa declaração if combinando o resultado mais comum, 31 dias para ser o caso padrão, e substituindo todos eles uma única palavra-chave else no final Se o mês não for fevereiro ou qualquer mês com 30 dias , o número de dias deverá ser 31. Todos os casos resultantes em 30 dias também podem ser combinados em uma única declaração usando o operador or. Se o mês for setembro ou se o mês for abril ou se o mês for junho, ou se o mês for novembro, o número de dias será 30. Mas a declaração é bem longa. Com mais casos, ele pode sair da tela. Para declarações simples, caso a caso, como essa, há uma palavra-chave mais limpa e fácil de usar do que a instrução I chamada match. A correspondência é seguida pelo nome de uma variável, dois pontos e depois por um bloco de código recuado Dentro de um bloco de correspondência, podemos especificar qualquer número de casos específicos para o valor da variável. Vamos começar com fevereiro. O caso também é seguido por dois pontos e outro bloco de código recuado Esse código só será executado se o valor do mês for fevereiro. Podemos agrupar casos em uma lista separada por vírgulas. Portanto, nossa condição de declarações I pode ser reduzida para apenas uma lista de quatro meses Se o valor do mês for setembro, abril, junho ou novembro, o número de dias será definido como 30, e nosso bloco poderá ser substituído por um caractere curinga representado por um sublinhado, definindo o número de dias como 31 se o valor do mês não for especificado acima Isso é o mesmo que usar o padrão em outros idiomas. Cada um desses blocos de código é chamado de ramificações. E no script GD, uma instrução de correspondência só executará a ramificação superior cuja condição foi atendida cuja condição foi atendida Em outras linguagens, isso é semelhante a uma instrução switch, mas difere porque as instruções switch podem executar mais de uma ramificação se várias condições forem atendidas. Por causa dessa restrição, não há necessidade de incluir quebras nas ramificações da partida Se quiséssemos imprimir o número de dias em cada mês, provavelmente usaríamos um loop, mas não podemos simplesmente contar ou incrementar uma sequência de caracteres como janeiro para, de alguma forma, virar fevereiro Portanto, é comum no código, ao representar coisas que existem em uma ordem sequencial, colocá-las em uma lista numerada chamada Uma enumeração no script GD é apenas um grupo Portanto, podemos ter uma constante para janeiro com um valor de um, outra para fevereiro com um valor de dois, etc Mas usando a palavra-chave Enum, podemos nomear o grupo de constantes, vamos nomeá-lo em meses seguidos por Dentro das chaves, podemos agrupar as constantes e cada uma receberá um número automaticamente com base em sua posição nessa lista Qualquer coisa contida nas chaves não precisa ficar em uma linha e pode ser dividida em qualquer formato que você preferir para torná-la mais legível recuo não importa aqui, mas geralmente ao escrever algo entre colchetes, a maioria dos codificadores recua no conteúdo, então parece semelhante a então Embora eu prefira que as chaves sejam alinhadas verticalmente, muitos codificadores preferem colocar a chave de abertura na linha de declaração Assim como Constance, as entradas de enumeração são convencionalmente nomeadas em maiúsculas e minúsculas. Agora que temos uma enumeração, o mês pode ser restrito ao tipo dessa Também podemos atribuir a ele um valor a partir da enumeração, começando com seu nome, seguido por um ponto e, em seguida, pela entrada na lista O mês que está sendo anexado à saída da string não é mais uma string em si e deve ser convertido em uma string antes que possa ser anexado O argumento que está sendo passado para o número de dias não é mais uma string e agora é um mês, e podemos alterar nossa função para aceitar um mês como parâmetro também. Como mês agora é um mês, não uma string, precisaremos alterar nossas condições para que correspondam usando o nome da enumeração seguido por um ponto e, em seguida, as entradas na lista Mas quando imprimimos os resultados, vemos que, em vez de janeiro, nosso mês é escrito como o número zero. Embora o tipo de nossa variável seja um mês, que é uma enumeração, o valor real é tratado como um número inteiro, sua posição na Como janeiro é a primeira entrada, seu valor como número inteiro é zero Fevereiro seria um, etc. Isso nos permite modificar o valor do mês com aritmética simples, então janeiro mais um Se envolvermos esse código em um loop que se repete 12 vezes, podemos iterar todos os 12 meses com facilidade Mas que tal escrever o nome do mês como uma string? Poderíamos fazer isso de duas maneiras diferentes. Nosso tipo de enumeração tem uma propriedade chamada keys, que consiste em todas as nossas entradas como uma matriz de Se indexarmos essa matriz usando nossa variável inteira, ela nos dará o nome da entrada como uma string correspondente a esse número Mas seguindo a convenção de nomenclatura de maiúsculas e minúsculas de Upper Snake, talvez não queiramos imprimir o nome dessa poderíamos renomear todas as nossas chaves de Em vez disso, poderíamos renomear todas as nossas chaves de enumeração no caso Pascal ou declarar uma constante contendo a matriz de strings, mantendo todos os nomes dos nossos meses ou declarar uma constante contendo a matriz de strings, mantendo todos os nomes dos nossos meses em um formato mais apresentável. Em seguida, use o mês como um índice nessa matriz. Outra coisa que podemos fazer com as enumerações é definir manualmente os valores das entradas usando o operador de entradas usando o operador Digamos que queremos que janeiro seja um em vez de zero. O restante das entradas atualizará automaticamente seus valores para incrementar a partir de um, então fevereiro agora é dois Mas isso não corresponde mais aos índices constantes da matriz. Então, se quisermos usar isso para escrever o nome dos meses, precisaríamos adicionar uma entrada vazia para o índice zero ou subtrair uma do mês conforme ela está sendo usada para indexar a matriz Na próxima lição, aprenderemos mais sobre como o mecanismo usa e executa nossos scripts Te vejo na próxima aula. 9. Árvore de cenas e herança: Olá, amigos. Hoje, aprenderemos sobre como o mecanismo usa a árvore de cenas para executar nossos scripts. Ainda não anexei um script ao nó raiz da árvore de cena, mas, em vez disso, começaremos esta lição adicionando mais nós. Clique com o botão direito do mouse no nó raiz selecione adicionar nó filho, ainda é um nó normal. Podemos renomeá-lo para presidente e fingir que nossa árvore de cenas é a estrutura de uma empresa O nó presidente é indentado porque é filho do nó raiz da cena Com um nó selecionado, também podemos usar o atalho Controle A ou Comando A para adicionar outro nó filho Vamos nomear esse gerente de operações, e ele é recuado outro nível porque é filho do presidente Agora vamos anexar um novo script ao nó do presidente e nomeá-lo funcionário. Substituindo a definição dos nós básicos da função ready, podemos simplesmente imprimir o nome desse nó e anexar está pronto. Esse script pode ser anexado a mais de um nó. Vamos anexar o mesmo script ao nó do gerenciador de operações arrastando-o da guia do sistema de arquivos até a árvore da cena Em seguida, execute a cena para ver o que acontece. Podemos ver que o gerente de operações está pronto e, em seguida, o presidente está pronto. Os dois nós que têm o script anexado executam o script e, como eles têm nomes diferentes, a saída foi diferente. Também podemos ver que o gerente de operações estava pronto antes que o presidente estivesse pronto. Para entender o porquê, precisaremos adicionar mais funcionários. O gerente de operações supervisionará vários operadores Então, adicionarei outro nó filho ao gerente de operações e o chamarei de operador 1. Em seguida, anexe o script do funcionário. Podemos clicar com o botão direito do mouse em qualquer nó, exceto no nó raiz, e selecionar duplicado para criar uma cópia dele O nome das duplicatas incluirá automaticamente um número crescente, para que possamos ter o operador dois, três e quatro, etc Como o nó que duplicamos tinha um script anexado, as cópias criadas também têm o mesmo script anexado Como os operadores têm o mesmo nível de indentação e são todos filhos do gerente de operações, eles são chamados de irmãos, e os irmãos não podem Nossa empresa deve ter mais de um departamento, então vamos duplicar todo o departamento de operações duplicando o gerente de operações Todos os nós secundários também são duplicados. Como os operadores não são irmãos diretos, eles podem manter seus nomes originais Vamos renomear o gerente para gerente de marketing, e eles terão apenas dois profissionais de marketing trabalhando em sua equipe Os nódulos parentais também podem ser reduzidos para esconder seus filhos ou expandidos para mostrá-los. Todos os funcionários dessa empresa têm o mesmo script de funcionário anexado a eles. Então, vamos rodar a cena e ter uma ideia melhor da ordem em que os scripts serão executados. Podemos ver que o primeiro operador é o primeiro a ficar pronto, seguido por cada operador em sequência e, finalmente, pelo gerente de operações. O mesmo acontece com o departamento de marketing. Então, finalmente, o presidente da empresa é o último a estar pronto. Como Gadot está decidindo essa ordem de execução? O motor começa no topo da árvore de cena e desce, mas não considera que nenhum nó esteja pronto até que todos os seus filhos estejam prontos. Portanto, o presidente não está pronto porque o gerente de operações não está pronto. O gerente de operações não está pronto porque os operadores não estão prontos. Os operadores estão prontos em sequência, pois não têm filhos. Quando todos os operadores estiverem prontos, o gerente de operações estará pronto. Mas o presidente ainda não está pronto porque o presidente tem outro filho que não está pronto. O gerente de marketing não estava pronto até que todos os profissionais de marketing estivessem prontos e, finalmente, o presidente é o último a estar pronto Como o nó raiz não tem um script anexado, sua função pronta é a de um nó padrão, que está vazio. Além de prontas, existem outras funções do nó que podemos substituir para serem executadas posteriormente, depois que um nó estiver pronto O mais comum é o processo também precedido por um sublinhado O mecanismo fará o possível para executar a função de processo de cada nó na árvore da cena 60 vezes por segundo usando a taxa de quadros padrão do projeto. Portanto, o processo usa um parâmetro chamado Delta, que é um número de ponto flutuante para representar o número de segundos que passaram desde o quadro anterior. Então, na maioria das vezes, será um 60º, mas nem sempre. Não precisamos usar esse parâmetro para nada hoje, então podemos continuar com o nome desse parâmetro com um sublinhado, para que Gudo saiba que não precisamos usá-lo e não devemos nos preocupar Mas, para substituir a função do processo, ela deve ter o mesmo número e tipos de parâmetros Vamos pedir aos nossos funcionários que trabalhem em cada quadro, imprimindo uma declaração dizendo que seu nome anexado a funciona Nessa cena, vemos que todos os nossos funcionários estão trabalhando muito, escrevendo suas declarações impressas 60 vezes por segundo. Isso não é o mesmo que um loop infinito, pois o trabalho está realmente sendo feito da maneira pretendida e nada está quebrado. Vamos tornar isso um pouco mais fácil de entender , permitindo que cada funcionário faça apenas uma unidade de trabalho usando uma variável Ban que tenha feito um trabalho com um valor padrão de false. Na função de processo, se o funcionário não tiver feito nenhum trabalho , ele trabalhará e alterará o valor para verdadeiro. Um 60º de segundo depois, como a variável é verdadeira, eles não funcionarão mais. Mas se declararmos essa variável dentro da função de processo , ela existirá somente dentro da função de processo e somente para uma única iteração No próximo quadro, quando a função do processo é executada pela segunda vez, a variável é declarada novamente e ainda assume o padrão false. Então isso não terá efeito. Para que nossa variável persista, ela precisa existir fora do contexto da função do processo Então, vamos declará-lo fora da função sem qualquer recuo As variáveis declaradas aqui podem ser acessadas em qualquer lugar em todo o script. Esse conceito é chamado de escopo e é um dos principais motivos pelos quais usamos recuo em nossos scripts Assim, podemos ver quais variáveis existem dentro de qual escopo. Comandando a cena agora, podemos ver cada um de nossos funcionários declarar que está pronto para trabalhar Então, somente quando todos estiverem prontos, cada um fará uma unidade de trabalho, mas agora em uma ordem diferente. A ordem na qual os nós na árvore de cena executam suas funções de processo segue a ordem exata da árvore de cena de cima para baixo. Os pais não precisam esperar por seus filhos como se estivessem prontos. Talvez queiramos que todos os funcionários da nossa empresa sejam parecidos, mas não exatamente iguais. O trabalho de um gerente não é realmente o mesmo que o de um trabalhador. Podemos usar a herança para criar comportamentos diferentes para objetos semelhantes Da mesma forma, estamos escrevendo scripts que estendem o node, mas mudando a forma como eles se preparam e como são processados. Primeiro, precisamos dar a esse script um nome que possamos usar como referência, usando a palavra-chave nome da classe, seguido por um nome que descreva o comportamento do script, geralmente igual ao nome do script, mas escrito em maiúsculas em Pascal Agora que o motor sabe que se trata de um funcionário, vamos criar um novo script e nomear esse gerente. Mas em vez de herdar do nó, desta vez podemos herdar do funcionário Como nosso script de gerente estende os funcionários, tudo o que está escrito no script de funcionário ainda se aplicará a este. Mas podemos adicionar mais ou fazer alterações. Um gerente ainda é um funcionário, mas a forma como ele trabalha é diferente. Devemos substituir o script anexado aos nossos nós gerenciadores pelo novo script gerenciador. Vamos substituir a definição do funcionário sobre a função pronta Então, quando um gerente estiver pronto, ele não apenas dirá que está pronto, mas dirá que todo o departamento está pronto. Para que nossos dois gerentes possam gerar o nome de seus departamentos, eles precisarão de uma variável para manter o nome do departamento como uma string. Mas como podemos preencher essa variável para manter valores diferentes para departamentos diferentes Se prosseguirmos com nossa declaração de variável com a tag na exportação, essa variável se tornará acessível por outras partes do GadoEngine, ou seja, o painel do inspetor Para que uma variável seja exportada, ela deve ser declarada no nível do escopo do script Selecionando o gerente de operações e a árvore da cena, agora há um campo no painel do inspetor onde podemos atribuir à variável do departamento um valor de string Dessa forma, o gerente de operações e o gerente de marketing podem ter seu próprio valor para essa variável que podemos controlar facilmente. Executando a cena, podemos ver que os nós que têm o script do gerente anexado agora declaram que seu departamento está pronto, enquanto todos os outros funcionários usam a definição anterior no script do funcionário A função de processo no script do funcionário também é herdada pelos gerentes e é executada da mesma forma que antes Então, vamos mudar a função de processo do nosso gerente. Os gerentes dirão algo diferente. O Name plus gerencia os trabalhadores para fazerem seu trabalho. A variável has done work do script do funcionário também foi herdada e não precisa ser declarada aqui para ser usada Na verdade, não podemos declarar uma variável com esse nome, pois isso causaria um conflito com a variável herdada com o mesmo Vamos examinar a cena novamente e ver como nossos gerentes agora fazem seu trabalho de forma diferente dos outros funcionários. Na próxima lição, aprenderemos mais sobre o uso de nós na árvore de cenas e os princípios de design orientado a objetos. Te vejo na próxima aula. 10. Abstração e encapsulação: Olá, amigos. Hoje, exploraremos como escrever aulas que sejam mais fáceis de usar e entender. Imaginando um carro como nosso quadro de referência. Vamos criar dois nós em nossa cena, um motorista e um carro como filho do motorista. Em seguida, anexe um novo script a cada um com o mesmo nome. Os carros são máquinas muito complexas, e a maioria das pessoas que os dirigem não tem ideia de como eles realmente funcionam. Eles só sabem como operar o carro. Vamos começar no script do carro e dar a ele o nome de classe car e, em seguida, adicionar uma variável para o ano do carro como um número inteiro Outra para a marca do carro como corda, e outra para o modelo também como corda. Exportando tudo isso, configurarei meu carro para ser um Honda Civic 2007 Ao criar uma nova classe, não se esqueça de salvar o script antes de tentar usá-lo. No script do motorista, o motorista precisará de uma referência ao carro, que podemos armazenar em uma variável do tipo carro. Os nós podem acessar outros nós na árvore de cena, maioria das vezes seus filhos usando outra tag semelhante à exportação chamada de ready. Usando a tag on ready, podemos atribuir o valor da variável depois que o nó estiver pronto, que significa que todos os seus filhos também estão prontos, mas antes de chamar a função ready desse nó. Podemos atribuí-lo ao valor de retorno de uma função incorporada, Get node, que aceita um caminho de nó como parâmetro. Se especificarmos o nome do nó filho entre aspas, agora temos uma referência ao nó filho armazenado em uma variável e podemos acessar suas propriedades e funções, incluindo aquelas no script anexado Substituindo a definição da função pronta, podemos acessar o nó do carro e imprimir seu ano, marca e modelo A função ready é executada após as tags on ready. Existe um atalho para a função get node para facilitar isso, o cifrão, seguido pelo mesmo caminho do nó Vamos voltar para o script do carro e adicionar outra variável. Este especificando se o motor está funcionando ou não como um booleano Como motorista, sabemos se o motor está funcionando e temos controle sobre se o motor está funcionando ou não, pois podemos optar por ligar ou parar o motor usando a chave. Portanto, consideraríamos essa variável pública. Outra propriedade do nosso carro pode ser o número de cilindros no motor como um número inteiro, e vou atribuir a ele um valor de quatro Isso é algo que o motorista não precisa saber, não pode acessar facilmente e nunca deve ser autorizado a mudar. Portanto, ao contrário da variável pública, essa seria considerada privada, e podemos marcá-la como privada fazendo seu nome continue com um sublinhado No script do motorista, podemos definir o valor do motor ligado como verdadeiro colocando a chave na ignição e girando-a Mas primeiro, devemos apertar o pedal do freio. Vamos usar uma função para definir a pressão aplicada ao pedal do freio, que assumiremos que seja de até 20 kg de Então, para ligar nosso carro, provavelmente deveríamos ajustar a pressão do freio para algo em torno de 10 kg De volta ao script do carro, precisaremos definir essa função que define a pressão do freio Como o mecanismo está em uma variável, isso seria chamado de função pública, já que está sendo usado por outro script. Essa função aceitará um número de ponto flutuante como parâmetro que representa a quantidade de pressão aplicada ao pedal Mas o que o carro realmente faz quando aplicamos pressão no pedal do freio Do ponto de vista do motorista, o motorista escolhe aplicar uma certa quantidade de pressão no pedal sem nunca saber a posição exata Do ponto de vista do carro, a posição do pedal é o que está sendo medido e usado para parar o carro O carro usa a posição do pedal do freio para ajustar a quantidade de pressão aplicada às pinças que prendem as pastilhas de freio contra as rodas do carro, sem mencionar a complexidade dos freios antibloqueio Então, se estivéssemos realmente programando um carro real, precisaríamos escrever várias funções complexas aqui que convertam a simples ação do motorista aplicando pressão no pedal do freio na complexa mecânica de apertar Isso faz parte das funções internas do carro e nada que seja controlado ou acessível ao motorista por qualquer meio que não ou acessível ao motorista por qualquer meio seja aplicar pressão no pedal do freio Portanto, consideraríamos que essas funções são privadas, uma vez que devem ser usadas apenas pelo próprio carro. E podemos marcar nossas funções privadas usando um sublinhado em seus nomes Observe como isso é o mesmo que o processo e as funções prontas. A forma como o GD Script usa variáveis e funções privadas é mais parecida com a forma outras linguagens usam as protegidas pois são acessíveis aos herdeiros GDScript não aplica essas regras de privacidade No entanto, o GDScript não aplica essas regras de privacidade e os scripts ainda podem acessar Essas convenções existem apenas para facilitar uma melhor estrutura e design de classes Outra forma de usar comentários no GD Script é criar regiões de nossos scripts que estejam relacionadas, usando a palavra-chave region seguida pelo nome da região Podemos finalizar uma região usando a palavra-chave e a região. Então, vamos criar uma região pública e uma região privada em nosso roteiro de carro, separando o que deve ser acessível ao motorista e o que não deve Para simplificar, digamos que o motorista só precise ligar ou desligar o motor, aplicar pressão no acelerador, aplicar pressão no pedal do freio ou girar o volante O que realmente acontece dentro de qualquer dessas funções públicas é a mecânica interna do próprio carro. O motorista não precisa saber como nada disso funciona para operar o carro. Por exemplo, ao pressionar o acelerador, o que realmente acontece é que o carro abre uma válvula de entrada de ar no motor, deixando mais ar e oxigênio entrarem no Portanto, o carro precisa usar um sensor para medir a quantidade de fluxo de ar e a quantidade de oxigênio que agora está fluindo para o motor Em seguida, use isso para ajustar a quantidade de combustível que está sendo injetada nos cilindros do motor Todas essas funções são privadas, pois não precisamos saber o que elas realmente fazem para dirigir o carro. forma como nosso carro se move estaria na função de processo, e precisaremos de outra variável privada chamada fase para representar em qual das quatro fases cada cilindro está atualmente. Na função de processo do carro, se o motor estiver funcionando, podemos passar por cada um dos cilindros do Somando o cilindro e a fase, depois o módulo quatro, obtemos uma fase diferente para cada cilindro Combinando esse número, podemos dizer a cada cilindro que execute uma fase diferente, o curso de admissão, o curso compressão, o curso de combustão ou o curso de escape, cada um aceitando o cilindro como argumento Em seguida, aumente a fase e volte para zero quando atingir quatro. Cada uma dessas funções pode então controlar as válvulas de admissão, válvulas de escape, injetores de combustível e velas de ignição de cada A quantidade de força produzida pelos cursos de combustão de cada cilindro moveria o carro para frente enquanto as pastilhas de freio tentavam parar o carro e a posição do volante mudaria de direção posição do volante A posição do carro seria então movida pela direção, velocidade e tempo Delta. Não se preocupe se nada disso fizer sentido para você porque esse é exatamente o objetivo desta lição. Você não precisa entender isso. Como tudo isso está na região privada do roteiro, o motorista não precisa saber como isso funciona para dirigir o carro. Eles só precisam saber como usar a região pública do script. A separação entre público e privado impõe dois princípios importantes da programação orientada a objetos encapsulamento é a região pública, fornecendo acesso a variáveis ou funções públicas que são fáceis de usar e simples de entender, e a abstração é a região privada, ocultando os detalhes de sistemas ou mecânicos complexos que não precisam ser entendidos para serem entendidos para Você saberá se suas aulas seguem esses princípios se puder ocultar todo o conteúdo privado e ainda entender facilmente como ele deve ser usado. Assim, nosso motorista agora pode simular a condução do carro acessando apenas as regiões públicas do script do carro, desde pressionar o freio e ligar o motor até soltar o freio, pressionar o acelerador, girar o volante, acessando apenas as regiões públicas do script do carro, desde pressionar o freio e ligar o motor até soltar o freio, pressionar o acelerador, girar o volante, etc. Esses princípios não são importantes apenas para nossos próprios scripts, mas também nos permitem usar scripts escritos por outros desenvolvedores sem entender completamente como eles funcionam internamente Eles também tornam os scripts R mais flexíveis. Imagine se trocássemos nosso carro a gasolina por um carro elétrico Alguma coisa no script do motorista precisaria mudar? Somente o script do carro precisaria ser alterado para um script de carro elétrico, já que todas as variáveis e funções públicas ainda existiriam no script dos carros elétricos. Da mesma forma, também podemos alterar o script do motorista para um script de piloto automático, que só precisa receber um destino e será capaz de operar o carro automaticamente Na próxima lição, aprenderemos ainda mais sobre os princípios de design orientado a objetos. Te vejo na próxima aula. 11. Polimorfismo: Olá, amigos. Hoje abordaremos o último dos princípios de programação orientada a objetos, o polimorfismo Estendendo os conceitos de herança e abstração, podemos escrever classes que representam um conceito mais abstrato, uma coleção de classes mais específicas relacionadas Vamos usar animais como exemplo criando um script chamado animal que estende o nó, mas não precisamos anexar esse script a nenhum nó na árvore da cena. Aqui podemos dar ao script um nome de classe e, em seguida, definir propriedades e comportamentos que são comuns a todos os animais, como uma variável para manter o plural do animal como uma string e outra para o nome de um agrupamento desse E também vamos definir uma função para o animal se mover, comer ou falar. Embora possamos definir facilmente o plural de animal como animais, não há uma palavra para um grupo de animais Também não podemos definir como um animal se move ou come sem saber que tipo de animal ele é Portanto, os corpos dessas funções podem permanecer em branco. Mas podemos considerar que alguns comportamentos são comuns o suficiente para que tenham um padrão, como falar. Embora existam muitos mamíferos diferentes que fazem uma grande variedade de ruídos, a maioria dos animais não o faz, incluindo peixes A maioria das pessoas não os descreveria como falando. Portanto, ao dizer a qualquer animal aleatório que fale, podemos considerar que o comportamento padrão é o silêncio. Então, vamos adicionar alguns animais diferentes à nossa árvore de cenas, começando com um gato. Agora podemos usar a herança, como fizemos antes, para criar vários scripts de animais diferentes que herdam de animais Em seguida, substituiremos a função ready para dar às variáveis herdadas do animal um valor apropriado para um gato O plural seria gatos, e um grupo de gatos é chamado de Clouder As funções de comportamento também podem ser substituídas para mudar o comportamento de falar em silêncio para miar Os gatos andam sobre quatro patas para se movimentar, e eu direi que comem peixe. O conteúdo real dessas variáveis e funções não é relevante, mas o foco está em como elas são herdadas do conceito abstrato de animal para uma instância mais específica de gato Podemos repetir esse processo para criar muitos outros tipos diferentes de animais para adicionar à nossa árvore de cena, como um pássaro ou um peixe. E dando a cada um novo script herdado do animal, cada um pode fornecer seus próprios valores exclusivos para as variáveis e implementações das funções que O plural de pássaro é pássaros. Um grupo de pássaros é chamado de rebanho. Eles voam para se movimentar, comem minhocas e cantam para falar. Vou começar meu script fish copiando o conteúdo do script cat. E o plural de peixe é peixe Um grupo de peixes é chamado de cardume. Eles nadam para se movimentar. Eles comem algas, mas não falam. Portanto, ao omitir a função de fala, peixes usarão a definição herdada da escrita animal Até agora, tudo o que fizemos foi usar os princípios orientados a objetos que já conhecemos para herdar, abstrair e encapsular as propriedades e comportamentos Mas tudo isso nos permite usar o polimorfismo tratando todos os animais como se fossem iguais e intercambiáveis iguais e intercambiáveis Primeiro, vamos adicionar um script ao nó raiz da nossa cena e chamá-lo de Zoo, herdando do nó Nosso zoológico está cheio de animais diferentes, mas não importa o que esses animais realmente sejam. Substituindo a definição da função pronta para nosso zoológico, podemos facilmente percorrer nossa lista de animais e tratar todos eles como se fossem apenas animais Uma maneira rápida e fácil de armazenar todos os nossos animais em uma única variável, vamos chamá-la de animais, é usar uma função de node chamada Get children. Isso retorna uma matriz de nós, todos os nós filhos desse nó convenientemente organizados em uma matriz na mesma ordem da árvore de cena Como isso depende das crianças, devemos usar a etiqueta em on ready Como sabemos que todos os animais têm as mesmas propriedades e comportamentos, podemos analisar cada animal em nossa variedade de animais e fazer com que cada um fale E apesar de tratar todos eles como animais, cada um falará de uma maneira única, conforme definido por seus próprios scripts específicos, ou usará a definição herdada de animal se não tiver a sua própria Podemos criar quantos níveis de herança quisermos Então, vamos criar outro script abstrato para mamíferos, herdado mamíferos são uma subcategoria de animais, incluindo todos os animais que têm glândulas mamárias e as usam para Essas são propriedades e comportamentos únicos dos mamíferos que não se aplicam a outros Assim, podemos adicionar uma nova variável ao script dos mamíferos para o número de glândulas mamárias que esse animal tem e escrever uma nova função chamada Novamente, o conteúdo das funções não é relevante para esta lição. Esse script também precisará de um nome de classe para ser herdado Passando para o script do gato, já que gatos são mamíferos, podemos atribuir ao número de glândulas mamárias um valor para gatos, que deve ser oito E também podemos adicionar novos mamíferos ao nosso zoológico, como um Os macacos também são mamíferos, mas só têm dois Mais uma vez, copiarei o conteúdo de outro script para tornar as coisas mais rápidas. O plural de macaco é macacos. Um grupo de macacos é chamado de tropa. Eles se movem subindo em árvores. Eles comem bananas, e eu vou dizer que eles dizem oh. Nosso script Zoo agora pode aproveitar essa nova estrutura de herança para aplicar condições exclusivas especificamente para aplicar condições exclusivas especificamente animais que são Podemos usar diretamente nomes de classes em declarações condicionais para dizer que, se o animal atual for um mamífero, executaremos algum código extra exclusivamente para Vou imprimir algumas linhas extras descrevendo nossos mamíferos E podemos ver que nossa produção é consistente para todos os animais, mas também tem algo único específico para os dois mamíferos Você pode imaginar como poderíamos mudar nossa lista de animais em nosso zoológico para qualquer tipo diferente de animal, e poderíamos alterar nossa estrutura de herança para categorizá-los com a precisão necessária Na próxima lição, aprenderemos sobre outra coleta de dados que podemos usar para agrupar informações relacionadas. Te vejo na próxima aula. 12. Dicionário: Olá, amigos. Hoje, usaremos uma alternativa à matriz que às vezes é usada como uma classe sem nenhuma função chamada dicionário. Imagine uma fileira de armários como você encontraria em uma escola secundária ou em um ginásio Se declararmos uma matriz de variáveis, podemos considerar que o índice da matriz de cada uma é o número dos armários Digamos que haja dez armários e possamos acessar cada armário individual para colocar algo dentro, começando no armário zero, começando no armário zero, um e O que colocamos dentro de cada armário não importa. Pode ser um inteiro, flutuante, string, booleano, nulo ou uma instância de uma classe E podemos imprimir o conteúdo dos armários para vê-los. Agora imagine que, quando colocamos algo em um dos armários, não apenas fechamos a porta do armário, mas também colocamos uma trava nela Esse cadeado requer uma combinação de números de três dígitos para Anteriormente, se quiséssemos recuperar o conteúdo do armário, precisávamos apenas saber o número dos armários, ir até ele e retirar o Agora podemos ignorar o número dos armários e, em vez disso, precisamos saber a combinação para abrir o cadeado Digamos que a combinação seja 149. Como uma matriz, atribuir algo ao número 149 significaria que a matriz teria que ter 150 Se mudássemos o tipo de nossa matriz para um dicionário, isso ainda funcionaria, exceto que não precisamos definir um tamanho para o dicionário antes de podermos acessar seu conteúdo. Observe como a saída mudou. dicionários são representados por chaves em vez de colchetes, e cada entrada é um número representando uma chave seguida por um valor do que está contido no armário trancado por essa Também não há entradas no dicionário para nenhuma chave à qual não tenha sido atribuído um valor. Como dicionário, esse número não é um índice ou endereço. É uma chave que usamos para abrir uma fechadura. E assim como o conteúdo do armário pode ser de qualquer tipo de dados, as chaves que usamos para bloqueá-lo também podem ser qualquer tipo de dados com apenas uma restrição Cada chave deve ser exclusiva. Caso contrário, não conseguiremos encontrar o armário que corresponda à chave Então, vamos tentar trancar um armário com um tipo diferente de fechadura, que usa letras em vez de números Portanto, a chave dessa entrada do dicionário é uma string, mas seu valor é um número. O oposto completo desse armário, cuja chave é um número e o valor é uma string Vamos trancar o próximo armário com uma trava giratória, que requer três números para desbloqueá-lo, que poderíamos armazenar em uma matriz Portanto, nossa chave de entradas do dicionário é uma matriz representada por colchetes contendo uma lista separada por vírgula de três Talvez esse número de bloqueio inclua um ponto decimal, então a chave é um flutuador E, de alguma forma, esse armário está trancado pela fotossensibilidade e só pode ser aberto se as luzes estiverem apagadas Portanto, sua chave é um booleano. Podemos até usar classes personalizadas como nossas chaves ou valores nos dicionários Vamos escrever uma nova classe para chave, que não precisará ser herdada de nada, pois não será anexada a um nó nem herdada Nossa classe chave precisa de um nome de classe e temos uma variável que descreve seus dentes. A implementação dessa classe não é relevante, mas podemos fingir que é uma chave De volta ao script do locker, podemos armazenar uma instância da nossa chave em uma variável Vamos chamá-la de key one do tipo key atribuindo-a ao nome da classe da chave Nunu cria uma nova chave, que é atribuída à nossa variável Agora podemos usar essa chave para criar uma entrada no dicionário. Também podemos criar mais chaves para criar mais entradas. Como cada chave que criamos é considerada única. A saída agora exibe as teclas como contagem de recifes seguida por um número longo Os nomes que usamos em outras classes foram herdados do node Mas como a chave não herda do node, ela não tem um nome Ref count é a abreviação de objeto contado por referência e é a classe base para o script GD Se escrevermos qualquer classe que não herde de nada, ela herdará da contagem de recifes e receberá um número longo aleatório Podemos ignorar isso e entender que nossas chaves são objetos com contagem de referência, o que significa que Gadot acompanha automaticamente cada instância única de cada objeto que criamos Mas o que queremos guardar nos armários? Assim como as matrizes podem conter outras matrizes, os dicionários também podem conter outros dicionários Combinando a forma como os dicionários são impressos, podemos criar nossos próprios dicionários rapidamente usando chaves Cada entrada começa com uma chave seguida por dois pontos e, em seguida, o valor que corresponde a essa chave uso comum de dicionários não é criar algo parecido com esse cenário de armário, mas sim criar algo mais parecido Embora sem nenhuma função, apenas variáveis. Digamos que esse armário contenha um brinquedo de pelúcia, que representaremos com um E este brinquedo de pelúcia pertence a um conjunto de brinquedos de pelúcia colecionáveis que são semelhantes, mas variados à sua maneira Cada um dos brinquedos de pelúcia é um tipo diferente de animal com uma cor e um nome Cada uma delas pode ser uma chave no dicionário. Digamos que esse armário contenha Bruno, o urso pardo. E o próximo armário contém Arthur, o Bode Branco. Podemos ver nosso dicionário de brinquedos de pelúcia dentro do dicionário de armários Acontece que a cor também é uma classe já definida em Gadot Então, em vez de armazenar nossas cores como strings, elas podem ser armazenadas como cores usando a cor do nome da classe Como você pode ver, há muitas cores predefinidas para usarmos, e podemos dizer pela forma como elas são nomeadas em maiúsculas e minúsculas, que essas são constantes da classe de Poderíamos até mesmo dizer isso e fingir que os brinquedos de pelúcia contêm uma etiqueta NFC ou de comunicação de campo próximo, tornando-os a chave para acessar o armário E podemos colocar o que quisermos dentro do armário como antes, incluindo outro pelúcia Vamos fazer outro brinquedo de pelúcia para guardar dentro do armário, que é destrancado usando Arthur como Desta vez, é fofa, o elefante cinza. Então, imaginando esse cenário, há um leitor NFC perto dos armários e seguramos um pelúcia com uma etiqueta NFC dentro, algo parecido com o que você pode encontrar em uma algo parecido com o que você pode Se segurarmos o brinquedo de pelúcia contra o leitor, precisamos verificar qual armário combina com o brinquedo de pelúcia e desbloqueá-lo, se houver algum armário Mas se tentarmos acessar uma chave em um dicionário à qual não foi atribuído um valor, causaremos um erro. Da mesma forma que faríamos se tentássemos acessar um índice de matriz fora do intervalo. Podemos verificar se um dicionário contém uma entrada correspondente a uma chave específica usando a função has e, em seguida, passando a chave como parâmetro. Isso nos permite verificar se existe uma entrada no dicionário antes de tentar acessar seu valor, evitando o erro. Se o dicionário não tiver a chave, imprimirei uma mensagem diferente. Em vez de definir o mesmo dicionário duas vezes, seria melhor armazenar em uma variável e usar a variável duas vezes. Na próxima lição, exploraremos algumas técnicas diferentes que você pode usar quando tiver dificuldades ou precisar de mais informações. Te vejo na próxima aula. 13. Depuração: Olá, amigos. Hoje, abordaremos algumas estratégias diferentes que você pode usar para ajudá-lo quando inevitavelmente ficar preso Eu já anexei um script ao nó raiz da cena chamado debug Você provavelmente já percebeu o recurso de preenchimento automático que está disponível se você especificar o tipo de suas variáveis Isso não só permite que você veja todas as propriedades e funções da classe, mas depois de selecionar uma função, você também pode ver os tipos de todos os parâmetros da função para que você possa fornecer argumentos correspondentes. , quando você conhece os tipos de todas as suas variáveis, isso torna os erros de incompatibilidade claramente aparentes, e você será avisado do erro sem precisar executá-lo Sem tipos rígidos, o motor não sabe o que é incompatível até tentar executar a linha Se você quiser navegar por uma classe embutida, como a cor, podemos acessar facilmente as informações clicando em qualquer um dos botões no canto superior direito do painel. Online Docs abre uma guia em seu navegador padrão para a API GADO correspondente à versão do editor que você está usando Aqui você encontrará informações básicas sobre GADO, dicas para começar, tutoriais detalhados sobre o básico, links da comunidade onde você pode encontrar recursos adicionais e uma referência completa Como você pode ver, há muitas aulas. E selecionando qualquer um deles, podemos ver do que eles herdam e por quais outras classes eles são herdados Cada um tem uma descrição do que faz. Links para tutoriais sobre como usá-lo, uma lista de propriedades e métodos Quando falamos sobre classes, tendemos a nos referir às variáveis como propriedades e às funções como métodos. Também existem sinais, algo que Gadot usa para comunicação automática entre nós, enumerações e constantes, como Todos eles têm suas próprias subseções e descrições de como usá-los. De volta ao Editor do GDA, a pesquisa Ajuda abre uma janela no GDA onde você pode ver uma lista de todas as classes Ao selecionar uma turma, podemos ver todas as mesmas informações disponíveis no site do GDA em nosso editor, para que possamos acessá-las offline Voltando ao nosso script, podemos até acessar essas informações mais facilidade mantendo pressionada a tecla de controle ou comando do que clicando no nome de uma classe, levando-nos diretamente às informações de referência dessa classe. O mesmo pode ser feito para funções e variáveis específicas. Clicar neles não apenas abre a página de referência da classe, mas também nos leva à função ou variável em que clicamos Também existem funções globais que podemos usar, principalmente para realizar operações matemáticas como clamp, por exemplo Se usarmos essa função, podemos ver os parâmetros que ela espera e podemos usá-la para fixar nossa variável em 0-1 Segurar a tecla de controle ou comando e clicar no nome da função global nos permitirá acessar a referência dessa função, completa com uma descrição e como usá-la. Todos eles estão contidos na classe de escopo global. Ok, vou adicionar outra variável e outra linha ao meu script. Se executarmos nossa cena, podemos ver a árvore de cenas da simulação em execução por meio do painel de cena clicando no botão remoto Essa não é a mesma árvore de cena na guia local que criamos para definir a cena, como uma planta Essa árvore de cena é aquela que foi construída pelo motor para executar a cena. Selecionando qualquer nó, podemos ver suas propriedades no inspetor e podemos ver que a função ready já foi executada, pois as cores têm valores diferentes Também podemos alterar os valores de qualquer uma dessas propriedades. Também podemos usar a impressão para imprimir sempre que quisermos ver o que nossas variáveis contêm a qualquer momento. E ajuda ser o descritivo possível com suas declarações impressas, para que não haja confusão sobre a origem delas Mas se mudarmos as coisas e usarmos a função de processo, mudarei a cor gradualmente ao longo do tempo adicionarei uma declaração impressa aqui. Como essa função de processo é executada 60 vezes por segundo, o valor das instruções de impressão como ferramenta de depuração é bastante reduzido, pois o registro de saída simplesmente repetirá a mesma mensagem mais rápido do que podemos lê-la ou reagir a Podemos pausar a simulação enquanto ela está sendo executada usando o botão de pausa ou pressionando F sete Isso nos permite ver a árvore da cena remota como ela está neste momento e revisar o conteúdo do painel de saída com a simulação pausada Mas isso ainda não é muito útil, pois vários quadros serão concluídos entre o momento em que a simulação começa e quando podemos pausá-la Se clicarmos à esquerda de qualquer linha de código, podemos adicionar um ponto de interrupção automático indicado com um círculo vermelho Quando executamos a cena atual, a simulação será pausada quando atingir essa linha antes de executá-la . Isso é muito mais útil se quisermos ver nossa simulação ser executada um quadro por vez. Agora podemos ver como a cor de cada quadro muda gradualmente de um quadro para o outro. Vamos fazer com que nossa função de processo chame outra função para realizar uma tarefa simples. Vou mudar a cor gradualmente, reduzindo seu valor de vermelho. Então, agora devemos ver a cor mudar gradualmente a cada quadro, ficando menos vermelho e mais azul. Com o ponto de interrupção ainda na primeira linha da função de processo, vou executar a cena Ele para aqui e podemos ver que a próxima linha de código a ser executada é indicada com um triângulo amarelo. Enquanto a simulação é pausada dessa forma, podemos pedir que ela execute apenas uma única linha de código por vez, em vez de um quadro inteiro, selecionando avançar menu Depurar ou usando o atalho F ten Isso executará apenas a linha de código apontada pelo triângulo amarelo e, em seguida, fará uma pausa novamente. Assim, podemos ver as alterações feitas apenas por essa única linha de código e podemos ver o triângulo amarelo apontar para a próxima linha esperando para ser executada. Podemos continuar executando nosso script linha por linha se continuarmos avançando até que a função do processo termine e o quadro seja concluído, retornando ao topo da função do processo para ser executado pela segunda vez Agora podemos observar cada alteração individual na cor à medida seu valor de azul aumenta separadamente de quando o valor de vermelho diminui, mesmo que elas ocorram durante o mesmo quadro. No caso de chamadas de função, há outra opção para entrar na função. Se selecionarmos essa opção ou usarmos o atalho F 11, a seta amarela entrará na função que está sendo chamada e executará essa linha por vez até sua conclusão Quando a função estiver concluída, a seta amarela retornará à função original para continuar executando aquela Usando essas ferramentas, temos uma visão muito focada do que nossas aulas estão fazendo e quando, como elas estão se comportando, e podemos observá-las em câmera lenta o quanto precisarmos para descobrir o que está errado em qual momento específico Se você não consegue resolver um problema sozinho, a comunidade GDA é muito prestativa e está sempre disposta a Existem servidores Discord para desenvolvedores do GoDo, incluindo meu servidor, onde meus alunos se ajudam mutuamente O link para participar está no meu perfil. Também existem fóruns on-line em sites como o Redit, onde você também pode fazer perguntas. Agora você tem uma compreensão básica da maior parte da sintaxe do GDScript e das ferramentas necessárias para explorar mais esses conceitos Quando estiver pronto, peça um código de desconto para qualquer um dos meus cursos de projetos de jogos, boa sorte. 14. Configuração: Olá amigos. Se você ainda não fez isso, você precisará baixar o GDOGameEngine Gudo Em seguida, extraia o conteúdo da pasta compactada. Certifique-se de colocar essa pasta descompactada em algum lugar seguro no seu Abra o Gudo quando estiver pronto. Espero que você tenha concluído a série de introdução à programação, para ter uma compreensão básica do editor e de como escrever scripts Clique no botão de adição Criar para criar um novo projeto. Nosso objetivo neste curso é criar um jogo inteiro usando somente nós de interface de usuário em uma única cena. Você pode nomear seu projeto como quiser, como curso de interface de usuário, jogo de interface de usuário sem nome ou, se tiver um nome para seu jogo, pode usá-lo aqui Godot criará automaticamente uma nova pasta para seu projeto em documentos, ou você pode clicar em Procurar para alterar o local Gosto de ter todos os meus GDObjects em uma Este projeto não envolverá nenhuma renderização complexa, então o renderizador não importará, mas usarei a compatibilidade para poder exportar para a Web E o GODO fornece suporte para controle de versão por padrão, o que é muito útil, e eu recomendo aprender a usá-lo em seus projetos Como nosso jogo deve conter apenas uma única cena usando nós de interface de usuário, vamos começar criando nosso nó raiz como interface de usuário. Todos os nós da interface do usuário têm ícones verdes para torná-los facilmente identificáveis na árvore da cena Podemos renomear nossos nós clicando neles depois de já terem sido selecionados ou clicando com o botão direito do mouse neles e selecionando já terem sido selecionados ou clicando com o botão direito renomear Vamos nomear essa tela de título do nó. Em seguida, salve essa cena em nosso projeto por meio da cena do menu principal, salve a cena ou usando o atalho Control S ou Command S. Apesar do fato de o nó raiz ser chamado de tela de título, pretendemos fazer todo o jogo em uma cena Um nome comum usado neste caso para a cena seria principal, então é isso que vou chamar de Mcene E com apenas uma cena, podemos simplesmente deixá-la na pasta de recursos do projeto. Se você não tiver certeza do que quero dizer com nós de interface de usuário, selecione o nó raiz do projeto. Em seguida, dê uma olhada em suas propriedades no inspetor, expanda a seção do tema, clique na seta para baixo ao lado do tema selecione o novo tema Essa cena agora tem um tema que mudará a forma como todos os seus nós de controle são exibidos. Clique no novo tema para abri-lo no painel inferior. Expandindo esse painel para obter uma visão melhor de todo o seu conteúdo, podemos ver uma grande variedade de nós de interface de usuário visualizados Botões de rótulos de vários tipos, texto editável, números e controles deslizantes, separadores, uma barra de progresso, guias, uma árvore e uma barra de rolagem, todos contidos em um painel e vários contêineres usados para Alguns nós de controle não estão incluídos aqui, incluindo um que pode ser usado para exibir duas texturas D. Se você ainda não escolheu um jogo para seu projeto, tente criar algo que você possa tentar criar usando apenas esses componentes. Agora estamos prontos para começar nosso novo projeto de jogo. Na próxima seção, criaremos uma tela de título básica para nosso jogo. Nos vemos na próxima seção. 15. Etiqueta A: Olá, amigos. Com nosso projeto iniciado, começaremos nosso jogo com uma tela de título básica. A coisa mais básica que precisamos para uma tela de título para nosso jogo seria o título. Vamos começar adicionando um novo nó à árvore da cena clicando no botão de adição, clicando com o botão direito do mouse no nó raiz e selecionando adicionar filho ou usando o atalho Controle A ou Comando A. Para concluir o desafio de usar somente nós da interface do usuário, usaremos somente os nós que estão classificados sob Esse controle também é do mesmo tipo do nó raiz da cena. Podemos ver na descrição que o controle é a classe base para todos os controles gráficos da interface do usuário. Esses nós adaptarão suas posições e tamanhos com base nos nós de controle principais. O controle mais usado para exibir texto tem o nome de rótulo indicado com um ícone de tag. Também podemos ver a herança da classe label, pois cada tipo de nó é recuado abaixo do tipo do qual ele herda Qualquer nó ou classe que herda de outro terá todas as mesmas propriedades herdadas, além de suas próprias propriedades extras Portanto, o nó do rótulo é um nó, mas também é um item de tela, um nó de controle e um rótulo. Cada um deles vem com suas próprias propriedades e comportamentos. Podemos ver que o nó do rótulo está recuado abaixo do nó raiz , pois é filho dele O nó raiz é o pai do rótulo, então o rótulo ajustará sua posição e tamanho com base no nó pai. Veremos o que isso significa em breve. Vamos renomear o nó do rótulo para título e dar uma olhada em suas propriedades no inspetor A primeira propriedade é o texto que o rótulo exibirá. Então, podemos inserir o título do jogo aqui. Há também várias opções para controlar o alinhamento do texto, a quebra, a justificação, a separação de parágrafos, o recorte, elipses Nenhuma delas é realmente aplicável ao nosso título, exceto talvez em maiúsculas, se você preferir transformar todas as letras minúsculas em maiúsculas As propriedades abaixo do texto exibido são aplicáveis somente situações em que há muito texto para exibir tudo de uma vez. E as opções de BD estão disponíveis para idiomas que são exibidos direita para a esquerda em vez da esquerda para a direita. Nada disso é importante para o título do nosso jogo. Vamos pressionar Play e ver nosso título exibido. Como nenhuma cena foi selecionada para a cena principal deste projeto, somos solicitados a configurá-la Pressione selecionar atual para definir essa cena como a cena principal do jogo, e podemos ver nosso jogo rodar, exibindo o título no canto superior esquerdo da janela. Pressione o botão de parada para finalizar esta simulação. Isso funciona, mas não é muito bom. Provavelmente queremos mover o título e aumentar seu tamanho. Examinando mais detalhadamente as propriedades do nó do rótulo, essas são todas as propriedades do próprio nó do rótulo, mas há mais seções de propriedades se rolarmos para baixo. A próxima seção contém todas as propriedades que o nó do rótulo herda do controle Se expandirmos a seção de layout e, seguida, a seção de transformação, podemos ver as propriedades de tamanho e posição do nó do rótulo. Se você não conseguir ver esse retângulo nas duas visualizações D, ajuste-o até poder usar a roda do mouse para deslocar e ampliar Esse retângulo azul é a área de exibição do jogo, pois será renderizado quando executarmos o Observe como o eixo X vermelho se sobrepõe à parte superior do retângulo azul, fazendo com à parte superior do retângulo azul que O eixo Y verde se sobrepõe ao lado esquerdo, tornando-o ciano, e o ponto de origem da cena está no canto superior Se clicarmos e arrastarmos o título para fora do canto superior esquerdo, seus valores de posição X e Y no inspetor serão atualizados para refletir sua nova posição Observe como mover a etiqueta para baixo aumenta a posição Y e movê-la para cima a diminui. Vamos colocar o título em algum lugar no centro da tela. Em seguida, pressione o botão play para ver a alteração. O título agora é exibido no centro da tela. Mas o que acontece se redimensionarmos a janela? A posição do título é determinada pela distância do canto superior esquerdo da janela. Portanto, se o tornarmos maior ou menor, o título não estará mais no centro da janela. Pressione o botão de reset para retornar a etiqueta à origem, posição 00. Você provavelmente notou o X verde na origem ao selecionar o nó do rótulo. São quatro âncoras, todas apontando para a mesma posição Vamos mudar o modo de layout do nó da etiqueta de posição para âncoras. Isso adiciona outra propriedade chamada predefinições de âncora, que podemos alterar Se alterarmos as predefinições de âncora para destruição total, isso é o mesmo que o nó raiz com uma âncora com uma âncora Se selecionarmos o nó raiz, todas as âncoras apontarão para cantos diferentes da tela R selecione o nó do rótulo. O restante das opções ancorará a etiqueta em diferentes locais na tela nos cantos centralizados ou esticados em um eixo ao longo Vamos ancorar o título no centro da tela. Agora, se clicarmos em Reproduzir e redimensionarmos a janela, o título permanecerá centralizado mesmo que o tamanho da tela mude Também pode personalizar como essas âncoras afetam o nó alterando as predefinições de âncora Isso nos permite alterar os pontos de ancoragem, definindo-os como porcentagens da largura ou altura da tela Como as âncoras são exibidas apontando para os cantos, cada uma dessas configurações de ponto de ancoragem afetará duas âncoras afetará duas Eu estou bem em manter o título centralizado horizontalmente, mas eu preferiria que ele fosse movido um pouco para cima para cerca de um terço da tela Ajustando o ponto de ancoragem superior para um terço, as âncoras superior esquerda e superior direita se movem para cima. Também definirei o ponto de ancoragem inferior em um terço, para que todas as âncoras apontem para a mesma posição E os deslocamentos de âncora podem ser usados para deslocar posição do nó do ponto de ancoragem Isso pode fazer com que o tamanho do nó seja maior que o texto e, portanto, a propriedade de alinhamento do rótulo afetará onde ele é desenhado Estou bem em ter a etiqueta centralizada no ponto de ancoragem, então vou redefinir todos os meus deslocamentos de âncora A direção de crescimento afetará a forma como o nó é reposicionado em relação ao ponto de ancoragem com base em seu tamanho Se for instruído a crescer para a esquerda ou para a direita, para cima ou para baixo, podemos ver como o nó é redimensionado e reposicionado para acomodar o texto Um título de jogo geralmente tem uma fonte e um tamanho de fonte exclusivos de qualquer outra coisa no projeto. Em casos como esses, podemos ignorar o tema que criamos na primeira lição e, em vez disso, expandir a seção de substituição do tema das propriedades de controle Antes de alterarmos a fonte, precisamos importar uma fonte para o projeto. Eu baixei essa fonte do Google Fonts. Podemos importar arquivos para o projeto arrastando-os para a janela do Godot Editor Agora podemos definir isso como a fonte do título. Também podemos alterar o tamanho da fonte. Vou definir o meu para 49. Os estilos geralmente não são usados para rótulos, mas, para demonstrar, podemos adicionar uma caixa de estilo plana para adicionar uma cor de fundo à fonte. Clicar na caixa de estilo nos permite alterar a cor entre muitas outras opções. Como eu disse antes, isso não é realmente algo que é usado com frequência para etiquetas, e examinaremos as caixas de estilo com mais detalhes em breve. Vou remover a caixa de estilo da minha etiqueta de título clicando no botão de redefinição. Em vez disso, adicionarei substituições de tema para a cor da fonte, cor da sombra e cor do contorno, tornando a fonte branca e a Em seguida, adicione constantes para os deslocamentos de sombra, e tamanho do contorno da sombra Como o título tem apenas uma linha, o espaçamento entre linhas não teria efeito Conforme mencionado anteriormente, os nós de controle dos pais afetam o tamanho e a posição de seus filhos. Como vimos anteriormente, o nó da tela de título está ancorado em todo o retângulo da área de exibição Mas se o redimensionarmos, seus filhos recalcularão seus tamanhos e posições de acordo com o tamanho e a posição Nesse caso, o título permanece centralizado horizontalmente e a um terço da parte superior da área da tela de título Podemos redefinir isso do jeito que era redefinindo as âncoras da tela de título Agora temos o título do nosso jogo exibido na tela de título. Na próxima lição, adicionaremos um plano de fundo. Te vejo na próxima aula. 16. Etiqueta B: Olá, amigos. Antes de passar para as texturas, podemos explorar um pouco mais do que os rótulos têm a oferecer Nenhuma das alterações feitas nesta lição será segura para o projeto, e vou voltar ao final da lição anterior antes de continuar Qualquer vídeo intitulado B seguirá essa regra, fornecendo apenas informações extras sobre o tópico anterior, mas pode ser ignorado Ao selecionar o nó do rótulo, temos uma propriedade chamada configurações do rótulo. Assim como o recurso temático da primeira lição, podemos criar um novo recurso de configuração de rótulo aqui, mas isso afetará somente esse rótulo. Ao criar esse recurso de configurações de rótulos, ignoraremos as substituições do tema e usaremos essas configurações Aqui, podemos alterar todas as mesmas configurações disponíveis no tema, espaçamento, fonte, tamanho da fonte, cor, cor, contorno e sombra Vamos adicionar uma segunda linha de texto ao título. Se, por algum motivo, o tamanho de um nó de etiqueta for maior que o texto, as propriedades de alinhamento determinarão onde o texto será desenhado, seja à esquerda, no centro, à direita ou preenchendo toda a largura, superior, inferior, etc Se o texto for muito longo para caber na largura designada do nó do rótulo, podemos usar o modo Auto rap para alterar a forma como o texto é movido automaticamente para a próxima linha. arbitrário simplesmente cortará qualquer caractere esteja no final da largura da etiqueta O Word tentará quebrar os espaços entre as palavras, e o Word Smart quebrará uma palavra se ela não couber em uma única linha. Se o significado de alguma propriedade não for óbvio e você quiser uma explicação mais detalhada, passar o mouse sobre o nome da propriedade fornecerá uma dica de ferramenta Vou usar um pouco de Lormipsum como texto reservado para explicar as próximas configurações sinalizadores de justificação podem ser usados para alterar a forma como o alinhamento do texto de preenchimento é implementado A partir da versão 4.4 do Gudo, você poderá alterar o novo caractere de linha para o que quiser texto do clipe pode ser usado para evitar que qualquer texto seja desenhado fora dos limites do nó do rótulo. Se o texto do clipe estiver ativado, comportamento de sobrecarga de texto poderá ser alterado para alterar a forma como o recorte é implementado Cortando caracteres ou palavras, até mesmo adicionando elipses para substituir caracteres ou palavras. O caractere de elipse também pode ser alterado também pode ser Normalmente, os caracteres de tabulação na área de texto são ignorados quando o rótulo renderiza o texto, mas você também pode adicionar paradas de tabulação aos seus rótulos Clicando na matriz packed float 32 para expandi-la. Clique no botão de adição de elemento adicional para adicionar uma parada de tabulação. Em seguida, defina o valor como um número decimal. Várias paradas de tabulação podem ser usadas para criar gráficos ou colunas dentro do nó do rótulo. Voltando ao orm Ipsum para ajudar a demonstrar o texto exibido, se tivermos uma grande quantidade de texto em um nó de rótulo, poderemos personalizar a quantidade de texto desenhada usando essas propriedades As linhas ignoradas ocultarão as linhas de texto começando pelo início, enquanto o máximo de linhas visíveis ocultará as linhas de texto começando pelo final Um negativo é usado para significar ilimitado neste contexto. Caracteres visíveis podem ser usados para controlar o número exato de caracteres que serão desenhados. Isso está diretamente ligado à propriedade de proporção visível, que é a mesma coisa, mas expressa como uma porcentagem do texto inteiro. Alterar um valor mudará o outro automaticamente. Se a visibilidade de caracteres e a quebra de palavras estiverem sendo usadas, forma como a quebra de palavras é implementada poderá ser alterada usando o comportamento visível de caracteres Por exemplo, essa palavra não caberia na primeira linha se estivesse toda desenhada, mas cabe somente por causa do número de caracteres visíveis. Alterando o comportamento dos caracteres visíveis para caracteres após a formatação, a palavra é quebrada na segunda linha independentemente de estar ou não completamente visível As configurações de layout de glifo são usadas somente se a direção do layout estiver definida da direita para a esquerda, e as configurações de BD são para idiomas escritos especificamente da direita para a Agora vou reverter o projeto para o que era antes desta aula Essas são todas as opções de etiquetas. Na próxima lição, passaremos para a textura Rx. Te vejo na próxima aula. 17. Textura direta: Olá, amigos. Na lição anterior, adicionamos um título à nossa tela de título. Nesta lição, adicionaremos uma imagem de fundo. Achei essa imagem que acho que combina muito bem com minha ideia de jogo no site gratuito pic.com feito pela Certifique-se de verificar os requisitos de atribuição e licenciamento dos ativos encontrados on-line antes de usá-los Eu baixei essa imagem e vamos importá-la para Gadot para que eu possa usá-la como plano de fundo da minha tela de título Para evitar que a pasta de recursos do meu projeto fique muito confusa e desorganizada, criarei uma pasta para ativos importados Em seguida, dentro dessa pasta, crie outra para se divertir. Em seguida, arraste cada arquivo para a pasta apropriada para que eu saiba onde encontrá-los. Para desenhar essa textura, precisaremos adicionar um novo nó secundário à nossa cena. O nó que precisamos usar para desenhar imagens na tela é o nó destruído pela textura Vamos renomear o plano de fundo desse nó. Em seguida, preencha sua propriedade de textura com a imagem importada Não podemos mais ver o título. A imagem está sendo desenhada sobre ela. Por padrão, cada nó na árvore da cena é desenhado de cima para baixo. Então, o título está sendo desenhado primeiro, depois o plano de fundo está sendo desenhado sobre ele. Podemos reorganizar nossos nós facilmente arrastando-os. Portanto, o plano de fundo é classificado acima do título na árvore da cena Dessa forma, o título é desenhado sobre o plano de fundo. Essa imagem é muito maior do que a área de exibição do nosso jogo. Queremos que a imagem de fundo cubra toda a tela, então mudaremos suas predefinições de âncora para totalmente Isso move a imagem para ser centralizada nas quatro âncoras, mas ela ainda é muito grande. Se alterarmos o modo de expansão do nó destruído pela textura, podemos fazer com que ele ignore o tamanho da textura e em vez disso, use o tamanho especificado pelas âncoras Agora, a imagem cobre toda a área de exibição, mesmo que a proporção da imagem não corresponda exatamente à proporção da área de exibição. É difícil dizer com essa imagem, mas agora ela está distorcida, sendo esticada Existem outras opções para forçar o redimensionamento da imagem para caber na largura, ignorando a altura da imagem, adequada para caber em um arranjo horizontal ou ajustar a altura, ignorando a largura da imagem, ignorando a largura da imagem, melhor para caber dentro Qualquer uma das opções proporcionais tenta fazer o mesmo que as opções anteriores, mas também mantém a proporção das imagens Com a largura de ajuste proporcional, a imagem cobre toda a área de exibição mantendo sua proporção seguir, temos as opções do modo de alongamento, com o padrão de escala, que permitirão que a imagem se estique da maneira necessária para atender às demandas do modo de expansão e das âncoras que permitirão que a imagem se estique da maneira necessária para atender às demandas do modo de expansão e das âncoras O modo mosaico é para imagens menores do que o tamanho fornecido. Então, vamos trocar a imagem pelo ícone Gudo. Agora, a área está cheia de ladrilhos da imagem. Ao desfazer essa alteração, o keep ignorará o modo de expansão e forçará a imagem a manter suas dimensões originais e alinhá-la com o canto superior esquerdo Manter centralizado também manterá as dimensões originais da imagem, mas centralizado em sua área Manter o aspecto permitirá que a imagem encolha ou cresça para caber na área Voltando para Ignorar tamanho, como as proporções não coincidem, a imagem não cobre a tela inteira Manter o aspecto centralizado faz o mesmo, mas também centraliza a imagem dentro da área Manter o aspecto coberto redimensionará a imagem, mantendo sua proporção, mas certifique-se de que ela cubra toda a área Então, agora as bordas esquerda e direita desta imagem estão sendo cortadas Se você quiser garantir que a imagem inteira seja exibida, você provavelmente usaria manter aspecto ou manter o aspecto centralizado e alteraria a cor de fundo para preencher a área não utilizada Se você não se importa em cortar as bordas, usar manter o aspecto coberto também é uma boa opção para imagens de fundo Os botões de virar horizontal e virar vertical simplesmente inverterão a imagem se isso for algo que você deseja Vamos apertar play e ver como fica. Lembre-se de que, se redimensionarmos a janela do jogo, as âncoras mudarão e afetarão a forma como a imagem é desenhada E embora a imagem se redimensione para caber na janela, o título só se reposicionará, pois está sendo desenhado para um tamanho de fonte específico Mas podemos alterar algumas configurações para ter mais controle sobre esse comportamento. No menu principal, selecione as configurações do projeto. Em seguida, procure a janela na tela. Aqui podemos editar as dimensões da nossa janela de visualização, alterando as dimensões da janela do jogo quando executamos o jogo e também as dimensões do retângulo azul no editor É uma boa ideia definir isso para corresponder às dimensões da sua plataforma de publicação de destino. As âncoras ainda não foram atualizadas, mas selecionar ou redimensionar os nós as forçará a se atualizarem, e podemos redefinir suas predefinições de âncora I Podemos alterar se o jogo abre ou não em uma janela ou em tela cheia, mas não altere essa configuração até que você tenha alguma forma de sair do jogo Você também pode alterar onde a janela será exibida na tela definindo o tipo de posição inicial como absoluta alterando as coordenadas da tela da janela. E também em qual tela ela será exibida, alterando o tipo de posição inicial para o centro da outra tela especificando o índice da tela Essas opções só funcionarão em um projeto exportado, não quando as executarmos no editor Podemos deixar a janela sem bordas. E até mesmo alterar se a janela pode ou não ser redimensionada. Essa é uma forma de resolver o problema, mas não é uma solução muito flexível. As configurações em andamento oferecem alternativas melhores. Podemos alterar o modo de alongamento de todo o jogo de itens desativados para itens do Canvas. Lembre-se de que todos os nós de controle herdam do item Canvas, então todos serão esticados com a janela Existe outra configuração para ampliar toda a janela de visualização, que incluirá a saída de três câmeras D. Ao realizar esse alongamento, podemos alterar se a tela do jogo manterá ou não sua proporção Ignorar permitirá que o jogo se comprima e se estenda de qualquer maneira Manter a largura ou manter a altura permitirá que a janela do jogo seja dimensionada apenas na medida em que a largura ou a altura permitirem. Expandir permitirá que a tela do jogo cresça e diminua, ainda mantendo a proporção, mas se expandirá para preencher a janela inteira escala pode ser usada para reduzir automaticamente todos os itens da tela para metade do tamanho ou até oito vezes seu tamanho. Útil para desenvolvimento em plataformas que têm resoluções drasticamente diferentes sua máquina de desenvolvimento E o modo de escala pode ser definido como inteiro para restringir a escala a apenas dividir ou multiplicar ou multiplicar Isso é particularmente útil para arte em pixels, pois não causa distorção de pixels ao tentar esticar ou reduzir pixels em quantidades fracionárias As configurações de orientação portátil estão disponíveis para desenvolvimento móvel para restringir a retrato, paisagem, inverter ou usar o sensor do dispositivo para determinar a E o modo VSync pode ser alterado para determinar como a GPU da máquina é sincronizada com a taxa de atualização da tela Essas configurações não estão disponíveis ao usar o renderizador de compatibilidade e não serão aplicáveis a nada que fizermos neste projeto Agora temos uma imagem de fundo para nossa tela de título. Na próxima lição, adicionaremos um botão Iniciar. Te vejo na próxima aula. 18. Botão A: Olá, amigos. Na lição anterior, adicionamos uma imagem de fundo à nossa tela de título e, nesta lição, adicionaremos um botão Iniciar. Adicionando um novo nó à tela de título, assim como fizemos antes, desta vez estamos procurando o nó do botão. Semelhante ao nó do rótulo, um botão pode conter texto, mas também um ícone. Vamos chamar os botões de início. Em seguida, coloque também o mesmo texto no campo de texto, para que ele seja exibido no botão. Há também um campo de ícone, que podemos preencher com o ícone Gadot para ver como ele funciona O botão é desenhado como um retângulo arredondado abrangendo o texto e o ícone fornecido O botão plano remove todas as texturas ou cores do botão, desenhando somente o texto e o ícone No entanto, toda a área dos botões ainda pode ser clicada e ainda há um estilo de foco no botão que será desenhado quando ele estiver focado Expandindo as seções de comportamento do texto e comportamento do ícone, podemos alterar o alinhamento do texto e do ícone para mudar a forma como eles são exibidos no botão Essas alterações são muito mais aparentes se o tamanho do botão for maior do que o necessário para acomodar o texto e o ícone. Algumas das mesmas configurações de comportamento estão disponíveis como o nó do rótulo para controlar a sobrecarga de texto. Embalagem automática. E recorte se o tamanho do botão for muito pequeno para acomodar o texto E o ícone pode ser expandido para preencher o tamanho do botão. As opções de BD também estão disponíveis para idiomas escritos da direita para a esquerda. O botão base é uma classe da qual todos os botões herdam, até mesmo botões de outros tipos Examinaremos essas configurações na lição B. Por enquanto, vamos editar as propriedades herdadas do controle, começando pelo layout Eu gostaria que meu botão Iniciar estivesse abaixo meu título em dois terços da altura da tela Então, mudando o modo de layout de posição para âncora, alterarei as predefinições de âncora Em seguida, mova a âncora esquerda para 0,5 e a âncora superior para A âncora direita não pode estar mais à esquerda do que a âncora esquerda, então ela é automaticamente alterada para o mesmo valor Da mesma forma, a âncora inferior não pode estar acima da âncora superior Atualmente, o botão está na parte inferior e direita da âncora, então vou mudar as direções de crescimento para ambas Em seguida, redefina os deslocamentos da âncora para centralizar o botão em torno do ponto de ancoragem Com o botão posicionado, o próximo passo seria editar as propriedades do tema Se você quiser que o botão seja exclusivo , seria apropriado usar a seção de substituição de tema para esse botão Mas se você quiser que vários botões compartilhem as mesmas propriedades do tema, seria melhor defini-los apenas uma vez. Ao selecionar o nó raiz, criamos um tema na primeira lição, ou você pode criar um agora, caso ainda não tenha feito isso. Vamos alterar a fonte padrão e o tamanho da fonte do nosso tema, e podemos ver os efeitos dessa mudança na pré-visualização do tema. Embora esse tema seja uma propriedade do nó raiz, não do botão, fazer alterações nesse tema também afetará o botão. Isso ocorre porque o tema é passado pela árvore de cenas de pai para filho em outra forma de herança Se um nó usar propriedades de substituição de tema, como o título , essas configurações substituirão as herdadas do Analisando o painel temático, nossa visualização prévia do tema contém um nó de botão com as propriedades padrão do tema, exceto que a fonte e o tamanho da fonte foram alterados para as novas configurações. Ao clicar no botão Mais, podemos adicionar tipos de nós ao tema, como botão. Isso adiciona várias propriedades que podemos adicionar ao tema e editar. Começando na seção de cores, podemos alterar a cor do texto e do ícone enquanto o botão estiver em estados diferentes. A cor normal da fonte dos botões precisa contrastar com o plano de fundo. Vou usar apenas o cinza claro padrão. Freqüentemente, um botão desativado terá texto em cinza, às vezes até transparente. Botões ao passar o mouse podem clarear a cor. Às vezes, pressionado é mais escuro, e também adicionarei uma cor de contorno Todas as mesmas opções de cores também estão disponíveis para o ícone, que serão multiplicadas pelas cores da textura do ícone para produzir o resultado Na seção constante, podemos adicionar a quantidade de pixels que separam o texto e o ícone quando eles estão alinhados horizontalmente Além da largura máxima do ícone, a altura do ícone será ajustada automaticamente mantendo sua proporção. E também podemos especificar o tamanho do contorno do texto. Ainda não abordamos as caixas de estilo, mas se estiver usando caixas de estilo de tamanhos diferentes, você pode adicionar essa propriedade e definir seu valor como um para forçar o botão a sempre usar o tamanho da maior caixa de estilo. Podemos alterar a fonte de todos os botões se quisermos, mas vou usar apenas minha fonte de tema padrão. No entanto, farei com que o tamanho da fonte dos meus botões seja um pouco maior do que o tamanho padrão da fonte. Na seção de ícones, podemos especificar um ícone padrão para usar em todos os botões. O ícone definido nas propriedades dos botões substituirá esse ícone se for fornecido Portanto, se você quiser que quase todos os botões seu jogo tenham o mesmo ícone, defina-o aqui. Mas você também pode ter botões especiais com ícones exclusivos. A próxima seção é para estilos, onde podemos desenhar um plano de fundo diferente para o botão, além do retângulo curvo preto transparente padrão retângulo curvo preto Começando pelo normal, essa é a aparência do botão quando não está fazendo nada. Adicionando-o ao tema, temos várias opções de como fornecemos estilos. textura Style boox é usada para desenhar imagens importadas para usar como plano de fundo dos botões Eu tenho essas imagens de botão que vou importar para o Gadot com a pasta de ativos já selecionada Dessa forma, eles são importados para essa subpasta automaticamente Clique na caixa de estilo para abri-la no inspetor. Em seguida, defina a textura normal para a caixa de estilo normal. Não quero modificar a textura de forma alguma, mas o texto e o ícone realmente não se encaixam bem na imagem de fundo. Então, adicionarei margens de conteúdo para forçar o ícone e textura a se afastarem das laterais para o interior plano do botão Passando para o estilo pressionado, podemos adicionar outra textura de caixa de estilo. Mas desta vez preencha a textura com a imagem pressionada do botão Em seguida, adicione as mesmas margens de conteúdo normalmente. E repita isso para adicionar desativado e passar o mouse. Não tenho uma textura exclusiva para o Hover Press, mas podemos duplicar rapidamente uma caixa de estilo clicando e arrastando a que foi pressionada para o Selecionando o botão na árvore da cena, podemos visualizar a aparência do botão quando está desativado marcando a opção desativada nas propriedades herdadas do Executando o jogo, também podemos ver o estilo do botão mudar ao passar o mouse sobre ele e pressioná-lo No entanto, uma vez pressionado, o botão agora tem foco, o que lhe dá essa borda branca. Se quiser remover isso, você pode fornecer outra caixa de estilo para foco. Ou, alternativamente, podemos simplesmente adicionar uma caixa de estilo vazia para removê-la. Esse botão ainda não faz nada, mas teremos que esperar por outra aula. Agora temos um botão Iniciar para uma tela de título. Na próxima lição, adicionaremos links de mídia social. Te vejo na próxima aula. 19. Botão B: Olá, amigos. Antes de prosseguir, examinaremos mais alguns recursos dos botões. Lembre-se de que nenhuma das alterações feitas durante esta lição será salva. Abordamos a propriedade desativada da classe base do botão, mas há muitas outras propriedades listadas aqui. modo de alternância transformará o botão em um botão, ou seja, uma vez pressionado, ele permanecerá pressionado até ser pressionado botão pressionado pode ser usado para definir o estado padrão do botão enquanto ele está sendo usado como alternador Se não for um botão, o botão não pode ser configurado para ser pressionado Podemos alterar se o botão é considerado pressionado quando o botão do mouse é solto ou quando o botão do mouse é pressionado pela primeira vez. E também especifique qual botão do mouse está sendo usado para clicar no botão. Se a opção Manter pressionado para fora estiver ativada, clicar no botão e mover o mouse para fora dos limites do botão manterá seu estado pressionado até que o botão do mouse seja solto. Um grupo de botões pode ser criado para transformar um botão de alternância em um botão de rádio, que significa que somente um botão pode ser pressionado por vez Veremos como isso funciona quando o usarmos em uma seção posterior. E, por fim, o botão pode receber um atalho. Vamos usar a tecla Enter como atalho para pressionar esse botão Expandindo o atalho clicando nele, podemos ver que ele contém uma lista de eventos, qual também precisamos clicar para expandir A lista está vazia, então ela tem um tamanho zero. Mas podemos clicar no botão de adição de elemento para adicionar um evento a essa lista. Ao clicar no menu suspenso, usaremos uma tecla de evento de entrada para reagir ao jogador pressionar uma tecla no teclado. Ao clicar na tecla do evento de entrada para expandi-la, há muito mais propriedades aqui, mas só precisamos pressionar o botão de configuração para abrir uma janela de configuração do evento. Essa janela está ouvindo ativamente os eventos de entrada, portanto, pressionar qualquer tecla no teclado a selecionará automaticamente. Também podemos adicionar a exigência de que eles mantenham pressionadas outras teclas, como Shift, Alt, control, windows, ou detectem automaticamente a tecla de controle ou comando com base no sistema operacional do usuário Pressionar OK, preencherá as informações necessárias para nós. feedback do atalho mudará se o estilo do botão mudar quando o atalho for usado, e o atalho e a dica de ferramenta adicionarão automaticamente uma dica de ferramenta ao botão que mostra o Deixando os dois ligados, vamos ver como fica. passar o mouse sobre o botão, a dica de ferramenta nos diz que Enter é uma tecla de atalho para pressionar Pressionar a tecla enter no teclado também pressiona o botão Se desativarmos essas opções, a dica de ferramenta será removida e, embora a tecla enter ainda seja um atalho, ela não fornecerá feedback visual que o botão está sendo pressionado Selecionando o nó raiz e dando outra olhada nas opções de textura da caixa de estilo do nosso botão. Vou trocar minha textura pelo ícone Gadot para demonstração As margens de textura podem ser adicionadas para criar nove fatias. As texturas de nove fatias podem ser convenientemente redimensionadas com os cantos da imagem mantendo seu tamanho original, esticando as bordas ao longo de um único eixo e esticando o interior ao longo dos dois eixos para preencher o espaço dois forma como esses alongamentos do eixo são implementados pode ser alterada nas configurações de alongamento do eixo, seja esticando a imagem, colocando-a lado a lado ou combinando ladrilhos e alongamentos para As margens de expansão podem ser usadas para tornar a caixa de estilo maior do que sua área normalmente deveria permitir, expandindo-a em qualquer uma das quatro direções A sub-região é usada para dividir folhas de sprites em Clicar no botão Editar região abre uma janela do editor de região. Essa janela permite clicar e arrastar para escolher a região, ajustando as bordas e os cantos conforme necessário Há opções de captura de pixels para maior precisão Encaixe de grade Se sua planilha de sprite tamanho e espaçamento uniformes, você poderá especificar o tamanho e o deslocamento da grade para coincidir com a Em seguida, selecione uma ou mais células da grade para formar sua textura. Ou o Auto Slice encontrará automaticamente as texturas para você, e você pode simplesmente selecionar uma clicando nela Modulate também pode multiplicar toda a textura por outra cor, ajustando-a a uma Isso geralmente é usado para adicionar tonalidade ou, se sua textura for inteiramente em tons de cinza, modulação pode ser usada como a principal fonte de cor, criando uma grande variedade de caixas de estilo coloridas a partir de uma caixas de estilo coloridas a partir Outras opções também estão disponíveis para criar caixas de estilo no editor de temas. Todas as outras opções de caixa de estilo também têm as mesmas opções de margem de conteúdo da textura da caixa de estilo. Style boox empty não desenhará nada e não tem propriedades exclusivas Já a linha Stylebox desenhará uma única linha horizontal na parte superior do botão Clicando na linha Stylebox, podemos mudar a cor da linha Espessura. Mude para a vertical e aumente a linha em qualquer direção. Usar valores negativos aqui reduzirá a linha. A caixa de estilo plana desenhará um retângulo colorido simples. Clicando na caixa de estilo plana, podemos mudar sua cor e incliná-la em qualquer direção Se adicionarmos uma largura de borda , também poderemos alterar a cor da borda. E misture a borda com o plano de fundo do botão. Alternar o centro de desenho removerá o fundo para desenhar somente a borda Se adicionarmos o raio do canto , o retângulo se curvará como fazia por padrão E podemos alterar quantas arestas são calculadas para criar os cantos curvos com a detalhe do canto Também podemos adicionar uma sombra atrás do botão, alterar sua cor, tamanho e deslocá-la nas duas direções. E o anti-aliasing pode ser desativado ou podemos alterar seu tamanho para que as bordas pareçam mais lisas Isso abrange todas as propriedades do botão e as opções da caixa de estilo. Na próxima lição, adicionaremos links de mídia social. Te vejo na próxima aula. 20. Botão do link: Olá, amigos. Na lição anterior, adicionamos um botão Iniciar à nossa tela de título. Nesta lição, adicionaremos links de redes sociais. Vamos começar adicionando uma nova nota à árvore da cena. Desta vez, é um botão Link. Nomearemos esse nó com o nome da plataforma de mídia social, no meu caso, Patron Em seguida, preencha também o campo de texto com as mesmas informações Copiando e colando o URI desejado no campo, nada mais é necessário para o botão Link faça exatamente o que esperamos Executando o jogo, podemos clicar neste botão Link para abrir uma janela do navegador para o URI que especificamos. A opção sublinhado nos permite alterar se o texto está sempre sublinhado, somente quando o mouse está passando o mouse sobre As mesmas opções de BD estão disponíveis para linguagens que escrevem da direita para a esquerda, e temos todas as mesmas propriedades herdadas da classe base do botão, se quisermos usá-las. Isso funciona, mas não é o que eu quero para meus links de mídia social. Eu preferiria ter o ícone da plataforma ao lado do texto e ter ambos clicáveis como um Para fazer isso, precisarei de um nó destruído de textura para exibir o ícone Vou renomear esse ícone de nó e usar o ícone Gadot como espaço reservado por enquanto Não quero que o ícone seja tão grande, então vou configurá-lo no modo de expansão para ignorar o tamanho e no modo de alongamento para manter o aspecto. Em seguida, reduza-o para um tamanho mais razoável. seguida, em vez de usar o nó do botão Link para exibir o texto, usarei o nó do rótulo. Vou renomear esse identificador de nó e colocar meu identificador no campo de texto Em seguida, mova-o para a direita do ícone. Preciso agrupar esses dois nós, fazê-los agir como um único nó Podemos fazer isso usando outro nó como pai, como o nó do botão Link. Ao selecionar o grupo dos dois nós, podemos arrastá-los sobre o nó do botão Link para reencaminhá-los ao botão Link Então, eles agora são filhos do nó do botão Link. Ao mover o nó pai, os dois filhos se movem junto com ele, mantendo suas posições relativas. Se ampliarmos o tamanho do nó do botão Link para cobrir os dois filhos, toda essa área se tornará um botão clicável vinculado à plataforma de mídia social Também podemos ancorar o nó do botão Link qualquer local na tela e ele ajustará automaticamente as posições relativas dos nós secundários Uma maneira mais fácil de ser mais exato com o alinhamento horizontal dos controles e mantê-los espaçados de forma consistente é usar outro nó de controle que atenda exatamente a essa finalidade Esse nó é chamado de contêiner de caixa horizontal. Ele organizará automaticamente todos os seus filhos horizontalmente com espaçamento consistente entre eles, tornando-o filho do botão de link e, em seguida, filho do ícone e da alça do contêiner horizontal da caixa O ícone e a alça agora têm seu modo de layout definido como contêiner. Como estão dentro de um contêiner, o contêiner é responsável por determinar seu tamanho e posição. Portanto, essas propriedades estão desativadas. As crianças também são forçadas a cair até o menor tamanho permitido, que significa que o ícone foi reduzido a nada Se alterarmos o modo de expansão para ajustar o proporcional, esse modo de expansão é ideal para caixas horizontais, garantindo que a largura da textura corresponda altura permitida pelo contêiner horizontal Vamos selecionar o nó raiz para que possamos ver o editor de temas e adicionar o contêiner de caixa horizontal ao tema. Esse tipo de nó tem apenas uma única propriedade que podemos definir na seção constante, que é o número de pixels que serão usados para separar os filhos dos nós. Sinta-se à vontade para alterar esse valor e ver o que parece bom. Ao selecionar o contêiner horizontal da caixa, seu tamanho era originalmente de 40 por 40 pixels por padrão e expandido para cobrir seus filhos horizontalmente, mas a altura permanece Se clicarmos no botão de reinicialização, o contêiner tentará desmoronar o máximo possível. Como o tamanho do texto do nó do rótulo exige 31 pixels de espaço vertical, o contêiner também tem 31 pixels de altura. Essa altura também é fornecida ao ícone, cujas próprias configurações definem sua largura para corresponder à sua altura. Como agora sabemos o tamanho exato que precisamos para esse ícone e alça, podemos copiar esses números na propriedade personalizada de tamanho mínimo do botão de link, garantindo que ele sempre abranja a totalidade Em seguida, redefina sua propriedade de tamanho para forçá-la a cair para esse tamanho. Agora temos um botão de link de mídia social que inclui um ícone e uma alça, e a totalidade de ambos pode ser Vamos criar algumas novas pastas de ativos, primeiro para ícones e outra interna para ícones de mídia social, e outra interna para a fim mantê-las separadas dos outros ícones do jogo. Em seguida, importe alguns ícones de mídia social com essa pasta selecionada. Em seguida, podemos substituir o ícone Gdo pelo ícone apropriado Ao selecionar o nó do botão de link, podemos duplicá-lo usando o Controle D ou o Comando D para adicionar mais links de mídia social Cada duplicata adicionará um número crescente ao nome, pois os nós irmãos não podem ter o mesmo Todos os nós secundários também serão duplicados, mas manterão seus nomes originais, pois não são irmãos com Provavelmente queremos que esses links sejam organizados verticalmente. Podemos fazer isso com um contêiner de caixa vertical que funciona exatamente como o contêiner de caixa horizontal, mas organiza seus filhos verticalmente Então, vamos adicionar isso como filho da tela de título e renomeá-la para redes sociais Em seguida, agrupe todos os nós do botão de link e coloque-os nesse contêiner de caixa vertical O contêiner os organiza automaticamente na vertical para nós Vou renomear cada botão de link para a plataforma de mídia social apropriada Agora que podemos ver todos os nossos links, vamos alterar seus URIs. Seus ícones. E suas alças, se necessário. Como meus botões de tinta agora têm larguras diferentes, o contêiner vertical da caixa expandirá todos eles até a maior largura, tornando vários desses botões de link muito mais longos do que deveriam Ao selecionar todos os links do grupo, podemos alterar a propriedade de tamanho do contêiner nesse menu pop-up na janela de visualização, alterando o tamanho horizontal do contêiner de preenchimento para início de redução Assim, cada botão de link reduzirá sua largura para o tamanho mínimo que definimos anteriormente. Essas propriedades de dimensionamento de contêineres também podem ser encontradas na seção de layout das propriedades herdadas do controle ao expandir a seção de dimensionamento de contêineres As opções horizontal e vertical estão disponíveis, encolhendo no início, no centro ou no final do contêiner ou enchendo-o inteiramente em qualquer direção Vamos ancorar esses links de mídia social um canto da tela onde eles tenham uma boa aparência Vou colocar o meu no canto inferior esquerdo. Não é uma boa ideia ter esses tipos de ícones ou textos tocando a borda da janela dessa forma Geralmente preferimos ter algumas margens. Podemos facilmente deslocar a posição do nó do contêiner alterando suas predefinições de âncora para personalizadas e, em seguida, ajustando os deslocamentos da âncora, adicionando um valor positivo ao lado esquerdo para afastá-lo da borda esquerda da janela e um valor negativo na parte inferior para movê-lo afastá-lo da borda esquerda da janela e um valor negativo na para cima Selecionando o nó raiz para que possamos ver o editor de temas, assim como no contêiner de caixa horizontal, podemos adicionar contêineres de caixa vertical ao tema para alterar o número de pixels usados para separar seus filhos. Eu gostaria que a maioria dos contêineres verticais do meu projeto tivessem a mesma separação uniforme de pixels dos meus contêineres horizontais. Mas vou usar uma substituição de tema para tornar esse contêiner de caixa vertical específico uma exceção e dobrar a separação para espalhar esses links um pouco mais E podemos alterar a ordem dos links facilmente clicando e arrastando-os para reordená-los na árvore da cena e no Agora temos links de mídia social em nossa tela de título. Na próxima lição, adicionaremos uma variação ao nosso tema. Te vejo na próxima aula. 21. Variação do tipo de tema: Olá, amigos. Na lição anterior, adicionamos links de mídia social à nossa tela de título. Nesta lição, adicionaremos um tipo de variação do tema. Vamos adicionar um novo rótulo à nossa cena apenas para fins de teste. Um sem nenhuma substituição de tema, ao contrário do título. Usaremos muitos deles para exibir todos os tipos de texto e números na tela posteriormente. Selecionar o nó raiz para que possamos ver o editor de temas. Podemos adicionar um novo tipo ao nosso tema, o rótulo node. Como fizemos antes, podemos alterar as constantes das cores Fonte, tamanho da fonte e estilo, se quisermos. Vou usar apenas a fonte padrão e o tamanho de fonte padrão que eu já defini para o meu tema. Isso cria uma aparência consistente para todo ou pelo menos a maior parte do texto em nosso jogo. Sendo o título único, usa substituições de tema para definir suas próprias propriedades especiais de tema Embora eu goste da fonte estilosa do título, do texto e do botão Iniciar do meu jogo , esses links de mídia social devem ser muito claros e fáceis de ler, especialmente porque meu nome é muito difícil por si só. Por isso, importei uma segunda fonte para usar apenas nesses links, Roboto, enquanto o resto do texto do meu jogo deve permanecer na fonte estilizada Poderíamos selecionar cada etiqueta de alça e usar a seção de substituição do tema para alterar sua fonte, como fizemos com o título Mas e se quisermos alterá-lo ou adicionar mais desses botões de link? Em seguida, teríamos que editar cada uma das substituições do tema dos nós para garantir que todas correspondessem Seria melhor usar nosso tema para defini-los todos de uma vez , mantendo-os separados de outros nós de rótulo. Mas já adicionamos o tipo de rótulo ao nosso tema. Portanto, nos casos em que queremos definir um tema para alguns nós, mas não para todos os nós do mesmo tipo, podemos adicionar um tipo de variação ao tema simplesmente digitando nosso próprio nome nesse campo Vou chamá-lo de handle, já que é para isso que vou usá-lo. Esse novo tipo ainda não tem propriedades porque o editor de temas não sabe qual é o tipo base. Temos que ir até a última página e definir o tipo base para essa variação. E o tipo base é o tipo dos nós que queremos efetuar, rotular. Podemos digitar o nome nesse campo ou clicar no botão de adição para escolher o tipo base em uma lista. Isso adicionará todas as mesmas propriedades a essa variação de tipo que estariam disponíveis para um nó de rótulo. Assim, podemos adicionar as mesmas cores, fonte, cor do contorno, cor da sombra, constantes como tamanho do contorno e deslocamento da sombra, fonte, que vou E o tamanho da fonte, que eu gostaria que fosse um pouco maior que o padrão em 28. Nenhuma dessas alterações afetou nossos rótulos, o título, o texto ou as alças. Ao selecionar os nós da alça, podemos até mesmo agrupar e selecionar todos eles juntos. Em seguida, expanda a seção do tema. Em seguida, clique no botão Editar ao lado do campo de variação e digite o nome da nossa variação de tipo de tema. Assim, todos esses nós de rótulo agora usarão a variação do tipo de tema, para que possamos ajustar suas configurações exclusivas coletivamente, mantendo-as separadas de outros rótulos no projeto Alterar a fonte e o tamanho da fonte também pode fazer as caixas horizontais mudem de tamanho para acomodar o texto. Então, vou ajustar rapidamente os tamanhos mínimos personalizados dos meus botões de tinta para que correspondam. E agora vou excluir esse nó de rótulo extra , pois ele não é necessário para a tela de título. Agora temos links de mídia social que são mais fáceis de ler. Na próxima lição, adicionaremos um plano de fundo para o jogo principal. Te vejo na próxima aula. 22. Painel: Olá, amigos. Na lição anterior, adicionamos uma variação do tipo de tema para dar a alguns nós um tema consistente que difere de outros nós do mesmo tipo. Nesta lição, adicionaremos um plano de fundo básico para nosso jogo principal. Normalmente, os jogos teriam uma cena diferente para a tela de título e para o jogo principal, mas neste projeto, estamos fazendo tudo em uma cena. Por padrão, o fundo é apenas cinza. Se você quiser usar uma imagem como plano de fundo, use um nó de gravação de textura para desenhá-la Não quero apenas uma imagem simples, então vamos começar adicionando um novo nó à nossa cena. Desta vez, um nó de painel e renomeie-o como jogo. Na verdade, os painéis não fazem nada além de um nó de controle padrão, exceto que eles também desenham uma caixa de estilo. Vamos colocar suas âncoras em totalmente destruídas para que cubram toda a janela A caixa de estilo padrão para um painel é a mesma de um botão, apenas um retângulo preto semitransparente com cantos arredondados Antes de importar a imagem para o meu painel, criarei uma nova pasta de ativos para estilos e outra dentro dela para o botão Em seguida, mova todos os meus estilos de botão para essa pasta. Em seguida, outra pasta para painéis, e eu selecionarei essa pasta ao importar as texturas do estilo do painel Selecionando o nó raiz para que possamos ver o editor de temas, vamos adicionar um painel ao tema. Os painéis têm apenas uma propriedade temática, sua caixa de estilo. As mesmas opções estão disponíveis para o painel e para botões vazios, de linha, planos ou de textura. Vamos usar uma textura de caixa de estilo clicar nela para abri-la no inspetor e atribuir a textura como aquela que foi importada Com as configurações padrão, a textura é esticada para caber no tamanho do painel, que não parece muito bom Ao mudar a propriedade de alongamento do eixo para ladrilho, a imagem será ladrilhada em vez de esticada para preencher o espaço alocado O uso do encaixe de ladrilhos fará tanto o ladrilho quanto o alongamento , de forma que toda a região seja coberta com ladrilhos inteiros em vez de frações Esta imagem está um pouco ocupada demais, pode ser muito perturbadora, então vou usar a imagem da borda da corda Se adicionarmos algumas margens de textura, a imagem será cortada em nove texturas diferentes que serão usadas para criar caixa de estilo com os cantos mantendo suas dimensões exatas em pixels, as bordas sendo esticadas ou ladrilhadas para conectar os cantos e o centro sendo esticado ou ladrilhado para preencher a área restante Agora que temos um plano de fundo básico para nossa janela de jogo, precisaríamos ocultá-lo por padrão quando o jogo rodar pela primeira vez para que possamos ver a tela de título, que podemos fazer clicando no ícone do olho ao lado dela na árvore da cena. Mas como passaremos a maior parte do tempo desenvolvendo o jogo editando o conteúdo desse painel, seria melhor se ele estivesse visível para nós e a tela de título estivesse oculta. Então, queremos trocar o nó do jogo pelo nó da tela de título, tornando o nó do jogo o nó raiz da cena Clicando com o botão direito do mouse no nó do jogo, selecione a opção criar raiz da cena. O nó do jogo agora é o nó raiz com a tela de título como filha dele. Portanto, a tela de título foi originalmente desenhada sobre o jogo. Para mudar da tela de título para o jogo principal, tudo o que precisamos fazer é ocultar a tela de título desligando sua visibilidade. No entanto, agora o tema do painel não está mais sendo aplicado ao nó do painel, já que o tema é uma propriedade da tela de título, afetarei apenas a tela de título e seus filhos. Com a tela de título selecionada, expandindo a seção do tema, podemos clicar na seta ao lado do tema e salvá-lo como um recurso do projeto. Vou deixá-lo na pasta de recursos do projeto e nomeá-lo com o nome da fonte. O comércio vence. Esse tema agora está salvo na pasta de recursos do nosso projeto. Assim, podemos selecionar o nó do jogo, expandir a seção do tema e usar o menu suspenso para carregar esse tema. Agora, o tema está sendo aplicado a todo o projeto como antes, pois é uma propriedade do nó raiz. Também podemos removê-lo do nó da tela de título pois, de qualquer forma, ele está sendo herdado pela árvore de cenas Em seguida, precisaremos anexar um script ao nó do jogo, selecionando-o e clicando no botão do script anexado ou clicando com o botão direito do mouse no nó e selecionando o script anexado. Chamaremos esse script de gerente de jogo e criaremos uma nova pasta para armazenar todos os scripts do nosso projeto. Em seguida, crie o script nessa pasta. O script será escrito no script GD e herdará do painel o tipo do nó ao qual está sendo anexado Isso muda automaticamente nossa visualização para visualização script e abre o script que acabamos de criar. Esse script só precisa ativar ou desativar a visibilidade da tela de título. Para fazer isso, precisaremos uma referência ao nó da tela de título. Clicando com o botão direito do mouse no nó da tela de título, podemos acessá-lo como um nome exclusivo desde que nenhum outro nó na árvore da cena tenha o mesmo nome, que será indicado com um sinal de porcentagem. Em seguida, clicando e arrastando esse nó para o script, mantendo pressionada a tecla de controle ou comando enquanto soltamos o mouse, armazenaremos uma referência a esse nó em uma variável Vou continuar com o nome da variável com um sublinhado para marcá-la como privada, o que significa que ela só deve ser usada por esse script Substituindo a função de prontidão. O ícone de seta azul ao lado da função nos diz que essa função está substituindo a definição fornecida na classe node Essa função é chamada quando o nó e todos os seus filhos estão prontos, podemos fazer com que a tela de título apareça. Ao selecionar o botão Iniciar, podemos mudar o painel do inspetor para o painel do nó, que nos dá uma lista de todos os sinais que esse nó pode emitir O sinal ao qual queremos reagir é o sinal pressionado, que será emitido quando o botão for pressionado Clique duas vezes no sinal ou clique com o botão direito do mouse e selecione Conectar. Podemos conectar isso ao nó do jogo, que gerará automaticamente uma nova função para nós no Start Pressed. O ícone de conexão verde à esquerda dessa função nos diz que uma conexão de sinal chamará essa função. Quando o botão Iniciar for pressionado, solicitaremos que a tela de título se esconda. Executando o jogo, a tela de título é exibida e, quando clicamos no botão Iniciar, ela se esconde, revelando o painel do jogo abaixo Agora temos um plano de fundo para nossa janela de jogo. Na próxima lição, adicionaremos uma transição de atenuação. Te vejo na próxima aula. 23. Reto de cores: Olá, amigos. Na lição anterior, adicionamos um plano de fundo para nossa janela principal do jogo. Nesta lição, adicionaremos uma transição gradual para alternar entre a tela de título e o jogo principal Atualmente, a tela de título é exibida imediatamente e pressionar o botão Iniciar corta o painel do jogo, que é um pouco chocante Seria melhor se fizéssemos a transição gradualmente, o que podemos fazer facilmente com outro nó A cor destruiu o nodo. Vamos renomeá-lo para fade. O nó destruído por cores simplesmente preenche seus limites com uma cor sólida, que podemos alterar no inspetor, então vamos defini-lo Em seguida, coloque as âncoras totalmente destruídas para cobrir toda a janela É assim que a maioria dos jogos começa, termina e muda de cena com apenas uma tela preta vazia. Podemos ajustar a transparência conhecida como Alfa dessa cor para torná-la invisível gradualmente ao longo do tempo e voltar ao preto sólido sempre que precisarmos. Vamos escondê-lo para que possamos ver nosso jogo enquanto trabalhamos nele. Anexando um script a esse nó, salvando-o na pasta de scripts, o objetivo do script será entrar e desaparecer Sempre que estivermos ajustando um valor ao longo do tempo, podemos usar uma classe embutida de Gadot, uma interpolação, que armazenaremos Adicionando uma função, vamos dizer que está muito claro. A função pode retornar um sinal que será emitido quando for concluída A primeira coisa que precisamos fazer é criar uma nova interpolação. Em seguida, atribua essa interpolação criada à nossa variável. Essa é uma função da classe node. Qualquer nó pode criar uma interpolação. Em seguida, diga à interpolação para interpolar uma propriedade. Essa função tem quatro parâmetros. Qual nó? Podemos usar a palavra-chave self para dizer a esse nó que o script está anexado ao nó fade, qual propriedade Como uma string encapsulada entre aspas, especificamos o nome da propriedade, que é a O valor final da propriedade, que é a cor clara. Vamos escrever isso em maiúsculas por enquanto. E, por fim, a duração do tempo. Digamos que 1 segundo, por exemplo. Podemos então retornar o sinal finalizado da interpolação, que emitirá o sinal automaticamente quando Clear é indefinido, então vamos dar uma definição declarando-a na parte superior do script como uma constante Uma constante é o oposto de uma variável. Embora ambos armazenem informações, uma constante nunca muda. Eles são convencionalmente nomeados em maiúsculas e minúsculas, e podemos atribuir a elas o valor de Em seguida, especifique entre colchetes zero vermelho, zero verde, zero azul e zero Alpha, que é preto, mas também totalmente transparente Mudando para o script do gerenciador de jogos. Vamos dar um nome exclusivo ao fade e adicioná-lo ao gerenciador de jogos como uma variável Pode-se dizer que ele se mostre primeiro. Depois que a tela de título for exibida, podemos desaparecer para revelar gradualmente o título por trás do esmaecimento Quando o botão Iniciar é pressionado, podemos primeiro ficar preto antes de ocultar a tela de título e depois voltar a ficar claro Mas esconder a tela de título precisa esperar que o desbotamento para preto termine Como estamos retornando um sinal dessa função, podemos usar o comando await para pausar essa função até que o sinal seja recebido Portanto, também precisamos escrever as duas funções pretas de volta em nosso script de fade Essa função fará exatamente a mesma coisa que a outra função, mas apenas alterará o valor final para o qual a propriedade de cor está sendo interpolada Em vez de duplicar todo o código, seria melhor tornar isso uma função privada do que fazer que ambas as funções públicas a chamassem Vamos chamá-la de cor de interpolação e alterar o argumento do valor final da função de propriedade de interpolação para cor final Em seguida, adicione a cor final como parâmetro da declaração da função. Tanto claro quanto preto demais agora podem retornar o valor de retorno da cor de interpolação, passando clear como argumento ou ponto de cor preto, pois preto já está definido para nós na classe de cores Se chamássemos as duas funções claras, então a função two black, enquanto a interpolação está ocupada no momento, isso pode causar algum comportamento indesejado Portanto, sempre que isso for possível, devemos primeiro verificar se a interpolação já foi criada e se está Se ambas forem verdadeiras, podemos matar a interpolação antes de criar uma nova, evitando que surja qualquer conflito, com duas interpolações tentando alterar a mesma propriedade Se não tivermos certeza de que queremos usar 1 segundo como duração, talvez queiramos transformar isso em uma variável também. Vamos nomear a duração e definir seu valor para 1 segundo. Em seguida, adicione a tag de exportação na frente da declaração para nos permitir atribuir a essa variável um valor diferente no inspetor Ao selecionar o nó de desvanecimento na árvore da cena, podemos ver que a variável de duração tem o valor um, mas podemos alterá-la para o que quisermos Vou tentar 2 segundos e ver como fica. Ao executar o jogo, a janela começa completamente preta , mas fica clara, revelando a tela de título atrás dela No momento, não podemos clicar no botão Iniciar porque, na verdade, estamos clicando na cor esmaecida reta, embora seja transparente O botão também não está respondendo ao passar o mouse sobre ele. Ao selecionar o nó de atenuação, precisamos examinar as propriedades herdadas do controle da seção do mouse e alterar sua propriedade de filtro para Agora, os sinais do mouse passarão pelo nó de desvanecimento até os nós abaixo dele Então, vamos tentar rodar o jogo novamente. Se pressionarmos o botão Iniciar, ele ficará preto, ocultará a tela de título e ficará claro mais uma vez, e ficará claro mais uma vez, revelando Agora temos uma transição gradual para nosso jogo. Na próxima seção, começaremos a trabalhar no jogo real. Nos vemos na próxima seção. 24. Barra de menu: Olá, amigos. Na seção anterior, criamos uma tela de título para nosso jogo que pode fazer a transição para o jogo principal. Nesta seção, começaremos a trabalhar na construção do jogo real. Vamos começar adicionando um novo nó ao painel do jogo, um nó da barra de menus. E classifique-o atrás da tela de título. O nó da barra de menu não desenha nada sozinho. Portanto, se você quiser uma representação visual da barra de menu, precisará colocar esse nó dentro de outro painel ou fragmento de textura Em seguida, use a caixa de textura ou estilo para desenhar uma barra real. Estou bem sem desenhar uma barra real, então vou excluir esse nó extra. A forma como a barra de menu realmente funciona pode ser um pouco confusa. Se precisarmos de mais informações sobre como qualquer nó funciona, sempre podemos verificar sua documentação clicando com o botão direito do mouse e selecionando a documentação aberta. Mudaremos a visualização da descrição e abriremos a documentação desse nó Podemos ler na descrição que esse nó criará botões de menu para cada nó de menu pop-up adicionado como filho. Voltando às duas visualizações em D, vamos adicionar um nó filho à barra de menu do tipo menu pop-up. Isso não é estritamente um nó de controle, mas está próximo o suficiente. Simplesmente adicionando o nó do menu pop-up como filho da barra de menu, a barra de menu adiciona automaticamente um botão de menu com o mesmo nome do nó. Vamos renomear esse nó para algo mais comum em uma barra de menu, como arquivo Também adicionarei outro para configurações e mais um nomeado. Talvez seja necessário fazer outras alterações antes que a barra de menu seja atualizada. Os botões do menu estão sobrepostos à borda do painel do jogo, o que não parece muito bom Seria melhor se fosse afastado da borda da janela. Poderíamos movê-lo manualmente usando sua posição de transformação ou âncoras e deslocamentos de âncora Mas eu não gostaria que nenhum dos elementos do meu jogo tocasse a borda, então seria melhor aplicar margens ao redor que se apliquem a tudo O nó do painel não é um contêiner, então ele não pode controlar as posições ou os tamanhos de seus filhos. Adicionar margens de conteúdo à sua caixa de estilo será ignorado. Então, vamos adicionar um contêiner ao painel do jogo, especificamente um que adicionará margens, o contêiner de margem Em seguida, faça com que o filho direto do painel do jogo com a barra de menu seja filho do contêiner de margem. Selecionar o nó raiz para que possamos ver o editor de temas. Vamos adicionar um contêiner de margem ao tema. O contêiner de margem não desenha nada. Ele só tem constantes nas propriedades do tema. Quantos pixels de espaço na margem são adicionados a cada lado? Como a tela de título é uma irmã do contêiner de margem, não uma filha, ela não será afetada pelas Vamos também adicionar uma barra de menu ao tema. A barra de menu nos permite alterar a cor da fonte de todos os botões de menu que ela cria em todos os vários estados de botão que vimos antes. Na seção de constantes, temos a separação de pixels entre os botões do menu e o tamanho do contorno da fonte Podemos alterar a fonte e o tamanho da fonte, mas vou usar meus temas, configurações padrão para eles. Não há ícones e podemos alterar as caixas de estilo dos botões de menu criados pela barra de menu em todos os mesmos estados de botão. Para meus botões de menu, vou usar a caixa de estilo vazia como normal e copiá-la para desativada e uma caixa de estilo plana para pressionada e copiá-la para passar o mouse e pressioná-la com o mouse Abrindo a caixa de estilo vazia, adicionarei apenas algumas margens de conteúdo para tornar o tamanho do botão um pouco maior que o texto E para a caixa de estilo plana, adicionarei as mesmas margens de conteúdo, alguns cantos arredondados e escurecerei a cor Em seguida, torne a caixa de estilo flutuante única para que não fique presa às outras, abra-a e altere-a para uma cor mais clara Vamos ver como isso fica quando rodamos o jogo. Os menus estão todos na barra de menu. Eles têm uma caixa curva de estilo plano em uma cor mais clara quando colocada o mouse e mais escura quando pressionada No entanto, seus menus pop-up estão vazios no momento. Há algumas opções que podemos usar no inspetor para alterar o comportamento dos botões do menu O botão plano ignorará caixas de estilo dos botões do menu e apenas desenhará o Desligar o botão ao passar o mouse forçará o jogador a clicar nos botões do menu para alternar entre eles, em vez de apenas passar o mouse E o menu global preferido permitirá que essa barra de menu seja desenhada pelos sistemas operacionais Mac como o menu global fora da janela do jogo. Então, se você não quiser que isso aconteça, você pode desativá-lo aqui. Mas se você estiver usando o menu global, poderá especificar onde no menu global começar a adicionar seus menus pop-up personalizados com o índice inicial negativo, neste caso, sendo usado para significar automático. E, é claro, as opções de BD também estão disponíveis para idiomas que escrevem da direita para a esquerda. Agora temos uma barra de menu com vários menus vazios. Na próxima lição, preencheremos os menus pop-up com várias opções Te vejo na próxima aula. 25. Menu pop-up: Olá, amigos. Na lição anterior, adicionamos uma barra de menu ao nosso jogo. Nesta lição, adicionaremos opções para os menus pop-up. Selecionando o nó do menu pop-up e examinando as propriedades no inspetor, a parte inferior é uma seção expansível chamada itens Aqui, podemos adicionar cada uma das opções que estarão disponíveis nesse menu pop-up, como Novo jogo, salvar, carregar e sair. Esses itens podem ser reorganizados clicando nas setas ou arrastando o Vou criar uma nova pasta de ativos para ícones de menu e importar alguns ícones de menu. Em seguida, atribua a cada item do menu seu próprio ícone. Para configurações, adicionarei outro item e tornarei esse item marcado como uma caixa de seleção Isso seria apropriado para algo que pode ser ligado ou desligado, como silenciar, por exemplo Em seguida, adicionarei outro menu pop-up como filho desse menu pop-up para criar um submenu, que chamarei de dificuldade Os itens neste menu pop-up serão minhas configurações de dificuldade, cada uma marcada como um botão de rádio, que significa que apenas uma pode ser selecionada por vez A opção Fácil será marcada por padrão. Fácil, normal e difícil. No menu de ajuda, adicionarei um item para about com outro ícone. Em seguida, outro item que diz suporte. Ao clicar no botão separador, essa opção de menu não será um botão clicável, mas um separador entre grupos relacionados de itens de menu com seu nome escrito nesse Em seguida, adicionarei outro item abaixo do separador, que será um link para meu Patroon com o ícone de mídia social Selecionar o nó raiz para que possamos ver o editor de temas. Vamos adicionar um menu pop-up ao tema. cor do acelerador de fonte é usada para exibir atalhos, mas não temos a opção de adicioná-los no inspetor Nossos menus pop-up também não têm títulos, mas o restante das opções de cores da fonte deve ser familiar, junto com configurações extras de cor de fonte para separadores Na seção constante, nossos menus pop-up não têm um botão para fechar, mas a separação horizontal pode ser usada para adicionar espaço entre o ícone e o texto de cada item A largura máxima do ícone será útil para limitar o tamanho dos ícones de acordo com a altura da fonte do texto Não haverá nenhum recuo nesses menus pop-up, mas o preenchimento pode adicionar pixels extras início e ao final de cada item, dando um pouco mais tamanho do contorno da fonte com o qual estamos muito familiarizados agora, que também pode ser aplicado a texto e separadores Esses menus pop-up não podem ser redimensionados e não têm títulos Mas a separação vertical pode ajustar o número de pixels que separam cada opção do menu Existem propriedades para fonte e tamanho da fonte das opções do menu, título e separadores Vou deixar tudo isso e usar os padrões do tema. A página de ícones pode ser usada para alterar os ícones usados para caixas de seleção, fechamento, botões de opção e submenus Eu importei alguns ícones novos para usar neles, então vou substituir todos eles. Essas imagens têm 16 pixels quadrados e não serão redimensionadas. Portanto, certifique-se de usar uma imagem razoavelmente pequena para esses ícones Mesmo que nossos menus pop-up não tenham um botão fechado, adicionarei esses dois. Na página de estilos, podemos adicionar uma caixa de estilo para o painel de menus pop-up. Vou usar uma textura de caixa de estilo desenhada com a imagem da placa de aço e dar a ela margens de textura para evitar que os parafusos sejam esticados A caixa de estilo de foco é desenhada quando a opção de menu é colocada sobre ela. Vou usar uma caixa de estilo plana e fazer com que tenha a mesma aparência dos botões do menu. Como meu separador tem texto, posso usar as caixas de estilo separador rotulado à esquerda e separador rotulado à direita para alterar a forma como o separador é desenhado à esquerda e à direita do texto do Se o separador não tiver texto , a caixa de estilo do separador será usada para desenhá-lo Bordas incorporadas não serão usadas em nossos menus pop-up. Vamos ver como esses menus pop-up ficam quando rodamos o jogo. Ao clicar em qualquer um dos nossos botões de menu, o menu pop-up é exibido com o painel. É possível passar o mouse sobre cada item e clicar, mas nenhuma das opções faz nada ainda, e o submenu de dificuldade Isso não é feito automaticamente. Temos que adicioná-lo por meio de um script. Então, vamos adicionar um script ao nosso menu pop-up de configurações. Salvo na pasta de scripts, herdado do menu pop-up Pegando uma referência ao submenu de dificuldade, tudo o que precisamos fazer é quando esse nó estiver pronto e, portanto, seus filhos também estiverem prontos, podemos chamar uma função da classe do menu pop-up Adicione o item do nó do submenu, que requer um rótulo, um nó de menu pop-up e, opcionalmente, o número do índice de onde o submenu será Podemos simplesmente usar o nome do nó para o rótulo e o próprio nó. Ao ignorar o índice, o submenu será adicionado ao final Vamos adicionar outro script ao menu pop-up do arquivo para que possamos adicionar atalhos Tudo o que precisamos fazer é exportar variáveis do tipo atalho para que possamos configurá-las no inspetor Então, quando o nó estiver pronto, podemos verificar se esses atalhos têm um valor antes de defini-los como atalhos para os números de índice de cada item neste menu pop-up Podemos preencher cada um desses atalhos no inspetor com atalhos convencionais atalhos Controle ou Comando N para o novo S para salvar, L para carregar e E para sair. Em seguida, devemos voltar ao editor de temas e adicionar uma cor de fonte para nossos novos atalhos Agora, quando executamos o jogo, nosso menu de arquivos tem atalhos e nosso menu de configurações tem um submenu com botões de rádio Mas o ícone do submenu está escondido atrás do texto dos itens. Infelizmente, da forma como esses itens são dispostos, o ícone do submenu só ficará visível se o item não for o mais longo Para remediar isso, podemos escrever algum código para editar manualmente a largura do painel ou podemos renomear alguns de nossos outros itens para que sejam maiores que o item do submenu Precisarei adicionar um pouco mais de separação horizontal e preenchimento para acomodar meu tamanho de fonte grande Vamos dar uma olhada nas propriedades do submenu. As três primeiras opções determinarão se o menu pop-up será ocultado após clicar em uma opção Se desmarcarmos a opção de seleção de itens marcáveis para ocultar , o menu pop-up não se ocultará ao clicar em uma caixa de seleção ou ao alterar os Isso pode ser útil para os menus pop-up de configurações e dificuldade. Um item de estado é semelhante a uma caixa de seleção, mas pode ter mais de dois estados e deve ser criado por meio de um script O atraso no pop-up do submenu é quanto tempo o mouse precisa passar o mouse sobre o submenu antes que o pop-up apareça Permitir pesquisa tornará cada opção de menu no menu pop-up pesquisável com entrada do teclado enquanto o menu pop-up é exibido As outras opções são para integrar esse menu pop-up com diferentes menus do sistema operacional Executando o jogo novamente, tudo fica mais espaçado e podemos usar as entradas do teclado para pesquisar o menu pop-up que está Agora temos menus pop-up para cada um dos nossos botões de menu. Na próxima lição, escreveremos scripts para nossas opções de menu. Te vejo na próxima aula. 26. Sinais: Olá, amigos. Na lição anterior, adicionamos opções de menu à nossa barra de menu. Nesta lição, escreveremos scripts que reagirão ao pressionamento de cada um deles. Começando com o menu pop-up do arquivo, mude o painel do inspetor para o painel do nó onde podemos ver todos os sinais que esse nó pode emitir Pode reagir ao sinal de ID pressionado conectando-o ao script do menu pop-up do arquivo. Portanto, nosso script reagirá ao jogador selecionar qualquer um dos itens do menu ou pressionar as teclas de atalho Ao contrário do botão, esse sinal nos passa em uma discussão. Portanto, a função gerada tem um parâmetro correspondente do mesmo tipo, o número de identificação do item que foi pressionado. De volta à guia Inspetor, podemos ver os números de identificação de cada item se precisarmos conhecê-los ou editá-los. Dentro dessa função, podemos usar uma instrução match para executar código diferente com base no item que foi pressionado. E mantenha as coisas organizadas simplesmente chamando uma função diferente para cada uma. Vamos simplesmente imprimir declarações que digam qual função foi chamada no momento. Depois de iniciar um novo jogo, precisaremos redefinir muitos dos nossos nós de controle para seus estados padrão, que seria meio chocante se isso acontecesse Então, vamos pegar uma referência ao fade node. Em seguida, podemos esperar que o fade to black antes de criar os novos dados de salvamento e depois voltar a ficar limpo É impossível prever quantas coisas podem ser necessárias para reagir aos novos dados salvos que estão sendo criados. Em vez de reiniciá-los todos aqui, seria melhor emitir um sinal Podemos declarar nossos próprios sinais da mesma forma que as variáveis. Vamos chamá-lo de reset. Em seguida, emita depois de criarmos os novos dados de salvamento. Qualquer nó na árvore da cena pode se conectar a esse sinal e voltar ao estado padrão quando o jogador quiser iniciar um novo jogo. Como esse processo não acontece instantaneamente, talvez queiramos restringir quando ele pode ser chamado. Se, por exemplo, o jogador começar a pressionar novo jogo e carregar o jogo em rápida sucessão, isso causaria um comportamento indesejado Vamos declarar outra variável para determinar se esse script está ocupado ou não como booleano Então, quando qualquer ID for pressionado, se esse script estiver ocupado, ele ignorará a entrada. Definindo ocupado como verdadeiro antes de desaparecer para preto, depois falso após desaparecer para claro, nenhuma dessas funções será capaz de interferir uma na outra depois que uma for chamada Carregar o jogo será essencialmente o mesmo que começar um novo jogo por enquanto. sair do jogo, basta definir “ocupado” como verdadeiro, ficar preto e, em seguida, mandar a árvore de cenas parar Isso fechará o aplicativo em qualquer plataforma, exceto na web. Os jogos na web tendem a não ter a opção de sair. Em seguida, vamos dar uma olhada no menu de configurações e conectar o sinal de ID pressionado ao script. Por enquanto, vou apenas declarar uma variável para manter o valor atual de mudo como um booleano, que naturalmente usará como padrão falso e outra para a dificuldade como um número inteiro padronizado como um número inteiro Esse menu pop-up tem apenas um item, o botão mudo. Então, vou apenas confirmar que a ideia é zero e, em seguida, chamar uma função para definir o valor de mudo como o oposto do que é atualmente Dando uma definição a essa função, aceitando o valor de mute como um booleano, precisamos definir a caixa de seleção para ser realmente Passando o mouse sobre qualquer propriedade no inspetor que desejamos acessar por meio de um script, podemos ver o caminho da propriedade, item zero, barra, CHEC item zero, barra, CHEC Clicando com o botão direito do mouse, também podemos copiar esse caminho para a área de transferência Em seguida, chamando a função set, que aceita o caminho da propriedade como o primeiro argumento, podemos colar isso entre aspas Seguido pelo valor, queremos configurá-lo para silenciar Isso marcará a caixa de seleção, mas na verdade não silenciará Mudando o painel inferior para áudio, podemos ver o editor de barramento de áudio do Godo, que tem apenas um barramento por padrão, o barramento Master Audio, cujo índice de barramento é zero A maioria dos projetos de jogos terá um ônibus para música, efeitos sonoros e dublagens, para que cada um possa ser gerenciado como De volta ao nosso script, podemos acessar esse barramento mestre a partir de um servidor de áudio Singleton integrado Em seguida, acesse a função set bus mute passando o índice de barramento, que é zero e o valor de mute como argumentos Examinaremos as aulas de Singleton com mais detalhes na próxima lição Conectando o sinal de ID pressionado do submenu ao mesmo script, podemos definir o valor da dificuldade para corresponder ao ID que foi pressionado Como eles estão em ordem crescente, isso faz sentido. Em seguida, precisamos definir a propriedade verificada de todos os itens, pois os botões de opção nunca devem permitir que mais de um seja verificado por vez. Usando quatro voltas, podemos percorrer cada item na contagem de itens de dificuldade Então, isso contará zero, um, dois. Podemos então usar a mesma função de definição de antes, desta vez no menu pop-up de dificuldade, definindo a propriedade zero do item marcada como sendo se o valor do item é igual ou não ao ID que foi pressionado. Mas não queremos definir apenas o item zero. Então, estamos substituindo zero por porcentagem S. Isso marca uma posição dentro da string que será substituída por um valor. Seguindo a string com outro sinal de porcentagem , o valor para substituí-lo por isso definirá o item zero marcado, item um marcado e o item dois marcado com zero será igual à ID. Um é igual a ID e dois é igual a ID. Antes de criarmos o script de ajuda, vamos criar rapidamente uma janela simples sobre adicionando um contêiner de painel ao jogo, renomeando-a e classificando-a para ser desenhada sobre os outros elementos do jogo Em seguida, adicione uma caixa vertical, uma etiqueta e um botão. O rótulo pode descrever o projeto, sua versão atual e quem o está desenvolvendo. O botão será usado para fechar essa janela e pode ser instruído a encolher até o centro em vez de preencher a largura do contêiner Em seguida, ancoraremos isso no centro da tela. Conectando o sinal pressionado do botão ao nó about, não precisamos de um script anexado ao nó. Podemos simplesmente escolher a função hide que está definida na classe de controle desativando somente os métodos de script Por padrão, mantenha-o oculto. E dê a ele um nome exclusivo. Finalmente, vamos criar um novo script para o menu pop-up de ajuda. E também pegue uma referência à janela Sobre e conecte o sinal de ID pressionado ao script. Combinando o ID, lembrando que o separador também ocupa um ID, podemos mostrar informações sobre nosso jogo ou abrir um URI em um navegador Usando o Singleton OS, abreviação de sistema operacional, usando a função Shell Open especificando o No entanto, isso não funcionará para o web Build. Portanto, se o nome do sistema operacional for HTML cinco, devemos usar o JavaScript Bridge Sileton para avaliar o seguinte Localização do ponto da janela dot href é igual a então o site. Agora, isso funcionará em qualquer plataforma. Vamos rodar o jogo e tentar apertar nossos botões. No jogo principal, pressionar Control end fica preto. Vemos a saída da nova mensagem do jogo e ela volta a aparecer. O carregamento faz a mesma coisa. E salvar apenas gera a mensagem. Podemos marcar e desmarcar o botão de mudo, alterar a dificuldade dos botões de opção, abrir a janela Sobre, abrir a janela Sobre, fechá-la e abrir minha página do Patrion no navegador padrão Agora temos todas as nossas opções de menu reagindo às interações dos jogadores Na próxima lição, adicionaremos dados salvos dos jogadores e os gerenciaremos. Te vejo na próxima aula. 27. Salvar dados: Olá, amigos. Na lição anterior, conectamos todas as nossas opções de menu aos scripts. Nesta lição, criaremos dados salvos do player e os gerenciaremos com as opções do menu. Para gerenciar um Saffle, precisaremos criar um novo script que descreva o que está nele Vamos chamá-lo de algo como salvar dados e herdar do recurso em vez do nó Esse recurso não é nada que será desenhado ou mesmo adicionado à árvore de cenas, mas será apenas uma coleção de dados que descrevem as informações do jogador conforme elas são necessárias para jogar o jogo. Começando na parte superior do script antes de estender, precisamos dar a esse recurso um nome de classe usando a palavra-chave nome da classe com um sublinhado Eles são convencionalmente escritos em caso de Pascal. Em seguida, podemos adicionar as variáveis que quisermos a esse script. Vamos adicionar se o volume está mudo ou não, que seria um booleano e a configuração de dificuldade como um E também quaisquer outras variáveis que possam ser necessárias para jogar, como o ouro atual do jogador, por exemplo. Todos os tipos de variáveis devem ser primitivos, como booleanos, inteiros, flutuantes ou strings, ou criados em classes que contenham somente esses tipos primitivos, primitivos, como booleanos, inteiros, flutuantes ou strings, ou criados em classes que contenham somente esses tipos primitivos, como vetores ou cores. Qualquer informação que você queira salvar deve ter a tag de exportação. Talvez você queira incluir algumas variáveis sem a tag de exportação, que não persistirá entre as sessões do jogo Embora todas essas variáveis tenham valores padrão naturais, também podemos atribuir a elas nossos próprios valores padrão. Ou se quisermos incluir algoritmos complexos ou geração de números aleatórios, seria melhor substituir a função inicializada herdada Godot chamará automaticamente essa função para nós ao criar o recurso, para que possamos inicializar qualquer uma das variáveis necessárias Esse script deve ser salvo antes que possamos usá-lo em outros scripts. Em seguida, vamos mudar para o script do arquivo. Como o recurso tem um nome de classe, podemos declarar uma variável usando-a como seu tipo Em seguida, a nova opção do menu do jogo pode criar um novo recurso desse tipo usando o nome da classe seguido pelo ponto Nu. Para salvar nosso jogo, precisamos saber onde salvá-lo também precisamos saber onde salvá-lo no sistema operacional do jogador, que é melhor armazenado em uma constante. Vamos chamá-lo de path como uma string. Felizmente, Godot resolve esse problema para nós fornecendo o atalho “colon slash slash slash” do usuário, que apontará automaticamente para um Só precisamos nomear o arquivo. Seguir o nome com a extensão de arquivo dot TRS gerará um arquivo de recurso de texto que pode ser lido e editado por qualquer pessoa no Bloco de Notas Definitivamente, uma boa ideia para depuração e projetos Indi. Para salvar nosso jogo, tudo o que precisamos fazer é acessar uma classe única integrada, Resource saver, que tem uma função Isso aceita um recurso e um caminho como argumentos. Carregar o jogo é muito parecido com salvar, exceto que atribuímos o valor dos dados salvos a outra classe única integrada, o carregador de recursos, que tem uma função chamada load, aceitando o mesmo Esses singletons que continuamos usando são apenas scripts que contêm classes, não muito diferentes de muitos que escrevemos, mas fazem parte do próprio motor de jogo Gadot Eles são chamados de singletons porque são escritos de tal forma que só pode haver uma instância deles por vez uma instância deles por Isso os torna muito acessíveis porque podemos acessar diretamente a instância exclusiva diretamente pelo nome da classe, da maneira que fizemos aqui sem a necessidade de armazená-la em uma variável. Não precisamos saber onde ela está ou encontrá-la porque o nome da classe em si é uma referência direta à instância dela, justamente porque há apenas uma. A maioria dos scripts que escrevemos como desenvolvedores não precisam ser exclusivos e, na verdade, é preferível que não sejam . Pegamos o script fade, por exemplo, não há razão para que não possamos colocar esse script exato outro nó na árvore de cena e reutilizá-lo para uma Mas a necessidade de referenciar o nó ao qual o script está anexado armazenando-o em uma variável é a única maneira de saber qual script de fade estamos tentando acessar, já que haveria várias instâncias É possível criar nossas próprias classes Singleton em Gadot, mas não precisaremos fazer isso para script do gerenciador de jogos, vamos dar ao nó do arquivo um nome exclusivo e armazenar uma referência a ele em uma variável. Então, quando o botão Iniciar é pressionado, podemos dizer ao nó do arquivo que inicie um novo jogo. O script do arquivo cuidará do back-end desvanecido para que possamos removê-lo daqui Definir o valor padrão de busy como true impedirá que o jogador acesse qualquer uma dessas funções na tela de título, o que atualmente é possível usando os atalhos E também devemos desativar o botão Iniciar para evitar que ele seja pressionado mais de uma vez. Dando a ele um nome exclusivo. Não precisamos armazená-la em uma variável pois vamos usá-la apenas uma vez e podemos simplesmente definir sua propriedade desativada como verdadeira quando pressionada. No script de configuração, precisaremos armazenar uma referência ao menu pop-up do arquivo em uma variável para acessar o recurso de dados salvos e podemos excluir essas variáveis temporárias. Ao selecionar a opção Silenciar, precisaremos definir o valor de mudo para oposto do que está armazenado nos dados salvos Definiremos o valor do recurso de dados salvos do arquivo para corresponder ao modo mudo, tornando-o o oposto do que era anteriormente Da mesma forma, alterar a dificuldade também precisará definir o valor nos dados salvos do jogador. Quando um novo dado salvo for criado ou carregado, precisaremos definir esses valores para corresponder aos dados salvos. Então, selecionando o menu pop-up do arquivo, podemos conectar o sinal personalizado que criamos na última lição ao script do menu de configurações para chamar automaticamente uma nova função. Permitindo-nos definir o mudo e a dificuldade acordo com o que está nos dados de salvamento recém-criados ou carregados Vamos testá-lo executando o jogo. Usando os atalhos da tela de título, eles são ignorados Pressionar o botão Iniciar agora cria nossos dados iniciais de salvamento. Se selecionarmos Salvar no menu, um arquivo salvo será criado em nosso computador, que pode ser aberto em qualquer editor de texto, como o Bloco de notas Podemos ver os valores de nossas variáveis. De volta ao jogo, podemos alterar os valores de mudo e dificuldade, salvar o jogo e ver as alterações imediatamente em nosso arquivo salvo Se sairmos do jogo e começarmos de novo, podemos carregar nosso arquivo salvo e ver as alterações feitas nos valores que salvamos. Agora temos todas as nossas opções de menu funcionando. Na próxima lição, acompanharemos o ouro do jogador. Te vejo na próxima aula. 28. Contador: Olá, amigos. Na lição anterior, gerenciamos os dados salvos dos jogadores. Nesta lição, adicionaremos um contador à tela para rastrear seu ouro. Vamos primeiro pensar no layout geral da tela e decidir onde colocar essas informações. Com a barra de menu ocupando o canto superior esquerdo, acho que ter os contadores de recursos dos jogadores na mesma linha horizontal da barra de menu faz bom uso do espaço extra no canto superior direito, deixando o resto da janela disponível para o jogo principal Então, com o contêiner de margem selecionado, vamos primeiro ancorá-lo no tamanho real do painel do jogo Em seguida, adicione um contêiner de caixa vertical para organizar a barra de menu acima dos outros componentes que ainda não adicionamos. Ao contêiner de caixa vertical, adicionaremos um contêiner de caixa horizontal, que organizará a barra de menu à esquerda e os contadores de recursos à direita Os próprios contadores de recursos, com um ícone e um número também serão contêineres de caixas horizontais Vamos chamar esse de ouro. Em seguida, atribua a ele um nó destruído de textura e um nó de rótulo como seus filhos Eu tenho esse ícone de moeda dourada usarei como moeda do meu jogo, que preencherei como a textura do meu ícone Ao criar uma interface de usuário como essa, é uma boa ideia que seus contadores usem como padrão o número mais alto possível que você deseja permitir Dessa forma, você sabe quanto espaço precisa ser alocado para acomodá-lo Acho que 10 milhões deveriam ser um número suficientemente grande aqui. Atualmente, o contador está classificado pelo contêiner de caixa horizontal à direita da barra de menu, mas eu preferiria estar no canto superior direito e quaisquer contadores de recursos adicionais que eu possa adicionar para preencher à esquerda Ao selecionar a barra de menu, podemos pedir que ela se expanda horizontalmente para preencher o máximo de espaço possível, pressionando o restante dos filhos da caixa horizontal a se moverem o mais para a direita possível Agora, se eu duplicar meu contador dourado, cada contador será adicionado à direita, empurrando os anteriores para a esquerda. Em seguida, vamos adicionar um script ao nó dourado, que será responsável por garantir que o número exibido sempre corresponda ao número de ouro nos dados salvos do jogador. Então, vamos chamá-lo de contador e salvá-lo na pasta de scripts. Para acessar os dados salvos do player, precisaremos armazenar uma referência ao nó do arquivo em uma variável e, para alterar a propriedade de texto do nó do rótulo, também precisaremos disso. Então, podemos escrever uma função que atualiza o contador. Tudo o que precisamos fazer é definir a propriedade de texto do nó do rótulo o valor dos dados do arquivo dot gold como uma string. Sempre que o jogador inicia um novo jogo ou carrega o jogo, o sinal de reset é emitido, que podemos conectar a essa função para atualizar o contador Em seguida, precisaremos escrever uma ou duas funções públicas que alterarão o valor. Escreverei duas funções separadas, uma que recebe o recurso e outra para gastar o recurso, ambas aceitando um parâmetro inteiro para o valor Ao receber, simplesmente definiremos a nova quantidade do recurso como sendo mais a quantidade recebida e atualizaremos o contador. Mas talvez tenhamos decidido que deveria haver uma quantidade máxima que possa ser exibida. Então, vamos aplicar essa restrição aqui. Exportaremos outra variável para a quantidade máxima e atribuiremos um valor a ela. Podemos então impor esse máximo usando a função mínima A função mínima retornará o menor de todos os valores fornecidos. Portanto, a quantidade do recurso mais a quantidade adicionada ou a quantidade máxima permitida, o que for Ao gastar o recurso, primeiro precisamos verificar se o jogador tem recursos suficientes para gastar a quantia. Se a quantidade do recurso for menor que a quantia que está sendo gasta, provavelmente não gostaríamos de continuar com a transação e a devolução. Se o jogador tiver o suficiente , podemos reduzir a quantidade pela quantidade e atualizar o contador. Podemos tornar essa função mais útil retornando um booleano, retornando falso se o jogador não tiver o suficiente ou verdadeiro se for bem-sucedido Portanto, qualquer lógica de jogo que chame essa função pode reagir ao resultado da tentativa de gastar esse recurso como sendo verdadeira ou falsa. Para fins de teste, vamos substituir a função de entrada, que aceita um evento de entrada como parâmetro Em seguida, verifique se as teclas para cima ou para baixo foram pressionadas. Se for pressionado, farei com que o jogador receba um número aleatório de ouro de 1 a 100 Da mesma forma, ao pressionar para baixo, eles gastarão uma quantidade aleatória de ouro e eu imprimirei o resultado. Durante o jogo, podemos ver que o contador foi configurado para corresponder ao valor inicial do ouro do jogador. Pressionando para baixo, o valor diminui até que eles não tenham mais dinheiro para gastar. Nesse caso, o contador não é reduzido e a saída muda para false. Pressionar para cima aumenta o contador e eventualmente, atinge a quantidade máxima Isso funcionará muito bem com ouro, mas e se tivermos recursos diferentes que quisermos tratar com todas essas mesmas funções? Precisaríamos de um script diferente para cada recurso, o que não é um design muito bom. Então, vamos tornar esse script mais flexível e exportar o nome do recurso que esse contador está monitorando como uma string. Lembre-se de definir esse valor exportado no inspetor com a mesma grafia variável nos dados salvos do jogador que você deseja contar Também mudarei meu valor máximo de ouro para o que deveria ser. Também precisaremos declarar outra variável para manter a quantidade Agora, ambas as funções de transação podem começar obtendo primeiro a quantidade do recurso dos dados salvos pelos jogadores usando a função G, que aceita o nome da propriedade como uma string. Então, daremos a ele o nome do recurso. Em seguida, realizaremos nossas transações na variável local, em vez de referenciar diretamente os dados salvos dos jogadores E depois de executar nossas funções, podemos definir a variável nos dados salvos do player da mesma forma usando a função set, passando o nome da propriedade como uma string e seu novo valor. Também precisamos obter a quantidade atual dos dados salvos do jogador ao atualizar o contador. Agora podemos duplicar o nó dourado e fazer com que ele rastreie um recurso diferente sem alterações no script, alterando apenas os valores de suas variáveis exportadas Vamos adicionar outro recurso aos dados salvos dos jogadores, algo como robôs com um valor inicial de um. Em seguida, conecte-se também ao sinal de reinicialização para atualizar automaticamente esse novo contador de recursos. Agora, quando rodamos o jogo, os dois contadores exibem as quantidades de recursos diferentes contidos nos dados salvos dos jogadores Lembre-se de remover ou comentar a função de entrada antes de continuar. Além disso, a exibição dos contadores deveria ter sido atualizada após definir seu valor de quantidade Agora temos contadores de recursos para nosso jogo. Na próxima seção, começaremos a implementar algumas mecânicas de jogo Te vejo na próxima seção. 29. Edição de linha A: Olá, amigos. Na seção anterior, criamos uma barra de menu para o nosso jogo. Nesta seção, começaremos a implementar algumas mecânicas de jogo Vamos começar recolhendo o contêiner horizontal da caixa e talvez renomeando-o para algo mais descritivo Podemos então adicionar outra criança ao contêiner vertical da caixa para preencher o restante do painel do jogo Vou usar outro contêiner de margem. Vou nomear esse navio porta-contêineres com margem, pois vou usá-lo para exibir informações sobre o navio do jogador e expandi-lo para preencher verticalmente o restante do painel do jogo Dentro do contêiner de margem, colocarei uma caixa vertical para organizar alguns componentes verticalmente, começando com um nó de etiqueta que simplesmente diz minha nave, para que o jogador saiba que essa é a nave deles Abaixo disso, vou colocar uma textura reta para desenhar uma imagem da nave, usar o ícone Gadot como uma imagem reservada, pedir que ela ignore o tamanho da imagem e atribua dimensões personalizadas de 150 E, finalmente, um bloco de estatísticas das várias estatísticas do navio Semelhante a um contêiner de caixa horizontal ou vertical, podemos organizar facilmente um grande número de nós de controle em uma formação de grade usando um contêiner de grade. Vamos nomear essas estatísticas e atribuir duas colunas, uma para rótulos e outra para valores. Para as estatísticas, adicionarei dois nós de etiqueta para cada um, o nome do navio, o tipo, o número de membros da tripulação e a quantidade de carga que ele pode conter. Os rótulos no lado esquerdo da grade indicando o tipo de valor. os rótulos no lado direito podem ser enquanto, os rótulos no lado direito podem ser preenchidos com informações de exemplo, mas queremos que isso esteja vinculado às informações nos dados salvos do player O contêiner da grade classificará automaticamente seus filhos no número de colunas especificado, mantendo todas as linhas e colunas alinhadas Selecionando todos os três nós secundários do contêiner vertical da caixa, farei com que eles se encolham até o centro Eu gostaria que o jogador pudesse mudar o nome de seu navio, então vamos mudar o nó do rótulo de nome para um nó de edição de linha. Esse nó permite que o jogador edite o texto dentro dele enquanto joga o jogo. Vou colocar tudo isso dentro de um recipiente de painel para que tenha uma boa borda ao redor. Em seguida, diga ao recipiente da caixa vertical que encolha verticalmente até o centro do contêiner do painel Nessa tela, podemos ver claramente as informações de que precisaremos armazenar para cada navio: uma foto, nome, tipo de navio, números mínimos e máximos números mínimos e máximos de tripulação e capacidade de carga. Assim como fizemos com os dados salvos do player, podemos criar um script de recurso para armazenar essas informações. Vamos primeiro criar uma nova pasta de scripts chamada Resources, e podemos colocar o script de salvamento de dados aqui. Em seguida, crie uma nova pasta para navios e crie um novo script nessa pasta chamado navio herdando do recurso Aqui, podemos exportar variáveis da mesma forma que fizemos com os dados salvos dos jogadores para descrever um navio, incluindo uma textura de dois D para a imagem, uma string para o tipo e números inteiros para a tripulação mínima, a tripulação máxima e a capacidade de carga Vou excluir o nome do navio, pois ele não será associado ao tipo de navio. Certifique-se de salvar esse script. Clicando com o botão direito na pasta de recursos da nave, agora podemos criar um novo recurso e fazer quantas naves quisermos. Vou fazer três navios, um cortador, uma caçamba e uma escuna Clicando duas vezes no recurso, podemos abri-lo no inspetor e editar as variáveis exportadas, preenchendo a imagem com a foto de um cortador, preenchendo o tipo, os limites da tripulação e as e Cada um de nossos recursos pode preencher as variáveis exportadas com seus próprios valores exclusivos, criando uma categoria de objetos semelhantes para nosso jogo, todos com as mesmas propriedades, mas com valores diferentes Para organizar melhor meus scripts, criarei uma subpasta para a interface do usuário, sim Onde colocarei todos os meus submanuscritos, fade Em seguida, outra pasta para gerentes, que conterá o gerenciador de jogos e outro novo script que anexarei ao nó da nave e o chamarei de gerente da nave. A responsabilidade do gerente do navio será gerenciar tudo o que acontece com seus filhos, incluindo a atualização das imagens e do texto exibidos. Para fazer isso, esse script precisa saber quais são todas as naves que existem no jogo. Então, vamos exportar uma matriz de navios como uma variável. Dando uma olhada no inspetor, podemos ver nossa variedade de navios, adicionar três elementos a ela e preencher cada um com um navio diferente Eu projetei minhas naves para funcionarem como atualizações e preferiria que elas fossem classificadas da pior para a melhor Então, colocarei o cortador no índice zero, seguido pela captura e depois pela escuna Agora, tudo o que precisamos saber dos dados salvos do jogador é qual navio o jogador tem atualmente. Isso pode ser facilmente armazenado de forma muito eficiente , apenas como o índice de matriz do navio. Passando para o script de dados de salvamento, adicionarei um número inteiro exportado para o número de índice do navio do jogador e farei com que o padrão seja zero Enquanto estiver aqui, também adicionarei uma string para o nome do navio. De volta ao script do gerenciador de navios, para exibir as informações do navio do jogador, precisaremos de uma referência ao menu pop-up do arquivo para acessar os dados salvos do jogador. Vou renomear este nó para minhas informações de nave. Em seguida, pegue referências aos nós de textura wrec, edição de linha e rótulo Vou renomear cada uma dessas variáveis para que eu saiba que elas descrevem a ficha atual do jogador e também uma variável local para conter o número de índice do navio do jogador Escrevendo uma função privada para atualizar as informações da nave do jogador, cada nó definirá a propriedade apropriada para a de uma nave na matriz, usando o número de índice da nave do jogador para indexar a matriz. Vou mostrar a equipe mínima e máxima juntas transformando-as em cordas e separando-as com um Em seguida, exiba também a capacidade de carga com suas unidades em toneladas. Ao iniciar um novo jogo ou carregar, o sinal de reset será emitido e podemos nos conectar a esse sinal para atualizar automaticamente as informações da nave do jogador A depois de recuperar o número de índice do navio a partir dos dados salvos Mas nosso navio ainda não tem nome. Vou gerar aleatoriamente nomes de navios a partir de uma lista declarando primeiro uma constante na parte superior do meu script chamada nomes de navios, que será uma matriz de Em seguida, preencherei essa matriz com vários nomes de navios comuns Na função de redefinição do arquivo, se o navio não tiver um nome, atribuirei a ele um nome selecionado aleatoriamente dessa lista Indexando a matriz com um número inteiro aleatório entre zero e o tamanho da matriz menos A última coisa que precisamos fazer é permitir que o nó de edição de linha altere o nome da nave do jogador, o que pode ser feito conectando sinal de texto enviado ao script do gerente da nave. Isso será omitido após pressionar a tecla enter. Também há sinais para cada vez o texto muda ou quando o limite de tamanho do texto é atingido. Em nossa função recém-gerada, há duas situações possíveis que devemos considerar se o texto de edição da linha estiver vazio ou não. Como o novo texto foi passado para nós como um parâmetro, podemos facilmente colocá-lo em uma declaração if com true não sendo vazio e false sendo vazio. Se o novo texto não estiver vazio, podemos atribuí-lo ao nome do navio do jogador. Mas se estiver vazio, podemos fazer o oposto, revertendo o texto na edição da linha para o valor anterior do nome do navio Isso evitará que o jogador tenha um navio sem nome. Também é uma boa ideia fazer com que o nó de edição de linha libere o foco, independentemente do resultado. O nome do navio pode ser lido diretamente dos dados salvos do jogador quando atualizado. Voltando à visualização em dois D, podemos ver que as informações da nave de nossos jogadores são preenchidas com informações de espaço reservado Quando rodamos o jogo, tudo é automaticamente substituído pelas informações associadas ao navio cortador, e o navio recebeu um nome aleatório da lista Podemos clicar no nó de edição da linha para alterar o nome do navio e pressionar Enter para enviar a alteração. Ao tentar nomear o navio, nada é rejeitado. Salvando o jogo e iniciando um novo jogo. O nome do navio é substituído por um gerado aleatoriamente e, ao carregar o jogo, nosso nome de navio salvo é restaurado Agora exibimos as informações do navio de nossos jogadores e podemos editar o nome do navio. Na próxima lição, examinaremos as opções disponíveis para propriedades e temas de edição de linha. Te vejo na próxima aula. 30. Edição de linha B: Olá, amigos. Na lição anterior, permitimos que o jogador alterasse o nome do navio. Nesta lição, examinaremos as opções disponíveis para propriedades e temas de edição de linha. Selecionando o nó de edição de linha, vamos dar uma olhada em suas propriedades no inspetor Usando a propriedade text, podemos atribuir a ela um valor padrão. Se a propriedade de texto estiver vazia, texto do espaço reservado será exibido em vez disso com uma cor de fonte diferente Podemos alinhar o texto ao centro, certo? Ou preencher a linha inteira espaçará as palavras uniformemente. Podemos restringir o tamanho do texto inserido. É uma boa ideia testar quanto texto pode ser exibido confortavelmente usando uma letra larga, como M ou W. Em seguida, use isso para avaliar o tamanho máximo do texto Se a edição de linha não for editável, o player não poderá clicar nela e editar seu conteúdo Se a opção Expandir para o tamanho do texto estiver ativada, a caixa se expandirá para acomodar o texto dentro dela. Ativar o menu de contexto permitirá que o jogador clique com o botão direito do mouse na linha no nó para exibir um menu de contexto. Podemos ver isso no editor de temas sem executar o jogo. O menu de contexto tem um tema automático para combinar com os menus pop-up do nosso jogo e inclui todas as coisas típicas que esperaríamos ver, como recortar, copiar , colar, selecionar tudo, limpar, desfazer e refazer, um submenu para alterar a direção do texto e opções para exibir e inserir Se você não quiser incluir esse menu de contexto, você pode desativá-lo aqui. Para plataformas móveis e de console, integração de teclado virtual está disponível e há várias opções de teclado virtual, especificamente para inserir números, decimais, números de telefone, e-mails, senhas ou URLs telefone, e-mails, senhas Um botão claro pode ser incluído, o qual, quando clicado, removerá todo o texto da linha de edição As teclas de atalho exibidas no menu de contexto serão usadas mesmo que o menu de contexto não esteja Eles podem ser desativados aqui. Há uma opção para desativar a colagem usando o botão do meio do mouse nas plataformas Linux Você também pode alterar se o jogador pode ou não selecionar texto usando o mouse ou o teclado. Desmarcar em caso de perda de foco desmarcará qualquer texto destacado quando o nó de edição de linha perder seleção de arrastar e soltar pode ser usada para controlar se o jogador pode ou não clicar e arrastar o texto dentro dessa edição de linha. Um ícone pode ser atribuído ao lado direito do nó para indicar melhor ao jogador que esse texto é editável Um lápis é comum, mas vou usar um ícone de pena para combinar com a estética do meu jogo Se houver um ícone direito e um botão claro, o botão limpar será desenhado em vez do ícone direito sempre que houver texto a ser apagado Flat funciona exatamente como os botões, removendo todos os estilos do nó e desenhando apenas o texto e o ícone. Desenhar caracteres de controle é a mesma opção de alternância que estava disponível no menu de contexto, permitindo que os caracteres de controle fossem desenhados Por fim, selecionar tudo em foco selecionará automaticamente todo o texto quando o nó capturar o foco pela primeira vez. Na categoria de quilates, podemos dizer ao quilate para piscar e especificar o intervalo de tempo entre as A coluna de quilates é o índice de caracteres da localização atual do quilate Podemos ver isso se forçarmos a edição da linha a exibir o quilate mesmo sem foco Se estiver usando a edição de linha para informações secretas, como uma senha, podemos ativar o segredo e cada caractere será desenhado como o caractere secreto especificado aqui. A exibição do grafema feito em quilates e as opções de BD também estão disponíveis para sistemas de escrita mais complexos fora do alfabeto Para o meu jogo, usarei o texto do espaço reservado nomear seu navio com um comprimento máximo de 16 caracteres e permitirei que a caixa se expanda para acomodar o texto Vou manter o ícone certo como a pena, selecionar todo o texto em foco e ativar o espaço em branco em quilates. Além disso, o resto das opções estão bem como padrão Selecionando o nó raiz para que possamos ver o editor de temas, vamos adicionar edição de linha ao tema. Na seção de cores, podemos alterar a cor do quilate e do botão transparente normalmente e pressionado Podemos alterar a cor da fonte do texto normal, do texto espaço reservado, do texto selecionado e do texto não editável, bem como a cor do contorno de todos eles e a cor da caixa desenhada atrás desenhada Na seção constante, podemos alterar a largura do quilate, definir a largura mínima dos caracteres para a caixa **** da linha medida em Ms e a espessura do contorno da fonte Como tudo com texto, podemos alterar a fonte e o tamanho da fonte, mas vou deixá-los como padrão para o tema e podemos substituir o ícone usado para o botão limpar As cores claras dos botões serão usadas como modulação nessa textura de ícone Por fim, na seção de estilo, podemos fornecer caixas de estilo para a aparência normal da edição de linha quando está em foco e quando é somente para leitura Vou usar o estilo Box flat para o normal. Em seguida, clique nele para editá-lo, adicionar meus sete pixels habituais de cantos, bordas e margens de conteúdo Eu terei a mesma cor do fundo com uma borda mais escura Em seguida, duplicarei a caixa de estilo até a opção de foco, tornarei única e a abrirei para edição Quando estiver em foco, mudarei a borda para uma cor mais clara e adicionarei uma sombra. Podemos ver a aparência de nossas alterações na prévia do tema. Somente para leitura, vou usar apenas uma caixa de estilo vazia. Vamos também adicionar o contêiner de grade ao nosso tema. Assim como os contêineres de caixa horizontais e verticais, o contêiner de grade só tem constantes para suas propriedades de tema, o número de pixels que separa suas linhas e colunas Não se esqueça de testar a aparência de suas alterações executando seu jogo. Agora temos nosso nó de edição de linha configurado para combinar com a estética do nosso jogo. E a próxima lição permitirá que o jogador compre um novo navio. Te vejo na próxima aula. 31. Botão de opção: Olá, amigos. Na lição anterior, permitimos que o jogador alterasse o nome do navio. Nesta lição, vamos deixar o jogador comprar uma nova nave. Vou apenas recriar um conjunto de informações muito semelhante à direita desse contêiner de painel, exibindo as estatísticas de um upgrade de navio que está disponível para compra, começando com um contêiner de caixa vertical, que chamarei de navios à venda, depois colocarei os dois em uma caixa horizontal para organizá-los lado a lado Com as duas anotações infantis selecionadas, pedindo que elas se expandam horizontalmente, elas compartilharão o espaço disponível uniformemente Dentro dos navios à venda, copiarei a textura da etiqueta, o contêiner Wreck Grid e todos os nós da etiqueta Farei com que os navios à venda se encolham verticalmente para o centro para combinar com o layout do lado esquerdo Alterar o rótulo para dizer “navios à venda”. Mas vou mudar o nome para custo, mudar a etiqueta esquerda para uma textura reta e usar meu ícone de moeda em vez de texto para indicar que esse é o preço de compra Vou configurá-lo para caber proporcionalmente à largura e manter sua proporção de acordo com a altura do nó à direita Em seguida, altere-o de volta para o nó de rótulo normal e preencha-o com um número de amostra Em seguida, mova-os para a parte inferior da grade. Em seguida, também adicionarei um botão na parte inferior para permitir que o jogador compre este navio. E encolha-o para o centro horizontalmente para combinar com o layout Pode não fazer muito sentido ter apenas um chip à venda, então vou mudar o tipo do navio para um botão de opção. Este é um botão que apresentará ao jogador várias opções para escolher. Esse botão de opção está herdando suas propriedades temáticas do Estou bem usando meu tema de botão para o botão de compra, mas gostaria que o botão de opção tivesse um estilo diferente. Selecionando o nó raiz para ver o editor de temas, vamos adicionar o botão de opção ao tema. Isso nos permitirá substituir as propriedades do tema que o botão de opção herda do botão A maioria das propriedades do tema do botão Opção são idênticas às do nó normal do botão, que nos permite alterar as cores da fonte e do ícone de todos os estados do botão. Cor do contorno da fonte, fonte e tamanho da fonte e caixas de estilo para cada um dos estados do botão também. Vou usar o estilo Box flat para meu botão de opção e fazer com que pareça com o nó de edição de linha. Em seguida, duplique essa caixa de estilo para pressionada, torne-a única e altere a cor da borda para um tom mais claro Use-o para passar o mouse, pressionar o mouse e focar. Depois, vou usar uma caixa de estilo vazia para pessoas com deficiência. Podemos ver a aparência de nossas alterações na janela de pré-visualização do tema sem executar o jogo. Na seção de ícones, podemos alterar a aparência da seta para baixo fornecendo um ícone diferente. Assim como nos menus pop-up, esse ícone tem 16 pixels quadrados e não será redimensionado É importante que o ícone pelo qual você o substitua tenha o tamanho adequado Também há uma propriedade de tema para um ícone que será desenhado à esquerda do texto no botão. Vou colocar outro ícone para mostrar a você como é. Na seção constante, há uma propriedade para definir o tamanho do botão de acordo com sua maior caixa de estilo caso suas caixas de estilo tenham tamanhos diferentes. Isso funcionará quando meu botão de opção estiver desativado, pois a caixa de estilo vazia é menor que o resto. A margem da seta é quantos pixels estão entre a seta para baixo e o lado direito do botão. A separação horizontal é quanto espaço existe entre o ícone do lado esquerdo e o texto do botão. largura máxima do ícone pode ser usada para limitar o tamanho do ícone esquerdo. Não tem efeito na seta para baixo. Module a seta, se receber qualquer valor diferente de zero, modulamos o ícone da seta com a cor da fonte do texto dos botões em todos os seus vários estados de botão E o tamanho do contorno desenha um contorno ao redor do texto, como sabemos Não quero usar o ícone esquerdo no meu jogo, então vou excluí-lo. Selecionando o nó do botão de opção, vamos dar uma olhada em suas propriedades no inspetor A seção de itens expansíveis funciona exatamente como a que usamos para criar nossos menus pop-up Então, vou adicionar um item para cada navio do meu jogo. Cada item pode receber um ícone, se desejar, desativado ou usado como separador O número de identificação é usado para identificar qual item na lista está atualmente selecionado. Com selecionado como negativo, nenhum item é selecionado. Ajustar ao item mais longo dimensionará o botão inteiro para melhor acomodar o item com o texto mais longo Desativado, o botão será redimensionado para caber somente no texto do item selecionado E o botão Permitir reseleção permitirá que o jogador selecione o mesmo item que já está selecionado, emitindo o sinal selecionado emitindo o Muitas das mesmas opções também estão disponíveis , herdadas do botão e do botão Base que já exploramos Está claro que cada um dos meus navios vai precisar de outra propriedade, seu preço de compra. Então, mudando para o ScriptView, adicionarei uma variável ao script do navio para o preço do Lembre-se de salvar o script. Em seguida, atribua a cada recurso do navio um valor diferente para seu preço. Vou renomear meu botão Por. Vamos conectar o sinal pressionado dos botões By ao script do gerente do navio. E também o sinal selecionado do item no botão de opção. Há também um sinal que será emitido quando um item no menu pop-up for focado, se necessário Assim como fizemos com as informações do navio do jogador, preencheremos as informações no lado direito da tela com as informações do navio, que são selecionadas no botão de opção com base em seu índice Portanto, precisaremos armazenar referências ao opção Texture Wrecked e aos nós do rótulo, além do botão By Como classifiquei todos esses nós em um contêiner de caixa horizontal, todos esses caminhos não são mais válidos Eu poderia renomear todos os meus nós para ter nomes exclusivos e usar referências de nomes exclusivas, mas vou apenas adicionar o contêiner de caixa horizontal ao caminho Podemos copiar quase todas as linhas de código da atualização das informações do navio do jogador para a função de valor do tipo selecionado para atualizar as informações sobre o navio à venda, simplesmente alterando o índice da matriz para o índice do navio selecionado. Isso só funcionará se os índices da matriz do navio forem iguais aos números de identificação dos itens no menu pop-up dos botões de opção Podemos garantir isso gerando nós mesmos os itens dos botões de opção a partir desse script. Substituindo a função ready, podemos percorrer cada um dos navios na matriz de navios e, em seguida, adicionar um item ao botão de opção, o tipo do navio seguida, adicionar um item ao botão de opção, o tipo do Como a matriz de envio é indexada de zero em contagem regressiva, adicionando cada item ao botão de opção, os números de identificação corresponderão exatamente Mas precisamos remover todos os itens do botão de opção e fazer com que ele inicie o jogo vazio para que isso funcione. Quando um novo jogo é iniciado ou um jogo é carregado, recuperamos o índice da nave que o jogador já tem Não quero permitir que o jogador compre o mesmo navio que ele já tem ou um que seja de qualidade inferior. Então, vou contar de zero até o tamanho da matriz de navios e desativar cada item cujo número de índice seja menor ou igual ao índice de navios atual do jogador. Em seguida, selecionarei a próxima atualização disponível para o jogador, se houver uma. Se o navio atual do jogador for o último número de índice da matriz de navios, não haverá mais atualizações, então vou dizer ao botão de opção para selecionar menos um, e todas as opções serão desativadas Caso contrário, o botão de opção pode selecionar o item cujo índice é um a mais do que o índice atual do navio do jogador. Como estou permitindo que um negativo seja selecionado, obviamente não é um índice de matriz válido, então precisarei adicionar uma condição à função do valor do tipo selecionado para acomodá-lo. Em vez disso, remova todas as informações. A última coisa que quero fazer é desativar o botão de compra se o jogador não tiver dinheiro suficiente para comprar o navio atualmente selecionado. Pegando uma referência ao contador dourado do jogador. Vou simplesmente definir o valor do ponto de compra desativado para ser o oposto do ponto dourado suficiente, passando o valor da ficha atualmente selecionada. Essa função não existe, então vamos passar para o script do contador e adicioná-lo rapidamente. Copiando a definição de gasto, basta retornar se a quantidade do recurso é maior ou igual à quantidade em questão. Enquanto estiver aqui, vou descomentar a função de entrada para poder trapacear e ganhar mais dinheiro Finalmente, ao pressionar o botão de compra, chamaremos gold dot spend, passando o preço do navio atualmente selecionado para venda, e colocar isso dentro de uma declaração I nos permite reagir se o jogador tem ouro suficiente ou não para fazer isso. Isso nunca deve acontecer, pois desativamos o botão preventivamente se eles não tiverem ouro suficiente, mas não há problema em ter Se a transação for bem-sucedida, definiremos o índice atual do navio do jogador para o navio atualmente selecionado. Em seguida, atualize as informações do navio do jogador e também os navios à venda. Caso contrário, imprimirei uma mensagem de erro para saber que isso aconteceu. Ao definir o índice selecionado do botão de opção por meio de nosso script, o sinal do item selecionado não será omitido Mas, em vez disso, podemos facilmente chamar nossa função diretamente. Passando o índice selecionado, acabamos de configurá-lo como. Durante o jogo, o jogador começa com um cortador e a captura é exibida para venda Ao expandir o botão de opção, o jogador não pode comprar outro cortador, mas também pode ver a escuna Ao comprar a captura, as informações do navio do jogador são atualizadas e a escuna é exibida para venda Expandindo o botão de opção, a escuna agora é a única opção Dando a mim mesmo mais dinheiro, selecionarei novamente a escuna para ativar o botão de compra Se o comprarmos, agora não há mais navios à venda. Também devo desativar o botão de compra se não houver nada para comprar. Agora temos navios à venda que o jogador pode comprar como um upgrade. Na próxima lição, criaremos várias páginas diferentes de informações entre as quais o jogador poderá alternar. Te vejo na próxima aula. 32. Recipiente horizontal dividido: Olá, amigos. Na lição anterior, permitimos que o jogador comprasse navios maiores e melhores. Nesta lição, permitiremos que o jogador redimensione regiões do painel do jogo Esta página de gerenciamento de navios do meu jogo está claramente dividida em duas regiões de informações, o navio atual do jogador e os navios que o jogador pode comprar. Organizados em um contêiner de caixa horizontal, nenhum deles ocupa todo o espaço fornecido para eles, então eles estão se expandindo para dividir o espaço Em casos como esse, há um nó de controle que podemos usar para dar ao jogador mais controle sobre o layout, permitindo que ele redimensione a divisão de um espaço entre dois nós de controle, um contêiner dividido Os contêineres divididos podem ser horizontais ou verticais, mas só podem ter dois nós secundários e dividirão o espaço disponível entre eles e também permitirão que o jogador o ajuste. Se eu renomear esse nó, todos os caminhos do meu nó serão interrompidos Então, vou deixar o nome como está. Parece que nada mudou, mas se rodarmos o jogo e passarmos o mouse sobre o centro do painel do jogo, agora há uma barra na qual podemos clicar para agarrar e arrastar para a esquerda ou direita para redimensionar cada Cada lado só poderá encolher até o ponto em que seus próprios nós de controle secundário não possam mais entrar em colapso Selecionando o contêiner dividido horizontal, vamos dar uma olhada em suas propriedades no inspetor O deslocamento dividido pode ser usado para ajustar a posição da divisão, com zero sendo onde ela ficaria naturalmente após o primeiro nó de controle infantil, com o negativo se movendo para a esquerda e o positivo se movendo para a direita Colapsed ignorará o deslocamento de divisão, reduzirá o primeiro nó de controle secundário e posicionará a divisão imediatamente após visibilidade do arrastador pode ser usada para ocultar o arrastador, tornando-o inutilizável ou ocultá-lo e reduzi-lo, removendo a separação de pixels entre os Selecionando o nó raiz para que possamos ver o editor de temas, podemos adicionar o contêiner dividido horizontal ao nosso tema. Na seção constante, podemos remover o comportamento oculto automático do agarrador alterando o valor para zero, o que tornará o agarrador espessura mínima da captura é a largura ou altura em pixels da área clicável gerada para cercar o agarrador, já que os ícones do agarrador geralmente são muito finos e a separação é o número de pixels que separam os dois nós de controle secundário Na seção de ícones, há três ícones de captura diferentes, mas precisamos apenas alterar o ícone há três ícones de captura diferentes, superior Os agarradores horizontal e vertical são propriedades do contêiner dividido da classe principal e não serão usados por esse nó de contêiner dividido horizontal executar o jogo, podemos ver que o agarrador não se esconde mais automaticamente quando o mouse não está tocando nele A área que separa os dois nós secundários é mais larga do que era antes, assim como a área clicável Agora temos nosso contêiner de margem dividido em duas regiões redimensionáveis Na próxima lição, daremos ao jogador várias páginas de informações entre as quais ele poderá alternar. Te vejo na próxima aula. 33. Recipiente de guias: Olá, amigos. Na lição anterior, permitimos que o jogador redimensionasse parte do jogo Nesta lição, permitiremos que o jogo exiba várias páginas diferentes de informações. Minha janela de jogo agora parece mais cheia e eu não conseguiria inserir mais mecânicas sem sobrecarregar o jogador com muitas informações exibidas ao mesmo tempo Para resolver isso, vamos transformar o nó que está abaixo da barra de menu em um contêiner de guias. A descrição nos diz que o contêiner de guias criará uma guia para cada controle infantil, exibindo apenas uma por vez. Tornando o nó do navio um filho do contêiner de guias. Ela se torna uma guia dentro do contêiner da guia. Vou adicionar várias outras guias adicionando mais filhos ao contêiner da guia Todos eles serão contêineres de margem. Eu terei um para deixar o jogador gerenciar a tripulação de seu navio, outro para comprar e vender carga e outro para navegar até outro porto As guias geradas pelo contêiner de guias podem ser reorganizadas alterando a ordem de seus filhos Com a reorganização da árvore de cenas, o script do gerente da nave terá desconectado seu caminho até o contador de recursos dourados Posso corrigir isso dando ao contador um nome exclusivo e usando a anotação do sinal de porcentagem em vez do caminho do nó Voltando às duas visualizações em D e selecionando o contêiner da guia, vamos dar uma olhada nas propriedades do contêiner da guia no inspetor As guias são alinhadas à esquerda por padrão, mas podem ser movidas para a direita ou para o centro Eles também podem ser movidos para a parte inferior do contêiner da aba. guia atual é o número do índice secundário da guia que está sendo exibida no momento. Se houver tantas guias que nem todas caibam no comprimento do contêiner de guias, as guias extras serão recortadas e os botões de navegação serão fornecidos para permitir que o jogador as percorra Se as guias do clipe estiverem desativadas, o contêiner da guia se expandirá para acomodar todas as guias Desativar as guias visíveis ocultará toda a barra de guias. As abas ainda existem e podem ser usadas por meio de script, mas o jogador não conseguirá clicar nelas. Todas as guias na frente podem ser usadas para desenhar todas as guias sobre o conteúdo, em vez de Vou demonstrar como isso se parece mais tarde. Se a opção arrastar para reorganizar estiver ativada, o jogador poderá clicar e arrastar as abas para reorganizar suas posições na barra de abas Se essa configuração estiver ativada e você tiver vários contêineres de guias visíveis e quiser que o jogador possa clicar e arrastar as guias de um contêiner de guias para o outro, você poderá definir todos os contêineres de guias para que tenham as mesmas guias e reorganize o ID do grupo para permitir esse compartilhamento Com o valor padrão de menos um, as guias não poderão ser realocadas para nenhum outro contêiner de guias Com as guias usadas para o tamanho mínimo desativadas, o contêiner da guia será redimensionado para acomodar o conteúdo de cada guia à medida que for selecionada Ao ativá-lo, cada guia terá o tamanho da guia maior. modo de foco da guia pode ser usado para controlar como as guias na barra de guias podem capturar o foco, usando padrão os controles do mouse e do teclado Você pode restringir a permissão de apenas cliques do mouse para dar foco à barra de guias, portanto, pressionar a tecla tab no teclado ou as teclas de seta não permitirá que o jogador mude o foco para a barra de guias Mas se a barra de guias estiver focada ao clicar, as teclas de seta ainda poderão ser usadas para navegar entre as guias, ou nenhuma poderá ser usada para nunca permitir que a barra de guias capte o foco O jogador ainda poderá clicar nas guias para alternar entre elas, mas não conseguirá focar, mas não conseguirá focar, então as teclas de seta não serão usadas para alternar entre as guias Se a opção de desseleção ativada estiver ativada, o valor da guia atual poderá ser definido como menos um para que todas as guias sejam desmarcadas Depois de configurar as propriedades do meu contêiner de guias, vou fazer com que ele se expanda verticalmente para preencher o espaço da janela do meu jogo Selecionando o nó raiz para que possamos ver o editor de temas, vamos adicionar um contêiner de guias ao tema. Começando na seção de ícones, podemos substituir os ícones usados nos botões de incremento e diminuição que o jogador usa para percorrer as guias recortadas e suas contrapartes destacadas, que são exibidas quando o jogador passa o Também podemos alterar o marcador de soltar que será exibido entre as guias ao arrastar e soltar uma guia e um ícone de menu, e um ícone de menu, se esse contêiner de guia tiver recebido um menu pop-up, bem como Na seção de cores, podemos fornecer uma cor de modulação para o marcador de queda A cor do contorno da fonte e as cores da fonte para cada estado das guias na barra de guias Antes de continuarmos com o restante das opções de tema, vamos rodar o jogo e ver como essas configurações funcionam. Como minhas guias estão sendo recortadas, podemos clicar nos botões de incremento e diminuição para Posso clicar e arrastar as guias para reorganizá-las, e o marcador é desenhado e modulado para indicar onde a guia será posicionada se eu soltar o posicionada se eu Nenhum ícone de menu é exibido porque esse contêiner de guias ainda não recebeu um menu pop-up. Vou mudar a modulação do marcador de queda de volta para branco. Agora, excluirei as guias em excesso no meu contêiner de guias. Se adicionarmos um menu pop-up como filho do contêiner de guias, ele não gerará uma nova guia, pois o nó do menu pop-up não é um nó de controle. Vou colocá-lo como a parte superior do recipiente da aba para facilitar as coisas. E basta colocar um item no menu pop-up que diz: Olá, se anexarmos um script ao contêiner da guia, não vou manter esse script no meu jogo, então vou deixá-lo na pasta principal de recursos com o nome padrão. Substituindo a função ready, podemos chamar a aba container function set pop up, que aceita um pop-up como argumento Assim, podemos passar esse get child com o índice filho de zero, o filho superior, o nó do menu pop-up. Em seguida, vou mudar para o script do gerente de navios. As guias não podem ter apenas texto, mas também ícones. Mas, assim como o menu pop-up, eles devem ser adicionados por meio de um script. Então, vamos exportar uma variável que será o ícone das guias de envio como uma textura dois D, que podemos preencher no inspetor Então, na função ready, sabendo que esse é um filho direto do contêiner da guia, podemos chamar Get parent para referenciar o nó pai desse nó. Em seguida, chame a função do contêiner da guia, defina o ícone da guia, aceitando o número do índice da guia e a textura do ícone como argumentos. Então, vou passar o índice número três e a textura exportada Voltando ao editor de temas na seção constante, podemos dar a esse ícone uma largura máxima em pixels. O número de pixels que separam o ícone do texto de cada guia, o tamanho do contorno da fonte e quantos pixels de espaço na margem são adicionados a cada extremidade da barra de guias Como sempre, vou ignorar as configurações de fonte e tamanho da fonte e usar minhas configurações de tema padrão. Na seção de estilo, podemos alterar a forma como o contêiner da guia, a barra de guias e as guias são desenhados Vou definir todos eles com diferentes texturas de caixa de estilos. painel é o preenchimento de fundo do contêiner da guia em que a criança ativa será desenhada. Isso geralmente é desenhado sem problemas com o estilo de guia selecionado Essa imagem tem cantos arredondados, então vou adicionar margens de textura de 16 pixels Vou copiar isso para o estilo da guia selecionada, mas torná-la única, pois não quero que as guias tenham cantos arredondados na parte inferior Expandindo a seção de sub-região e, em seguida, clicando no botão Editar região, podemos usar somente uma parte da imagem fornecida para desenhar a caixa de estilo Com o encaixe da grade, posso cortar os 16 pixels inferiores para remover os cantos arredondados Agora, a guia selecionada parece estar conectada diretamente ao painel. Também removerei as margens da textura inferior. Isso moverá o texto e ícone para baixo na guia selecionada, fazendo com que pareça mais como se estivesse acima das outras. Copiando essas duas não selecionadas e tornando-as únicas, substituirei a textura por uma mais escura e, em seguida, colocarei a margem inferior da textura novamente, movendo o texto e o ícone Em seguida, repita o processo para adicionar texturas diferentes para Foco rígido e desativado O fundo da barra de guias também pode receber uma caixa de estilo, então vou usar uma sombra. Executando o jogo, agora temos uma barra de guias estilizada, e a guia do navio tem até um ícone de navio. O ícone do menu é exibido à direita e podemos clicar nele para abrir um menu pop-up. Não tenho planos de usar esse menu para nada no meu jogo, então vou excluí-lo. Remova o script do contêiner da guia e exclua o script dos recursos do meu projeto. Se suas guias tiverem um design muito ornamentado e você permitir que elas expandam margens grandes o suficiente para se sobreporem ao conteúdo da guia selecionada, é quando todas as guias desenhadas na frente podem ser usadas para desenhar todas as guias na frente do conteúdo da margens grandes o suficiente para se sobreporem ao conteúdo da guia selecionada, é quando todas as guias desenhadas na frente podem ser usadas para desenhar todas as guias na frente do conteúdo da guia selecionada. Vou reverter essas mudanças para o que eram. Agora temos várias guias entre as quais o jogador pode alternar Na próxima seção, usaremos mais novos nós de controle para adicionar mais mecânicas. Nos vemos na próxima seção. 34. Árvore A: Olá, amigos. Na seção anterior, permitimos que o jogador gerenciasse sua nave. Nesta seção, permitiremos que o jogador gerencie sua equipe. Mudando para a guia tripulação, adicionarei uma estrutura de nós semelhante à guia do navio, começando com um contêiner dividido horizontal contendo dois contêineres verticais , um para a tripulação que o jogador tem atualmente e outro para as pessoas que ele pode contratar, expandindo horizontalmente e preenchendo o espaço Em seguida, no lado esquerdo, adicionarei um novo nó chamado árvore e farei com que a árvore se expanda para preencher o espaço verticalmente Se selecionarmos o nó raiz e dermos uma olhada no editor de temas, há uma árvore aqui que podemos ver preenchida com diferentes tipos de itens de árvore, incluindo texto simples, texto editável, uma caixa de seleção, uma caixa de rolagem e uma lista Os três últimos também são classificados como filhos de outro item da árvore Há uma barra de rolagem que pode ser usada para percorrer os itens da árvore se a árvore for mais alta que a área alocada Os itens da árvore-mãe podem ser reduzidos ou expandidos para ocultar ou mostrar aos filhos Achei que essa seria uma ótima maneira de representar a cadeia de comando dos tripulantes do meu navio Selecionando a árvore novamente, não há como preenchê-la com itens de árvore a partir daqui Isso deve ser feito por meio de um script. Reconhecendo que é da mesma forma a árvore de cena funciona na guia de cena do Editor Gudo, posso recriar exatamente o que quero na minha árvore usando Com o topo da hierarquia sendo o capitão, seguido pelo primeiro companheiro, o segundo companheiro e o terceiro companheiro Antigamente, eles também podem ter tido um quarto companheiro. Posso reorganizar esses nós para que o primeiro parceiro tenha autoridade sobre o segundo, terceiro e quarto parceiros e adicionar mais filhos a cada um deles. O segundo companheiro é responsável pela navegação, então eles terão um navegador, timoneiro, Brelman, topeiro e marinheiros sob seu comando Brelman, topeiro O terceiro companheiro é responsável pela segurança e pelo combate, então eles terão o contramestre ou contramestre, um construtor de barcos em inglês moderno, carpinteiro, cirurgião E, finalmente, o quarto companheiro, se houvesse um, seria responsável pela logística e pelos recursos, então eles comandariam o cozinheiro, o açougueiro e o comissário Talvez eu também queira permitir passageiros pagantes a bordo do navio. Ao anexar um script à guia tripulação, vou exportar um ícone para ele, preenchê-lo com o ícone da tripulação do meu jogo e defini-lo como o ícone da guia de contêineres para essa guia na função pronta da mesma forma que na guia navio Em seguida, vou pegar uma referência ao nó da árvore. Vamos escrever uma função que adiciona um item à árvore. Podemos adicionar um item à árvore chamando sua função create item, que aceita argumentos opcionais para o pai do item que está sendo criado e o número de índice do filho. Ignorando esses argumentos, esse item será criado como a raiz da árvore Se quisermos alterar alguma coisa sobre esse item, precisamos armazenar uma referência a ele em uma variável do tipo item de árvore. Vou chamá-lo de novo item. Em seguida, podemos chamar a função set text nesse item de árvore recém-criado, que requer um número de coluna e argumentos de texto. Atualmente, a árvore tem apenas uma coluna, então o índice da coluna é zero, e eu vou colocar o texto que eu quero definir como um parâmetro da função. Sabendo que vou ter muitos itens de árvore, vou armazená-los em um dicionário e, em seguida, atribuir o item da árvore no índice do texto como o novo item. Agora, para adicionar o capitão à árvore, tudo o que preciso fazer é chamar minha função passando o nome do nó filho superior da árvore. Se eu quiser adicionar o resto deles à árvore, também preciso especificar o também preciso especificar item da árvore-mãe ao chamar create item, para que esse possa ser outro parâmetro da função. Ao chamar essa função para o capitão, o item da árvore-mãe será nulo Agora preciso percorrer a hierarquia que construí na minha árvore de cenas, adicionando cada item à árvore com o pai correto, o que parece complicado, mas pode ser simplificado usando recursão, ou seja, uma função que se chama Para simplificar ainda mais, vou manter a lógica recursiva separada da adição de um item de árvore e fazer isso em uma função separada, que chamarei de populate O primeiro parâmetro dessa função será o nó atual na árvore de cena, e também precisarei saber o item da árvore-mãe, se houver um. Em seguida, posso chamar a função de item da árvore do AD, especificando o nome do nó como texto e transmitindo o item da árvore principal Em seguida, armazenarei isso em uma variável local, retornando-a da função de item AdTree Usando um loop de quatro para iterar por todos os filhos desse nó, podemos simplesmente chamar essa função de árvore de preenchimento novamente no nó filho e fornecer a ela item da árvore principal gerado a partir do nó atual Se o nó atual não tiver filhos, esses quatro loops não serão executados. A função ready só precisa iniciar esse processo, começando com o nó filho superior da árvore e nenhum item da árvore principal Ao executar o jogo, a árvore é preenchida com a estrutura exata dos nós da árvore de micina Cada item na árvore pode ser selecionado e os itens principais podem ser reduzidos ou expandidos Vamos selecionar o nó da árvore e dar uma olhada em suas propriedades no inspetor As colunas podem adicionar colunas extras à árvore, dando a cada item da árvore várias entradas de texto, uma para cada coluna. Terei três colunas na minha árvore para exibir funções, nomes e salários. Os títulos das colunas estão ocultos por padrão, mas podem ficar visíveis com essa caixa de seleção Permitir nova seleção emitirá o sinal selecionado novamente se o jogador clicar no item selecionado, e podemos alterar se o botão direito do mouse pode ou não ser usado para Permitir pesquisa permitirá que o jogador navegue pelos itens da árvore digitando, combinando o texto de cada item A dobragem oculta oculta as setas de contrair ou expandir, e habilitar a dobragem recursiva permitirá que o jogador mantenha pressionada a tecla shift para expandir ou contrair as crianças Ocultar raiz ocultará o item da árvore raiz. No meu caso, seria o capitão. As bandeiras do modo drop podem alterar a forma como o jogador arrasta e solta dados na árvore, mas isso está além do escopo deste curso modo de seleção pode mudar se o jogador seleciona um único item, vários itens ou uma linha da árvore rolagem horizontal e vertical também pode ser ativada ou desativada Agora, com várias colunas e títulos visíveis, adicionarei títulos a cada uma das minhas colunas chamando a função definir título da coluna da árvore. Em seguida, defina também a última coluna para não expandir. Portanto, as colunas de função e nome ocuparão a maior parte do espaço da árvore. Depois de pegar uma referência ao menu pop-up do arquivo, precisaremos conectar o sinal de redefinição do arquivo ao script do gerente da equipe para reagir ao jogador está iniciando um novo jogo ou carregando o jogo e preencher as duas colunas restantes da árvore com o nome da equipe e as taxas de Como os itens da árvore são armazenados em um dicionário , faria sentido também armazenar os dados da tripulação do jogador em um dicionário correspondente. Por enquanto, vou apenas inicializar esse dicionário para já conter uma tripulação mínima para o navio, começando com o capitão Cada membro da tripulação precisa de várias informações, para que possam ser armazenadas em outro dicionário, dando ao capitão um nome padrão e uma taxa de pagamento de zero ouro. Em seguida, adicionarei um navegador, timoneiro, topeiro e marinheiro, cada um com um nome e uma cada um com De volta ao script do gerenciador de equipe, quando o arquivo é redefinido, podemos preencher a árvore com os membros da tripulação do jogador, mas também podemos precisar apagar os que já estão Então, analisando cada papel na árvore, verificaremos se a equipe do jogador tem esse papel Em seguida, chame outra função, especificando o item da árvore que estamos alterando, junto com o nome e a taxa de pagamento para os quais estamos alterando com valores em branco , caso o jogador não tenha essa função Escrevendo essa função, aceitando os mesmos parâmetros, podemos simplesmente definir o texto do item da árvore nas outras colunas para serem os valores passados. Agora, a árvore é preenchida automaticamente com os nomes e taxas de pagamento da tripulação do jogador, mas eu gostaria que o pagamento do capitão em branco e seu nome fosse editável Definir o item das raízes da árvore para ser editável na coluna um é bem simples com uma chamada de função Então, ao preencher um membro da tripulação, só definirei o texto da segunda coluna se o item não for o item raiz Conectando o sinal editado do item ao script do gerente da tripulação, podemos reagir quando o jogador edita o nome do capitão. Isso não nos fornece nenhum argumento, mas eles são armazenados na classe tree e podem ser recuperados com as funções get No caso da minha árvore, apenas um item da árvore é editável, então eu realmente não preciso saber nada além do que o jogador inseriu para o nome do capitão Se não estiver vazio, mudarei o nome do capitão nos dados de salvamento do jogador. Ou, se estiver vazio, reverta o item da árvore para o valor Isso funciona desde que cada função seja única, mas talvez eu queira ter algumas funções com vários membros da tripulação. Nesses casos, alterarei o valor armazenado em meus dados salvos de um dicionário descrevendo um membro da tripulação para uma série de dicionários descrevendo uma lista de membros da tripulação Vou dar ao jogador vários marinheiros e homens de primeira linha para realizar as operações básicas de navegação do navio, cada um com nomes exclusivos, mas vou deixar que eles paguem o mesmo porque meu navio é De volta ao script do gerente de equipe, ao criar a árvore, precisarei adicionar tantos itens de árvore quanto o número máximo possível de funções duplicadas, que indicarei na árvore da cena adicionando X seguido por um número ao nome da função Então, ao preencher a árvore, pesquisarei o nome do nó pela letra X e a armazenarei em uma variável Se a letra X não for encontrada, ela retornará menos um como resultado. Declarando novas variáveis para a função e a quantidade dessa função, a função padronizada para o nome do nó e a quantidade padronizada para um, se X for encontrado, posso analisar esses valores a partir do nome do nó usando a função substring com a função antes de X e a quantidade depois analisar esses valores a partir do nome do nó usando a dela antes Em seguida, chame o item da árvore de anúncios com as variáveis. Adicionar item de árvore precisará de um novo parâmetro de quantidade e, se a quantidade for maior que um, entrada do dicionário para esse item de árvore precisará ser uma matriz de itens de árvore, muito parecida com o dicionário da equipe. A criação do item da árvore pode então ser agrupada em quatro voltas, contando até a quantidade. E com base no fato de a quantidade ser ou não uma, defina a entrada do dicionário para o item ou anexe-a à matriz de não quero um monte de entanto, não quero um monte de funções repetidas em branco na árvore, então vou definir a visibilidade dos itens da árvore como verdadeira apenas para a primeira depois falsa para o resto. Quando o sinal de redefinição do arquivo for recebido, código diferente precisará ser executado com base no fato de a função ser ou não uma matriz. Se for uma matriz e o jogador tiver essa função no dicionário da equipe , a quantidade dessa função será o tamanho da matriz. Iterando todas as funções que estão disponíveis na árvore Se I for menor que a quantidade, o item da árvore na função de índice I pode ser preenchido com os dados da tripulação do jogador nos mesmos índices Caso contrário, eles ficarão em branco. E a visibilidade do item também pode ser definida como verdadeira se I for zero ou se for menor que a quantidade. Portanto, pelo menos uma de cada função sempre será exibida, mesmo quando o jogador ainda não as tiver. Durante o jogo, podemos ver que o jogador agora tem vários membros da tripulação designados para as principais funções de Homens e Marinheiros Agora temos um nó de árvore exibindo a tripulação do jogador. Na próxima lição, examinaremos as opções de tema disponíveis para o nó da árvore. Te vejo na próxima aula. 35. Árvore B: Olá, amigos. Na lição anterior, usamos uma árvore para mostrar a tripulação do jogador. Nesta lição, exploraremos as opções de tema disponíveis para o nó da árvore. Antes disso, porém, vou alterar esse parâmetro de nome para nome da tripulação para me livrar do aviso. Com o nó raiz selecionado, vamos adicionar o nó da árvore ao tema do jogo. Começando na seção constante, podemos definir se as linhas horizontais que separam cada item da árvore serão desenhadas alterando serão desenhadas alterando a propriedade da guia de desenho para zero ou não zero O mesmo pode ser feito para as linhas de relacionamento que mostram as relações entre pais e filhos dos itens da árvore com mais clareza. A largura da linha de relacionamento pode ser alterada aqui. E podemos fornecer diferentes larguras de linha de relacionamento para relacionamento infantil, bem como linhas de relacionamento com pais Também podemos separar a linha de relacionamento principal das linhas de relacionamento entre irmãos não selecionadas adicionando uma margem de pixels A separação horizontal são os pixels do espaço entre as colunas da árvore, bem como o lado esquerdo da árvore, se a dobra estiver desativada. As células dos itens da árvore podem receber pixels de espaço na margem em todas as quatro direções. margem do item também fornecerá um recuo extra à esquerda dos itens da árvore tamanho do contorno é o contorno da fonte com o qual estamos muito familiarizados até borda de rolagem e a velocidade de rolagem servem apenas para alterar o comportamento da rolagem de arrastar e soltar, não como a barra de rolagem se comporta naturalmente, portanto, não usaremos isso Podemos adicionar separação horizontal de pixels entre os itens da árvore e a barra de rolagem vertical, bem como separação vertical de pixels da barra de rolagem horizontal, se houver. E também podemos dar margens às barras de rolagem. A separação vertical adiciona separação de pixels entre cada item da árvore. Os itens da árvore podem conter vários botões e podemos usar essa propriedade para alterar a separação horizontal entre os botões. largura máxima do ícone pode ser usada para limitar o tamanho dos ícones fornecidos para os itens da árvore, e sua altura será ajustada automaticamente para manter a proporção. Vou exportar outro ícone do meu script de gerente de equipe e adicioná-lo à raiz da árvore na coluna um, para que o jogador possa ver claramente que pode editar o nome do capitão. Durante o jogo, o nome do capitão agora tem um ícone para indicar ao jogador que ele pode ser editado. De volta ao editor de temas, na seção de cores, há cores de fonte para o texto padrão do item da árvore, texto fonte desativado para quando um item da árvore é editável ou uma caixa de seleção, mas também está desativado, a cor do contorno da fonte, a cor da fonte dos itens da árvore selecionados e também as cores da fonte do título da coluna Podemos mudar a cor das diretrizes aqui, e também podemos mudar a cor das linhas de relacionamento e ter cores diferentes para as linhas de relacionamento com filhos e pais . cor da posição de soltura é a cor usada para indicar onde os itens arrastados serão soltos, e o destaque da fonte do botão personalizado só é usado para botões personalizados quando o mouse passa o mouse sobre eles Não usaremos nenhuma dessas opções. Existem diferentes opções de fonte e tamanho de fonte para os itens da árvore e os títulos das colunas, mas continuarei usando meus padrões de tema para Na seção de ícones, podemos alterar a aparência das setas de expansão e retração, bem como as caixas de seleção quando estão marcadas ou desmarcadas, ativadas ou desativadas e também os estados indeterminados Útil para pais tratarem itens que contêm listas de caixas de seleção como filhos Assim, o pai pode exibir a caixa de seleção indeterminada para indicar que alguns, mas não todos os filhos esse comportamento não é automático No entanto, esse comportamento não é automático e deve ser programado. O ícone da seta de seleção é desenhado para indicar os botões de opção que exibem um menu pop-up, e o ícone up-dwn é usado para caixas giratórias que editam números dentro de um intervalo O jogador poderá clicar na seta para cima para aumentar ou na seta para baixo para diminuir o valor. Para criar esses diferentes tipos de itens de árvore interativos, acessarei minha função de preencher membros da tripulação Em seguida, chamarei o modo de célula do conjunto de funções na coluna dois, que é a coluna de pagamento, e alterarei seu modo para verificar. Se o valor do pagamento não estiver vazio, definirei sua propriedade editável como verdadeira Caso contrário, vou configurá-lo como falso. Agora podemos ver que os itens da árvore na coluna de pagamento são caixas de seleção e só são ativados se o jogador tiver um membro da tripulação para essa função O ícone do modo de célula exibirá apenas um ícone sem texto, e o personalizado pode ser usado para criar botões personalizados, mas não faremos isso. Se o configurarmos para o modo de intervalo , podemos usá-lo para criar um botão de opção fornecendo uma lista de opções separada por vírgula como propriedade de texto ou um intervalo numérico que pode ser editado como uma Podemos configurar as propriedades do intervalo da caixa de rotação chamando set range config, fornecendo a coluna, o valor mínimo, valor máximo e o valor da etapa, e definir o valor atual chamando set range, fornecendo a coluna e o valor como um flutuante entanto, se o valor do pagamento estiver vazio, alterarei o modo da célula para string e o exibirei como texto vazio não editável Durante o jogo, o jogador pode alterar a taxa de pagamento dos membros da tripulação em intervalos de um a nove de ouro por dia, com passos de um ouro por clique. Essa interação também emitirá o sinal editado do item da árvore Portanto, precisarei verificar se o item que foi editado é o item raiz da árvore antes de editar o nome do capitão. Também terei que escrever um código adicional para alterar a taxa de pagamento do tripulante nos dados salvos do jogador aqui. Sem saber a função ou o índice de matriz do tripulante cujo pagamento foi editado, não há muito que eu possa fazer além de analisar todos eles e verificar qual deles era Então, iterando todos os itens da árvore, verificarei primeiro se é uma matriz Se não for uma matriz e for o item que foi editado, definirei o pagamento dessa função para novo valor do intervalo, convertido em um número inteiro Se a função for uma matriz, terei que pesquisar essa matriz até encontrar a que foi editada, agora me dando o índice da matriz, que posso usar para definir o pagamento do tripulante nessa função e o número do índice da matriz. De volta ao editor de temas, na seção de estilo, podemos alterar o painel da caixa de estilo desenhado atrás da árvore. Vou usar apenas uma caixa de estilo vazia para ignorá-la. Assim como o estilo de foco, que será desenhado sobre toda a árvore quando ela estiver focada, que também removerei ao defini-la como vazia. Podemos alterar as caixas de estilo dos botões de título normalmente quando passamos o mouse e pressionamos Não quero que meus títulos funcionem como botões, então também usarei caixas de estilo vazias para eles. A única caixa de estilo que eu quero usar para minha árvore será quando um item da árvore for selecionado. Então, vou configurá-lo como uma caixa de estilo plana, dar a ele uma cor sombria com cantos arredondados e copiá-lo na caixa de estilo para o foco selecionado O nó da árvore pode incluir automaticamente barras de rolagem horizontais e verticais, então talvez também queiramos adicioná-las ao tema Na seção de ícones, podemos fornecer ícones para incremento e diminuição nos estados normais de destaque e pressionado Lembre-se de que, com a barra de rolagem vertical, o incremento é aquele que aponta para baixo Não quero incluir esses botões nas minhas barras de rolagem, mas quero usá-los para definir a área clicável do mouse Então, vou adicioná-las como texturas de espaço reservado e dar a elas uma largura de oito pixels, mas sem Portanto, nada será desenhado por eles. Em seguida, na seção de estilo, posso definir a caixa de estilo de rolagem como uma caixa de estilo simples. Faça uma linha preta muito estreita adicionando uma borda invisível nos lados esquerdo e direito. Em seguida, copiarei isso para o estilo de foco também. Para quem gosta, vou fazer com que seja da mesma cor dos meus botões, com cantos arredondados e uma sombra Copiando isso para os outros dois estilos, eu os tornarei únicos, definirei a cor do realce mais clara e a cor pressionada mais escura Todas essas mesmas opções também estão disponíveis para a barra de rolagem horizontal. Agora temos nosso nó de árvore temático para combinar com a estética do nosso jogo Na próxima lição, permitiremos que o jogador contrate e demita membros da equipe. Te vejo na próxima aula. 36. Recipiente de rolagem: Olá, amigos. Na lição anterior, exploramos as opções de temas disponíveis para o nó da árvore Nesta lição, permitiremos que o jogador contrate e demita membros da equipe. Começarei adicionando um botão abaixo do nó da árvore que diz atire e encolha horizontalmente em direção ao centro Em seguida, conecte o sinal pressionado ao script do gerente da equipe. Podemos solicitar qual item foi selecionado nó da árvore e armazená-lo em uma variável. Se nada foi selecionado, ou se o item selecionado for o capitão, que no meu jogo representa o próprio jogador, pressionar o botão de disparo não deve fazer nada. Portanto, se algo foi selecionado além do capitão, obterei a função que foi selecionada como texto na coluna zero do item da árvore selecionado. Em seguida, divida minha lógica com base no fato de a função permitir várias pessoas, apagando a função da tripulação do jogador ou verificando se o tamanho da matriz de tripulantes atribuída a essa função não é zero antes de remover a pessoa no mesmo índice do índice da matriz do item da árvore selecionado Isso só é necessário porque eu ainda tenho a função representada como uma entrada em branco, mesmo que o jogador não tenha ninguém designado para essa função. Depois de demitir o tripulante, posso simplesmente solicitar a redefinição do arquivo para atualizar a árvore da tripulação com as novas informações. Vamos experimentá-lo. Podemos demitir qualquer um dos membros da tripulação, exceto o capitão. Tentar disparar entradas em branco não faz nada. No script de salvamento de dados, removerei a tripulação inicial, exceto o capitão, e inicializarei as matrizes como vazias Em seguida, precisarei gerar uma lista de pessoas procurando trabalho que o jogador possa contratar. Então, vou adicionar um contêiner de grade no lado direito desse painel e um botão abaixo dele que diz contratar um encolhimento no centro horizontalmente Vou fazer com que o contêiner da grade se expanda para preencher o espaço na horizontal e Dando três colunas ao contêiner da grade, adicionarei dois nós de rótulo e uma textura rect como cabeçalhos das colunas Nomeie-os e preencha-os com papel, nome e meu ícone de moeda Vou fazer com que o rolo e as etiquetas identificação se expandam para preencher o máximo de espaço possível, reduzindo a coluna de pagamento até o fim Vou precisar escrever um roteiro que preencha essa grade com candidatos em potencial Mas primeiro, eu não quero ser restringido pela quantidade de espaço aqui. Vou precisar de barras de rolagem como a árvore tem. O nó da árvore inclui a rolagem automática. Mas se eu quiser que meu contêiner de grade tenha rolagem, precisarei adicionar outro nó, um contêiner de rolagem O contêiner de rolagem só pode ter um nó secundário, que será recortado para caber dentro seu retângulo de controle e fornecerá barras de rolagem se o filho não couber, que eu expandirei para preencher o espaço fornecido Podemos ver os efeitos do contêiner de rolagem duplicando os nós secundários várias vezes, para que ele não caiba mais na vertical e continue adicionando texto até que não caiba mais Selecionando o nó do contêiner de rolagem, vamos dar uma olhada em suas propriedades no inspetor Seguir o foco fará com que o contêiner de rolagem ajuste automaticamente a posição de rolagem para manter o nó de controle de foco visível o tempo todo. Tanto o modo de rolagem horizontal quanto o vertical têm várias opções. A opção padrão mostra automaticamente a barra de rolagem somente quando é necessária, mas podemos alterá-la para sempre mostrar, nunca mostrar ou desabilitar Expandiremos o contêiner de rolagem para caber seu nó filho nessa dimensão, eliminando a necessidade de rolagem. Uma zona morta pode ser adicionada à rolagem por toque para ajustar sua sensibilidade Expandindo a seção de rolagem, podemos alterar a posição de rolagem padrão horizontal ou verticalmente por pixel, bem como alterar o incremento ou diminuição da etapa, que moverá a posição de rolagem quando o jogador clicar nesses botões Eu removi os botões de incremento e diminuição do meu tema da barra de rolagem Agora estou pronto para preencher essa grade com possíveis membros da tripulação esperando para serem contratados pelo jogador Centralizarei o texto nos cabeçalhos das minhas colunas para evitar que sejam recortados pelo contêiner de rolagem Então, vou conectar o sinal pressionado do botão de locação ao script do gerente da equipe. Primeiro, vou pegar uma referência ao nó do contêiner da grade. Também precisarei conhecer todas as funções possíveis que podem ser contratadas, que armazenarei em uma matriz, e uma lista de todas as pessoas aleatórias que eu gero, que também armazenarei em outra matriz. Depois de gerar a árvore da tripulação, defina as funções possíveis como a matriz de chaves do dicionário de itens da árvore, removendo capitão e passageiro das funções potenciais que podem ser contratadas. Em seguida, chamarei uma função diferente para preencher a grade superior A primeira coisa que farei ao preencher a grade superior é limpar seu conteúdo com outra função Depois disso, vou repetir várias vezes, digamos 15, e acrescentar uma nova pessoa ao grupo de pessoas que procuram trabalho digamos 15, e acrescentar uma nova pessoa ao grupo de pessoas que procuram Essa entrada na matriz será um dicionário, contendo uma função, um nome e uma taxa de pagamento com o nome e a taxa de pagamento sendo nós de rótulo, inicializando-os com o nome de classe dot neu A função será uma caixa de seleção, que é outro nó herdado do botão Dessa forma, o jogador pode marcar as caixas de seleção de todos que deseja contratar antes de clicar no botão de contratação para contratá-los todos de uma vez Todos esses três nós têm uma propriedade de texto que precisa ser preenchida Vou apenas dar a todos eles valores aleatórios, começando com a função sendo uma seleção aleatória de possíveis funções. Escolherei um nome aleatório de uma matriz constante de strings da mesma forma que fiz com os nomes dos navios, fornecendo uma grande lista de nomes em potencial em meu script em uma tag de região que posso recolher para evitar que atrapalhe Para pagar o pagamento deles, usarei apenas um número inteiro aleatório de 1 a 9 convertido em uma string Todos os três nós podem ser adicionados à grade superior como filhos. Limpar a grade é tão simples quanto percorrer a matriz de pessoas que estão procurando trabalho, ligar gratuitamente para Q em todas as três entradas do dicionário e , em seguida, limpar Se executarmos isso agora, a caixa de seleção não tem um tema e está herdando as propriedades do tema Então, vamos adicionar uma caixa de seleção ao tema do jogo e fazer com que pareça mais apropriado Começando na seção de estilo, caixas de seleção têm todos os mesmos estilos dos botões, que eu removerei definindo todas como caixa de estilo vazia. Em seguida, na seção de ícones, junto com o mesmo ícone herdado do botão, há ícones marcados e não marcados e desativados, além de um conjunto de botões de rádio Como sempre, deixarei a fonte e o tamanho da fonte para usar a configuração padrão do tema. As mesmas opções de cor de fonte e ícone também estão disponíveis para a caixa de seleção e para o botão Observe que as cores de modulação do ícone se aplicam somente à propriedade do ícone, não às caixas de seleção marcadas ou desmarcadas Na seção constante, alinhada à maior caixa de estilo com a qual estamos familiarizados até agora, igual ao tamanho do contorno e à largura máxima do ícone. Marcar o deslocamento vertical compensará a posição vertical ícones da caixa de seleção em alguns pixels para cima ou para baixo A separação horizontal adiciona pixels de espaço entre o ícone da caixa de seleção e seu texto. Se a caixa de seleção tiver uma caixa de seleção e um ícone, a separação horizontal será aplicada a ambas a separação horizontal será aplicada a Vou remover o ícone da minha caixa de seleção. Isso parece muito melhor. De volta ao roteiro, quando o jogador clica no botão de contratação, já que meu jogo tem regras sobre não ter várias pessoas na mesma função, eu criarei uma matriz de todas as pessoas que foram contratadas com sucesso e uma sequência para a função Depois de analisar as pessoas que estão procurando trabalho, analisarei todas as pessoas que foram contratadas e as removerei da lista de pessoas que procuram trabalho e , em seguida, atualizarei a árvore da equipe Dentro desse loop for, verificarei se a caixa de seleção da função da pessoa foi pressionada e, em caso afirmativo, definirei a função como o texto dessa caixa de seleção Para saber se essa pessoa pode ser contratada, a lógica será diferente se a função permitir várias pessoas ou não, que eu sei com base no fato de a entrada do dicionário de itens da árvore no índice dessa função ser uma matriz. Começando com funções exclusivas, se o dicionário da equipe de salvamento de dados do jogador não tiver essa função, posso definir o valor dessa função como essa pessoa, criando um dicionário com seu nome e taxa de pagamento como um número inteiro No entanto, se for uma matriz, terei que comparar o número de pessoas designadas para essa função na equipe existente do jogador com o número máximo permitido. E se eles ainda tiverem espaço , anexe essa nova pessoa à matriz Se o jogador não tiver espaço para mais essa função ou se a função única já estiver preenchida, continuarei até a próxima pessoa que estiver procurando trabalho. Se essa pessoa for contratada com sucesso, libertarei todos os nós associados a ela do cenário e os anexarei ao conjunto de pessoas que foram Isso será suficiente para permitir que o jogador contrate esses membros da tripulação As tentativas de contratar cargos de tripulação que já estejam preenchidos ou lotados serão ignoradas. Mas eu acho que é importante reforçar a capacidade máxima de tripulação da nave atual do jogador Então, vou escrever uma função que conta a equipe atual do jogador, retornando um número inteiro, iterando cada entrada no dicionário da equipe do jogador, se a entrada for uma matriz, adicionando o tamanho da matriz, caso contrário, adicionando uma e retornando o resultado Ao clicar no botão de contratação, adicionarei uma variável para a tripulação máxima. E a cada iteração de pessoas procurando trabalho, verificarei se o jogador atingiu a capacidade de tripulação e saio do circuito, se tiver Precisarei recuperar essas informações da nave atual do jogador Então, dando nomes exclusivos a essas guias, vou pegar uma referência ao gerente do navio usando o complemento Pronto E solicite os limites da tripulação do jogador, definindo o máximo para ser o primeiro elemento de uma matriz. O script do gerente de navio então precisa de uma função que retorne uma matriz de dois números inteiros dos limites atuais da tripulação do navio do jogador, simplesmente retornando uma matriz de dois números preenchidos com a tripulação mínima e a tripulação máxima de sua nave atual Agora, o jogador está impedido de contratar mais tripulantes do que sua nave atual pode suportar. O jogador agora pode gerenciar sua tripulação a partir desta guia de tripulação com mecânicas para contratar, ajustar as taxas de pagamento e demitir membros da tripulação. Na próxima seção, permitiremos que o jogador navegue para outro porto Nos vemos na próxima seção. 37. Botão de rádio: Olá, amigos. Na seção anterior, permitimos que o jogador gerenciasse sua equipe. Nesta seção, forneceremos a eles um mapa dos diferentes portos pelos quais eles podem navegar. Assim como na guia tripulação, vou começar mudando para a guia do mapa, adicionando um script a ela, chamando-a de gerenciador de mapas e salvando-a na pasta de scripts do gerenciador. Em seguida, exporte um ícone como uma textura dois D e defina-o como ícone dessa guia chamando o ícone definir guia no pai desse nó, o contêiner da guia, passando o ícone como argumento e preenchendo o ícone exportado com um ícone de mapa Voltando para duas visualizações em D, começarei adicionando um contêiner de caixa vertical a essa guia, contendo um nó destruído de textura, preenchido com a textura de um mapa do Mar do Caribe, configurado para caber proporcionalmente à sua largura, manter sua proporção e expandir para preencher o espaço verticalmente e encolher até o e encolher Neste mapa, adicionarei um nó de controle para usar como uma pasta para armazenar todas as minhas portas e ancorá-las em toda a destruição do Em seguida, representarei cada porto com caixas de seleção, começando por Havana, Cuba, depois Kingston Jamaica, Porto Prince Haiti e Santo Domingo na República Dominicana Essas caixas de seleção são naturalmente configuradas para o modo de alternância, que o jogador possa marcá-las ou desmarcá-las, mas eu só quero que elas possam ter uma marcada por vez, o que significa que devem ser ter uma marcada por vez, botões de rádio Podemos criar botões de rádio clicando no menu suspenso denominado grupo de botões e criando um novo grupo de botões Não precisamos fazer nada com esse grupo de botões além salvá-lo como um recurso do projeto. Em seguida, atribua todos os botões para também usar o mesmo grupo de botões. Os botões em um grupo de botões usarão os ícones dos botões de opção em vez dos ícones da caixa de seleção, e somente um botão em um grupo poderá ser ativado a qualquer momento Desativarei o botão Havana Cuba , pois será o local de partida do jogador E assim, eles terão três opções para escolher para seu primeiro destino. Eu gostaria de personalizar a aparência desses botões sem afetar outras caixas de seleção em meu projeto Então, vou adicionar uma nova variação de tipo de tema ao meu tema, chamá-la de porta e definir seu tipo base como caixa de seleção Se alguma porta estiver desativada, esteja ela marcada ou não, definirei seu ícone como uma âncora, pois isso indicará que é onde o jogador está atualmente Um botão de rádio não marcado será um ícone de venda, e um botão de rádio marcado será um X vermelho, indicando que é o destino selecionado pelo jogador Também vou reduzir o tamanho da fonte desses botões para que eles não ocupem muito espaço no mapa. Selecionando todos os meus botões de porta na árvore de cena, trocarei todos eles para usar a variação do tipo de tema da porta. Em seguida, redefina suas propriedades de tamanho para que sejam as menores possíveis enquanto contêm o texto. Para evitar que o texto do meu botão se sobreponha, farei com que Kingston e Portal Prince invertam o layout da direita para a esquerda, para que o texto apareça à esquerda do ícone do botão de rádio Para garantir que os botões permaneçam nas posições corretas, mesmo que o mapa seja redimensionado por qualquer motivo, configurarei os botões para o modo âncora usando âncoras personalizadas e posicionarei seus pontos de ancoragem no centro dos ícones dos Em seguida, repetirei isso para cada uma das minhas portas. Selecionando um dos botões de rádio, dando uma olhada em seus sinais, não seria um bom design conectar cada um desses sinais alternados a uma função diferente no script Isso tornaria a adição de mais portas muito complicada. Mas observe que o argumento transmitido pelo sinal é um booleano chamado ativado No script do gerenciador de mapas, podemos reagir a qualquer botão sendo ativado com uma única função Vamos primeiro declarar uma variável para manter a porta atual do jogador como um número inteiro, que naturalmente será zero, e outra como seu destino Vou atribuir a ele um valor padrão de menos um, que significa que o jogador não selecionou um destino. Podemos então escrever uma função para definir o destino, primeiro aceitando o parâmetro ativado para corresponder ao argumento passado pelo sinal alternado Em seguida, adicione outro parâmetro, o ID da porta do botão que foi pressionado. Se o botão estiver sendo ativado, o destino será o ID da porta Se o botão estiver sendo desativado e o ID da porta for o destino, o destino foi removido pelo jogador e deve ser colocado novamente em negativo Para conectar o sinal alternado dos botões a essa função, precisamos expandir a seção avançada do diálogo de conexão do sinal Aqui podemos adicionar argumentos extras ao sinal. O tipo de argumento que queremos adicionar é um número inteiro e, para Havana, deixarei seu valor em zero Podemos então voltar à lista de nós na cena, selecionar o nó do mapa e escolher uma função para chamar como reação a esse sinal. A função que está sendo chamada deve ter parâmetros cujos tipos correspondam aos emitidos pelo sinal Como esse sinal foi ativado como booleano e estamos vinculando um número inteiro extra, destino definido deve ter parâmetro booleano seguido por um parâmetro Podemos então repetir esse processo para cada botão de rádio, alterando o valor do argumento inteiro vinculado para um valor diferente Para simplificar, usarei o número de índice filho de cada botão na árvore da cena. De volta à visualização em dois D, também adicionarei um contêiner de margem na parte inferior do mapa ancorado na parte inferior e colocarei dentro desse contêiner de margem uma etiqueta para indicar a distância do porto atual do jogador até seu destino, medida em dias de navegação, e um botão para embarcar em sua jornada, e um botão para embarcar em sua encolhendo até o final do Em seguida, anotarei a posição e o tamanho do contêiner de margem e adicionarei um nó colorido destruído, pois é irmão, com as mesmas âncoras, tamanho e posição, colorido de preto semitransparente A imagem do mapa está muito ocupada e adicionar essa tonalidade apenas tornará o rótulo e o botão mais visíveis Vou deixar o rótulo invisível e o botão desativado por padrão. De volta ao script, vou pegar referências ao gerente do navio e a esses dois nós usando o addon ready. Em seguida, defina também uma matriz constante para manter as distâncias entre cada um dos meus portos medidas em milhas náuticas Criando uma matriz de números inteiros, as posições reflexivas serão se a porta e o destino atuais forem iguais, então a distância seria zero E vou preencher a matriz com alguns valores realistas para a distância de navegação em milhas náuticas entre cada uma dessas cidades Os valores simétricos devem ser os mesmos, supondo que você possa navegar pelo mesmo caminho em ambas as Depois de definir o destino, se o destino for negativo ou tiver o mesmo valor da porta atual, ocultarei o rótulo de distância e desativarei o botão de embarque Caso contrário, definirei o texto da etiqueta de distância para os números corretos de dias de viagem e, em seguida, ativarei o botão de embarque Para acessar os dados salvos do player, precisarei de uma referência ao nó dois do arquivo. Para calcular o número de dias de navegação, usarei a função de vedação, que arredonda uma bóia até o número inteiro mais próximo e divide a distância de navegação em milhas náuticas pela velocidade atual do navio do jogador Para que isso funcione, terei que adicionar essa função get speed ao script do gerenciador de navios. Então, voltando à tona, devolverei os navios indexados pelo número de identificação atual do navio do jogador E eu não incluí um valor de velocidade para o recurso da minha nave, então vou abrir o script de recursos da nave e exportar outra variável para a velocidade da nave. Em seguida, atribua um valor padrão de 100 milhas náuticas por dia. Posso então dar a cada navio uma velocidade diferente, se eu quiser, e o jogador poderá fazer essas viagens em menos dias de navegação Também gostaria que o jogador pudesse desativar o destino clicando nele novamente, que não é permitido por padrão Se clicarmos duas vezes no grupo de botões nos recursos do projeto, podemos ativar a propriedade Permitir pressão para acomodar esse comportamento . Vamos experimentá-lo. O jogador pode clicar em qualquer desses botões de rádio no mapa, selecionando-o como seu destino, e o número de dias será atualizado e o botão de embarque será ativado. Se pressionarmos o botão que já estava ligado, também podemos desativá-lo E agora não há destino, então o número de dias fica oculto e o botão de embarque é desativado Agora temos um mapa com várias portas que o jogador pode escolher como destino. E a próxima lição permitirá ao jogador controlar a âncora do navio Te vejo na próxima aula. 38. Botão de verificação: Olá, amigos. Na lição anterior, permitimos que o jogador selecionasse um destino em um mapa. Nesta lição, vamos deixar que eles controlem a âncora do navio. Abaixo do meu mapa, o contêiner vertical conterá um contêiner horizontal e um botão de verificação que será usado para controlar a âncora do navio Assim como a caixa de seleção, o botão de seleção também herda a maioria de suas propriedades do botão, incluindo seu tema Selecionando o botão de verificação, vamos dar uma olhada em suas propriedades no inspetor Começarei removendo as propriedades do tema de estilo herdadas do botão marcando a caixa de seleção plana Podemos adicionar texto ao botão de verificação e também a um ícone. Vou usar o texto para indicar ao jogador que isso é usado para controlar a âncora do navio Como outros botões, podemos ajustar como o texto e o ícone serão desenhados em relação à posição do botão de seleção e quanto espaço está disponível. Em seguida, vamos selecionar o nó raiz para que possamos ver o editor de temas e adicionar o botão Verificar ao tema. O botão de verificação herda muitas das propriedades com as quais estamos familiarizados das cores dos botões, como fonte e ícone Na seção constante, podemos alinhar tudo à maior caixa de estilo definindo-a para qualquer coisa diferente de zero Adicione algum deslocamento vertical ao botão de verificação, separação horizontal entre o ícone, o botão de verificação e o texto Defina um limite para a largura máxima do ícone. E um tamanho de contorno para o texto, tudo o que fizemos antes com outros nós de controle Como sempre, vou deixar a fonte e o tamanho da fonte como padrão do tema Na seção de ícones, podemos alterar a aparência do botão de seleção quando está marcado, desmarcado ou desativado, bem como fornecer um ícone que será usado para todos os botões de seleção em todo o projeto, a menos que seja substituído pela individual do ícone dos botões de seleção E, finalmente, na seção de estilo, temos todos os mesmos estilos que foram herdados do botão, que removerei substituindo-os todos pela caixa de estilo vazia Ao selecionar o nó do botão de verificação, pressionarei meu botão por padrão. Vou renomear meu nó âncora e a pasta ports antes de usá-los em meu script Precisaremos responder ao jogador clicar no botão de verificação conectando seu sinal a um script. Em vez do sinal pressionado que normalmente usaríamos para o botão, precisaremos saber se o botão de verificação está sendo ativado ou desativado. Portanto, conectaremos o sinal alternado, que passa o estado alternado do de Conectando isso ao meu script do gerenciador de MAP, posso reagir facilmente ao sinal com base no fato de o botão de verificação estar ou não sendo ativado ou desativado Mudando para o script de salvamento de dados, adicionarei a variável is anchored como um booleano exportado e a padronizarei Também vamos conectar o sinal de reinicialização do arquivo ao script para que possamos inicializar essa guia com as informações apropriadas dos dados salvos do player Precisarei de referências ao meu nó âncora e à matriz de nós secundários na minha pasta ports Tudo o que preciso fazer para a âncora é definir propriedade pressionada pelo botão para corresponder aos novos dados salvos Também precisarei percorrer todas as minhas portas e definir suas propriedades desativadas para corresponder se essa é ou não a porta atual do player e definir que nenhuma delas seja pressionada O botão de verificação reage ao passar o mouse e clicar nele pesa a âncora Clicar nele, novamente, solta a âncora. Agora temos um botão de verificação controlando a âncora do navio. Na próxima lição, permitiremos que o jogador controle as velas Te vejo na próxima aula. 39. Controle deslizante vertical: Olá, amigos. Na lição anterior, adicionamos um botão de verificação que controla a âncora do navio Nesta lição, usaremos um controle deslizante para controlar as vendas do navio Começarei adicionando um controle deslizante vertical ao contêiner da caixa horizontal abaixo do meu mapa Ao contrário do botão de seleção, o controle deslizante vertical não tem propriedades de texto ou ícone, então também adicionarei um nó de rótulo, que preencherei com a palavra vendas, para que corresponda ao estilo do meu controle âncora Vamos selecionar o nó deslizante vertical e dar uma olhada em suas propriedades no inspetor A caixa de seleção editável determinará se o jogador pode ou não alterar o valor desse controle deslizante, e a opção rolável mudará se ele pode fazer isso usando a roda do mouse enquanto passa o mouse enquanto A contagem de tiques adicionará linhas horizontais ao controle deslizante para indicar segmentos como um termômetro Eu terei três marcas no meu controle deslizante, e a caixa de seleção de marcas nas bordas mudará se a primeira e a última marca serão desenhadas para os valores máximo As propriedades do intervalo também são importantes para esse nó, permitindo especificar quais são os valores mínimo e máximo do controle deslizante, bem como o quanto o controle deslizante pode mudar em seu valor a cada etapa Como meu controle deslizante está sendo usado para controlar as vendas de navios, ele terá apenas três valores possíveis, zero, metade ou um para venda total Essas propriedades de intervalo também são usadas por outros nós, como a barra de rolagem, que usa a propriedade de página, mas os controles deslizantes não a usam , então podemos ignorá-la valor é o valor atual do controle deslizante, então podemos alterar o que é por padrão, e ele se ajustará automaticamente aos valores da etapa entre nosso mínimo e máximo edição exponencial distorcerá o valor para ser exponencial em vez de linear, mas somente se o valor mínimo for maior que zero Arredondado sempre arredondará o valor para o número inteiro mais próximo Permitir maior ou menor permitirá que o valor ultrapasse os valores mínimo e máximo Mas o controle deslizante não indicará que sim. Aprenderemos mais sobre essas propriedades na próxima lição. Vamos selecionar o nó raiz para que possamos ver o editor de temas e adicionar o controle deslizante vertical ao nosso tema Todas as propriedades do tema do controle deslizante vertical também estão disponíveis para controles deslizantes horizontais Como o controle deslizante não tem texto ou ícones, ele não tem cores, fonte ou tamanho da fonte Então, vamos começar na seção constante. Se a captura central for algo diferente de zero, será posicionada dentro do espaço do controle deslizante vertical base somente em seu ponto central, em vez de em todas vez E o deslocamento do agarrador pode adicionar algum deslocamento horizontal do agarrador para a esquerda Em um controle deslizante horizontal, essa mesma propriedade será um deslocamento vertical Na seção de ícones, podemos fornecer imagens diferentes para o grabber em seus estados normal, desativado e destacado, bem como a imagem usada para desenhar marcadores ao longo Vou usar uma corda como meu agarrador e uma viga transversal para meu carrapato Na seção de estilo, podemos alterar a forma como o controle deslizante é desenhado, bem como a área preenchida abaixo da barra normalmente e quando ela é destacada Para um controle deslizante horizontal, essa seria a área à esquerda do agarrador Farei com que meu controle deslizante seja uma fina linha marrom representando um mastro, e o preenchimento será uma textura de caixa estilizada que preencherei com a imagem de uma vela e a expandirei para a esquerda e para a direita, para que pareça uma Em seguida, copiarei isso, o tornarei único e alterarei a textura para quando estiver destacado. Para dar mais espaço a essa venda, substituirei minha configuração de tema para o contêiner horizontal da caixa tenha 21 pixels de espaço entre os nós secundários Ao selecionar o nó deslizante, precisamos reagir ao jogador usando o controle deslizante conectando um de seus sinais a um script Se você quiser reagir à alteração do valor somente depois que o jogador soltar o botão do mouse e parar de arrastar, conectar o sinal de encerramento de arrasto seria apropriado Mas eu quero reagir à alteração do valor mesmo enquanto o jogador ainda está pressionando o botão do mouse. Então, em vez disso, conectarei o sinal de mudança de valor e o conectarei ao meu script de gerenciamento de mapas. Vou armazenar o valor do controle deslizante de vendas nos dados salvos do player Obtendo uma referência ao nó de venda, também posso definir seu valor quando os dados salvos são Também precisarei adicionar essa variável ao script de salvamento de dados. Vamos experimentá-lo. O controle deslizante vertical reage ao passar o mouse e podemos alterar seu valor usando Também podemos clicar e arrastar o agarrador para alterar seu valor Agora temos um controle deslizante vertical controlando as velas do navio Na próxima lição, deixaremos o jogador embarcar em direção ao seu destino Te vejo na próxima aula. 40. 6 4 Barra de progresso: Olá, amigos. Na lição anterior, adicionamos um controle deslizante vertical para controlar as velas do navio Nesta lição, usaremos uma barra de progresso para indicar a distância da viagem do navio Vou adicionar um nó da barra de progresso ao contêiner da caixa horizontal abaixo meu mapa e fazer com que ele se expanda horizontalmente para preencher o espaço e, em seguida, posicioná-lo entre os controles de âncora e vela Vamos dar uma olhada em suas propriedades no inspetor. Podemos mudar a direção do preenchimento e alterar o valor para ver o efeito disso. Também podemos ativar ou desativar a exibição percentual, e a alternância indeterminada nos mostrará que algo está progredindo sem qualquer indicação de quanto progrediu , o que podemos ver se também verificarmos a opção que podemos ver se também verificarmos nos mostrará que algo está progredindo sem qualquer indicação de quanto progrediu, o que podemos ver se também verificarmos a opção de visualização em Editor. Todas as mesmas propriedades de intervalo estão aqui e funcionam da mesma forma que o controle deslizante Mas se permitirmos que o valor seja menor que o mínimo ou maior que o máximo, o valor será indicado pela porcentagem, mas não pelo preenchimento da barra de progresso Vamos selecionar o nó raiz para que possamos ver o editor de temas e adicionar a barra de progresso ao nosso tema. Como qualquer nó que tenha texto, podemos alterar a fonte e as cores do contorno da fonte e definir o tamanho do contorno na seção constante Como sempre, vou deixar a fonte e o tamanho da fonte como padrão do tema, e a barra de progresso não tem ícones para alterar Na seção de estilo, podemos alterar fundo e o preenchimento da barra de progresso, que preencherei com caixas de estilo simples Vou usar a mesma cor de fundo azul do meu painel, arredondar os cantos e adicionar algumas margens de conteúdo para torná-lo um pouco maior Em seguida, copie isso para o preenchimento, torne-o exclusivo e mude sua cor para verde. Para embarcar em nossa jornada, precisaremos conectar o sinal pressionado do botão de embarque ao script Na parte superior do script, precisarei de uma referência à minha barra de progresso. Também declararei uma variável booleana para determinar se o jogador está navegando ou não, a quantidade de tempo decorrido como flutuador e o número de dias no mar como um número inteiro Para começar a navegar, definirei a variável booleana como verdadeira. O tempo passou e os dias no mar chegaram a zero. Também vou percorrer o resto das em meu contêiner de guias e desativá-las, pois elas só devem ser acessíveis em um porto, não durante Em seguida, escreverei outra função para chegar a uma porta, aceitando um ID de porta como um número inteiro Depois que a configuração estiver navegando como falsa, habilitarei a porta de onde o jogador navegou, alterarei a porta atual para a de destino, desativarei a nova porta atual e, em seguida, definirei o destino como negativa, que significa que não há Posso então reativar as outras guias, pois o jogador agora está em uma porta Em seguida, defina o valor máximo da barra de progresso para a distância entre a porta atual e o destino e desative o botão de embarque Para navegar da porta atual até o destino, usarei a função de processo para preencher gradualmente a barra de progresso ao longo do tempo Se o jogador não estiver navegando, estiver ancorado ou as velas estiverem zeradas, nenhum progresso será feito e eu simplesmente retornarei Caso contrário, aumentarei o tempo decorrido pela Delta e, se o tempo decorrido for maior que o número de dias no mar, aumentarei os dias no mar e pagarei à tripulação e pagarei Em seguida, adicionarei ao valor da barra de progresso a velocidade atual do navio do jogador multiplicada pelo valor de venda multiplicado pela Isso fará com que o navio percorra sua velocidade em milhas náuticas a cada 1 segundo e com 1 segundo representando um dia Se o valor da barra de progresso atingir seu valor máximo, então eles chegaram ao destino. Vou precisar escrever essa função de pagamento no meu script de gerente de equipe Obtendo uma referência ao gerente de equipe usando o complemento Pronto e, em seguida, mudando para o script do gerente de equipe Primeiro, declarando uma variável para o pagamento total como um número inteiro, analisarei a equipe do Se a função da tripulação não for uma matriz, adicionarei o pagamento dessa função ao pagamento total. Se for uma matriz, analisarei novamente cada pessoa nessa função e adicionarei todo o salário ao total Precisarei de uma referência ao nó de recursos dourados para que esse script possa solicitar que o jogador gaste esse valor total. E, finalmente, gaste a quantidade de ouro necessária para pagar todos os membros da tripulação. Se o jogador não tiver dinheiro suficiente para pagar toda a equipe, esse seria um bom momento para terminar o jogo com o fim do jogo. Eu adicionei um S ao nome das minhas variáveis aqui. Vou precisar consertar isso. Ao clicar na caixa de seleção de uma porta, primeiro verifico se o jogador está navegando no momento e, em caso afirmativo, pressiono o botão que pertence ao porto de destino e retornarei Isso evitará que o jogador mude seu destino enquanto navega Se eles não estiverem navegando e estiverem definindo seu destino, definirei o valor da barra de progresso como zero Vamos experimentá-lo. O jogador pode selecionar um destino e clicar no botão de embarque para começar a navegar, mas não fará nenhum progresso em direção ao destino se estiver ancorado ou se suas velas não estiverem A velocidade do navio pode ser ajustada com a vela pela metade ou cheia Ao chegar ao destino, as guias e caixas de seleção podem ser interagidas Uma vez em um porto, o jogador pode recrutar tripulantes e, navegando para outro porto, o pagamento da tripulação será deduzido por Agora temos uma barra de progresso mostrando a distância entre o navio e seu destino. E isso abrange quase todos os nós de controle de Godo. As poucas mecânicas restantes para concluir este jogo usariam apenas mais dos mesmos nós que já usamos em outras partes do projeto Agora você deve estar pronto para concluir seu projeto. Se você está acompanhando este projeto, veja se consegue concluir o market tap deste jogo e adicionar uma tela de fim de jogo. Boa sorte