Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Xcode
Code

Uma introdução ao GameplayKit: Parte 3

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called An Introduction to GameplayKit.
An Introduction to GameplayKit: Part 2

Portuguese (Português) translation by David Batista (you can also view the original English article)

Esta é a terceira parte do Uma introdução ao GameplayKit. Se você ainda não passou pela primeira e segunda parte, então eu recomendo a leitura do primeiro tutorial antes de continuar com este.

Introdução

Neste terceiro e último tutorial, eu irei ensinar à você sobre mais duas funcionalidades que você pode usar em seu próprio jogo:

  • geradores de valor aleatório
  • sistemas de regras

Neste tutorial, utilizaremos primeiro os geradores de valor aleatório do GameplayKit para otimizar nosso algoritmo de aparição inicial dos inimigos. Então implementaremos um sistema básico de regras em combinação com outra distribuição aleatória para lidar com o comportamento de respawn dos inimigos.

Para este tutorial, você pode usar sua cópia do projeto completada no segundo tutorial ou fazer download de uma cópia fresca do código fonte no GitHub.

1. Geradores de valor aleatório

Valores aleátorios podem ser gerados no GameplayKit usando qualquer classe que estiver em conformidade com o protocolo GKRandom. O GameplayKit fornece cinco classes em conformidade com este protocolo. Estas classes contêm três fontes aleatórias e duas distribuições aleatórias. A principal diferença entre as fontes aleatórias e as distribuições aleatórias é que as distribuições usam uma fonte aleatória para produzir valores em um range específico e podem manipular o valor aleatório de saída de várias outras maneiras.

As classes mencionadas acima são fornecidas pelo framework de modo que você possa conseguir um balanço entre performance e aleatoriedade para seu jogo. Alguns algorítimos geradores de valor aleatório são mais complexos do que outros e consequentemente impactam na performance.

Por exemplo, se você precisa gerar um número aleatório a cada frame (sessenta vezes por segundo), então seria melhor usar um algorítimo mais rápido. Em contraste, se você raramente gera um valor aleatório, você pode usar um algorítimo mais complexo a fim de produzir um melhor resultado. 

As três classes de fontes aleatórias fornecidas pelo framework GameplayKit são GKARC4RandomSource, GKLinearCongruentialRandomSource e GKMersenneTwisterRandomSource.

GKARC4RandomSource

Esta classe usa um algorítimo ARC4 e é adequada para a maioria dos propósitos. Este algorítimo funciona produzindo uma série de números aleatórios baseado em um valor raiz. Você pode inicializar um GKARC4RandomSource com um valor raiz se você precisar replicar um comportamento aleatório para outra parte do seu jogo. A raiz de uma fonte existente pode ser recuperado em sua propriedade somente leitura seed.

GKLinearCongruentialRandomSource

Está classe de fonte aleatória usa o algoritmo básico gerador de correspondência linear. Este algorítimo é mais eficiente e com uma performance melhor do que o algorítimo ARC4, mas também gerá valores que são menos aleatórios. Você pode buscar um valor rais do objeto GKLinearCongruentialRandomSource e criar uma fonte com ele da mesma maneira que o objeto GKARC4RandomSource.

GKMersenneTwisterRandomSource

Esta classe usa o algorítimo Mersenne Twister e gerá o mais randômico dos resultados, mas ele é também o menos eficiente. Como as duas outras classes de fontes aleatórias, você pode recuperar o valor rais do objeto GKMersenneTwisterRandomSource e usa-la para criar uma nova fonte.

As duas classes de distribuição aleatória no GameplayKit são GKGaussianDistribution e GKShuffledDistribution.

GKGaussianDistribution

Este tipo de distribuição garante que o valor gerado aleatoriamente siga uma distribuição Gaussian, também conhecida como uma distribuição normal. Isto significa que a maioria dos valores gerados cairão no meio do range especificado.

Por exemplo, se você definir o objeto GkGaussianDistribution com um valor mínimo de 1, um máximo de 10 e um desvio padrão de 1, aproximadamente 69% dos resultados estarão entre 4, 5 e 6. Eu explicarei está distribuição com mais detalhes quando adicionarmos ela em nosso jogo mais tarde neste tutorial.

GKShuffledDistribution

Está classe pode ser usada para certificar que os valores aleatórios são uniformemente distribuídos ao longo do intervalo especificado. Por exemplo, se você gerar valores entre 1 e 10, e um 4 for gerado, outro 4 não será gerado até que todos os outros números entre 1 e 10 tenham sido gerados.

Agora vamos colocar tudo isso em prática. Nós iremos adicionar duas distribuições aleatórias para nosso jogo. Abra seu projeto no Xcode e vá para o arquivo GameScene.swift. A primeira distribuição aleatória que iremos adicionar é um GKGaussianDistribution. Em seguida, iremos adicionar também um GKShuffledDistribution. Adicione as duas propriedades a seguir à classe GameScene.

Neste trecho, criamos duas distribuições com um valor mínimo de 0 e um valor máximo de 2. Para o GKGaussianDistribution, a média e o desvio são automaticamente calculados segundo a equação abaixo:

  • média =  (máximo - mínimo) / 2
  • desvio = (máximo - mínimo) / 6

A média de uma distribuição Gaussian é o seu ponto médio e o desvio é usado para calcular qual a porcentagem dos valores que devem estar dentro de um determinado range médio. A porcentagem dos valores dentro de um determinado range é:

  • 68,27% dentro de 1 desvio na média
  • 95% dentro de 2 desvios da média
  • 100% dentro de 3 desvios da média

Isso significa que aproximadamente 69% dos valores gerados devem ser igual a 1. Isso resulta em uma proporção maior de pontos vermelhos em relação aos pontos verdes e amarelos. Para fazer isso funcionar, você precisa atualizar o método initalSpawn.

Dentro do laço for, substitua a seguinte linha:

pela seguinte:

O método nextInt pode ser chamada por qualquer objeto que esteja em conformidade com o protocolo GKRandom e retornará um valor aleatório baseado na fonte e, se aplicável, a distribuição que você esta usando.

Compile e rode seu app e mova-se pela mapa. Você poderá ver muito mais pontos vermelhos em comparação com ambos os outros pontos, verdes e amarelos.

Large proportion of red dots

A segunda distribuição aleatória que iremos usar em nosso jogo, vai entrar em cena quando tratarmos o comportamento de respawn baseado no sistema de regras.

2. Sistemas de regras

Os sistemas de regras do GameplayKit são usados para melhorar a organização da lógica condicional para seu jogo e também introduzir a lógica fuzzy. Com a introdução da lógica fuzzy, você pode fazer as entidades dentro do seu jogo tomarem decisões baseadas em um range de regras e variáveis diferentes, como a vida do jogador, quantidade corrente de inimigos e a distância para o inimigo. Isto pode ser muito vantajoso se compararmos com simples instruções if e switch.

Os sistemas de regras, representados pela classe GKRuleSystem, têm três partes chaves:

  • Agenda. Este é o conjunto de regras que será adicionado ao sistema de regras. Por padrão, estas regras são validadas na ordem em que forem adicionas ao sistema de regras. Você pode alterar a propriedade salience para qualquer regra especifica quando você quiser que ela seja validada.
  • Informação de estado. A propriedade state de um objeto GKRuleSystem é um dicionário que você pode adicionar qualquer dado, incluindo tipos de objeto customizados. Este dado pode então ser usado pelas regras do seu sistema de regras quando retornar o resultado.
  • Fatos. Os fatos dentro de um sistema de regras representa as conclusões tiradas pela validação das regras. Um fato também pode ser representado por qualquer tipo de objeto dentro do seu jogo. Cada fato tem também um grau de registro, que é um valor entre 0.0 e 1.0. Este grau de registro representa a inclusão ou presença do fato dentro do sistema de regras.

As próprias regras, representadas pela classe GKRules, têm dois componentes principais.

  • Predicado. Esta parte da regra retorna um valor booleano, indicando se os requisitos da regra foram atendidos. Um predicado de regra pode ser criado usando um objeto NSPredicate ou, como nós veremos em nosso tutorial, um bloco de código.
  • Ação. Quando o predicado da regra retorna true, a ação é executada. Esta ação é um bloco de código onde você pode realizar qualquer lógica se o requerimento da regra for cumprido. Aqui é onde você geralmente afirma (adiciona) ou retrair (remove) os fatos dentro do sistema de regra pai.

Vamos ver como tudo isso funciona na prática. Para nosso sistema de regra, nós iremos criar três regras, conforme a seguir:

  • a distância do ponto de aparição para o jogador. Se este valor for relativamente pequeno, nós aumentaremos a probabilidade da aparição dos pontos vermelhos.
  • a quantidade atual de nós no cenário. Se for muito alta, não queremos que mais pontos sejam adicionados ao cenário.
  • se houver um outro ponto presente no local de aparição. Se não tiver, então iremos gerar um novo ponto no lugar.

Primeiro, adicione a propriedades a seguir à classe GameScene:

Em seguida, adicione o trecho de código a seguir ao método didMoveToView(_:):

Com este código, criamos três objetos GKRule e adicionamos eles ao sistema de regras. As regras afirmam um fato particular dentro de seu bloco de ação. Se você não fornecer um valor de grau e chamar o método assertFact(_:), como fazemos com o playerDistanceRule, é dado um grau padrão de 1.0 ao fato.

Você notará que para o nodeCountRule nós afirmamos o fato "shouldSpawn" com um grau de 0.5. O nodePresentRule então afirma este mesmo fato e adiciona um grau de 0.5. Isso é feito para que quando verificamos os fatos mais tarde, um valor de grau de 1,0 significa que ambas as regras tenham sido satisfeitas.

Você também verá que ambos, o playerDistanceRule e o nodePresentRule, acessam o valor "spawnPoint" do dicionario state do sistema de regra. Iremos definir este valor antes de validar o sistema de regras.

Por último, procure e substitua o método respawn na classe GameScene com a implementação a seguir:

Este método irá ser chamando uma vez por segundo e é muito similar ao método initialSpawn. Embora haja algumas diferenças importantes dentro do laço for.

  • Primeiro reiniciamos o sistema de regra chamando o método reset. Isto é precisa ser feito quando o sistema de regra for sequencialmente validado. Isto remove todos os fatos alegados e dados relacionados, para assegurar que nenhuma informação sobrou da validação anterior que possa interferir na atual.
  • Então atribuímos o local de aparição ao dicionário state do sistema de regras. Usamos um objeto NSValue, porque o tipo de dado CGPoint não esta em conformidade com o protocolo AnyObject do Swift e não pode ser atribuído para esta propriedade NSMutableDictionary.
  • Validamos o sistema de regras chamando o método evaluate.
  • Em seguida recuperamos o grau de registro do sistema de regras para o fato "shouldSpawn". Se for igual a 1, continuamos a dar respawn no ponto.
  • Por último, verificamos o grau do sistema de regras para o fato "spawnEnemy", se for igual a 1, usamos normalmente o gerador aleatório distribuído para criar o nosso spawnFactor.

O restante do método respawn é a mesma coisa do método initialSpawn. Compile e rode seu jogo uma última vez. Mesmo sem se mover, você verá novos pontos aparecendo quando as condições necessárias serem atendidas.

Respawning dots

Conclusão

Nesta série do GameplayKit, você aprendeu bastante. Vamos resumir brevemente o que abordamos.

  • Entidades e Componentes
  • Máquinas de estado
  • Agentes, metas e comportamentos
  • Busca de caminho
  • Geradores de valor aleatório
  • Sistemas de regras

O GameplayKit é um adição importante ao iOS 9 e ao OS X El Capitan. Ele elimina muito da complexidade do desenvolvimento de jogos. Eu espero que esta série tenha motivado você a experimentar mais do framework e a descobrir do que ele é capaz.

Como sempre, por favor não esqueça de deixe seu comentario e feedback abaixo.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.