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