Advertisement
  1. Code
  2. SpriteKit

Criar Space Invaders com Swift e SpriteKit: Implementando classes

This post is part of a series called Create Space Invaders with Swift and Sprite Kit.
Create Space Invaders With Swift and SpriteKit: Introducing SpriteKit
Create Space Invaders With Swift and SpriteKit: Implementing Gameplay

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

Final product imageFinal product imageFinal product image
What You'll Be Creating

Na primeira parte desta serie, nós exploramos o básico do framework SpriteKit e implementamos a tela de inicio do jogo. Neste tutorial, nós iremos implementar a classe principal do jogo.

O Swift é uma linguagem orientada a objetos e iremos tirar vantagem disto, separando todas as entidades do jogo em suas proprias classes. Começaremos implementando a classe Invader.

1. Implementando a classe Invader

Passo 1: Criar a classe Invader

Selecione New > File... no menu File do Xcode, escolha Cocoa Touch Class na seção iOS > Source e clique em Next. Chame a classe de Invader e certifique que ela herde do SKSpriteNode. Certifique que a Language esteja definida como Swift. Entre com o código a seguir na Invader.swift.

A classe Invader é uma subclasse da classe SKSpriteNode. Ela tem duas propriedades, invaderRow e invaderColunm. Os invasores serão alinhados em um grade como o jogo Space Invaders original. As duas propriedades iram nós dar um auxílio no controlo de qual linha ou coluna o invasor está.

No método init, nós inicializamos um instância SKTexture. O método init(imageNamed:) recebe uma imagem como parâmetro. Então chamamos o inicializador da superclasse, passando a texture, SKColor.clearColor para o parâmetro color e para o parâmetro size nós passamos o tamanho da textura. Para finalizar, nós definimos o nome de "invader" para podermos identifica-lo mais tarde.

O método init é um inicializador designado, o que significa que nós precisamos delegar a incialização para um inicializador designado da superclasse da Invader. Por isso que chamamos o método init(texture:color:size:).

Você deve estar se perguntando sobre o método requerid init(coder:) que está la também. O SKSpriteNode precisar estar em conformidade com o protocolo NSCoding. O método init(coder:) está marcado como necessário, o que significa que todas as subclasses precisam sobrepor este método.

Implementaremos o método fireBullet mais tarde neste tutorial.

Passo 2: Adicionando os invasores no cenário

Neste passo, adicionaremos os invasores no GameScene. Abra a GameScene.swift e delete tudo que há dentro do método didMoveToView(_:) como também tudo que há dentro do método touchesBegan(_:withEvent:). O conteúdo da GameScene.swift deverá ficar como abaixo. 

Nós teremos uma variável global em nosso projeto, invaderNum. Está variável será usada para manter o controle do nível atual do jogo. Declarando ela como uma variável global, nós teremos acesso à invaderNum através dos cenários. Para declarar a variável como uma variável global, nós declaramos ela fora da classe GameScene.

Em seguida, adicionamos as propriedades abaixo na classe GameScene.

A propriedade rowsOfInvaders será quantas linhas de invasores o jogo terá e a propriedade invaderSpeed é quão rápido os invasores se movem. As propriedades leftBounds e rightBounds são usadas para criar uma margem no lado esquerdo e lado direito da tela, restringindo o movimento dos invasores no sentido esquerdo e direito. E finalmente, a propriedade invadersWhoCanFire é um array que é usado para manter o controle de quais invasores podem atirar.

Adicione o método setupInvaders abaixo do método update(currentTime:) na classe GameScene.

Nós temos as variáveis invaderRow e invaderColunm que serão usadas para definir as propriedades com o mesmo nomes do invasor. Em seguida usamos um duplo loop de for para posicionar os invasores na tela. Há varias conversões de tipo numérico acontecendo, porque o Swift não converte implicitamente números para o tipo apropriado. Temos de fazer nós mesmos.

Primeiro instanciamos um novo Invader, tempInvader, e depois declaramos uma constante invaderHalfWidth que recebe a metade do tamanho do tempInvader.

Em seguida, nós calculamos o xPositionStart de modo que os invasores serão sempre alinhados no meio do cenário. Pegamos a metade da largura do cenário e subtraímos a metade da largura do invasor, desde o ponto de registro padrão é o centro (0.5, 0.5) do sprite. Em seguida, temos de subtrair a largura vezes a quantidade de invasores, invaderNum, e adicionamos 10 pontos de espaço a esse valor, uma vez que vamos manter 10 pontos de espaço entre os invasores. Isto pode ser um pouco difícil de compreender no início, então, gaste um tempo para entendê-lo.

Então definimos a propriedade position do invader, que é um GGPoint. Nós usamos um pouco mais de matemática para certificar-se de que cada invasor tem 10 pontos de espaço entre eles e que cada linha tem 46 pontos de espaço entre eles.

Nós atribuímos as propriedade invaderRow e invaderColumn, e adicionamos o tempInvader ao cenário com o método addChild(_:). Se for a ultima linha de invasores, nós colocamos o tempInvader no array invadersWhoCanFire.

O método setupInvaders é chamado no método didMoveToView(_:). Neste método, nós também definimos a propriedade backgroundColor com SKColor.blackColor.

Se você testar o aplicativo, você verá 4 linhas com 3 invasores. Se você definir o invaderNum com 2, você verá 4 linhas com 5 invasores alinhados no centro do cenário.

2. Implementando a classe Player

Passo 1: Criar a classe Player

Crie um novo Cocoa Touch Class chamada Player que é uma subclasse de SKSpriteNode. Adicione a seguinte implementação à Player.swift.

O método init lhe parecerá familiar. A unica diferença é que nós iremos usar uma imagem diferente para a configuração inicial. Há duas imagens chamadas player1 e player2 na pasta de imagens, uma tem o propulsor ligado e a outro tem o propulsor desligado. Nós iremos trocar constantemente entre as duas imagens, criando uma ilusão de o propulsor disparar e desligar. Isto é o que o método animate faz.

No método animate, nós temos um array playerTextures que conterá as texturas para a animação. Nós adicionamos objetos SKTexture neste array usando um loop for-in e um intervalo fechado usando um operador de intervalo fechado. Nós usamos interpolação de string para pegar a imagem correta e inicializar uma instância SKTexture.

Nós declaramos uma constante, playerAnimation, que chama o método repeatActionForever da classe SKAction. Nesta ação, nós chamamos animateWithTextures(_:timePerFrame:). O método animateWithTextures(_:timePerFrame:)  recebe como parâmetro um array de texturas e a quantidade de tempo que cada textura será apresentada. Por ultimo, chamamos runAction(_:) e passamos ao playerAnimation.

Os outros métodos vão ser implementados mais tarde neste tutorial.

Passo 2: Adicionando o jogador ao cenário.

Declare uma propriedade constante chamada player na classe GameScene.

Em seguida, adicione o método setupPlayer abaixo do método setupInvaders.

Você deve achar familiar a implementação do método setupPlayer. Nós definimos a position do player e adicionamos ele ao cenário. Entretanto, nós vamos usar uma nova função, CGRectGetMidX(_:), que retorna o centro de um retângulo com base em seu eixo x.  Aqui usamos o frame da scene.

Você pode chamar agora o método setupPlayer no método didMoveToView(_:).

Se você testar o aplicativo, você verá o jogador adicionado na parte inferior da tela com o propulsor ligado e atirando.

3. Implementando a classe Bullet

Passo 1: Criar a classe Bullet

Crie uma nova Cocoa Touch Class chamada Bullet que é uma subclasse da classe SKSpriteNode.

O método init recebe dois parâmetros, imageName e bulletSound. O segundo parâmetro é opcional. O jogador tocará um som de laser toda vez que atirar. Eu não irei criar os invasores fazendo isso neste jogo, embora você certamente possa fazer. Também por essa rasão que o som de tiro é um parâmetro opcional. Você poderia até usar um som diferente para cada um.

A primeira parte vai ser familiar, embora estejamos criando agora a texture com qualquer imagem que for passada no primeiro argumento. Isto permitirá que você use imagens diferentes para os tiros do jogador e do invasor se você quiser.

Se a bulletSound não for igual a nil, nós executamos um método SKActionplaySoundFileNamed(_:waitForCompletion:). Este método recebe como parâmetro uma String, que é o nome do arquivo de som, incluindo a extensão, e um Bool, waitForCompletion. O parâmetro waitForCompletion não é importante para nós. Se estiver definido como true, então a ação irá durar até o final do arquivo de som.

Passo 2: Crie a classe InvaderBullet

Crie uma nova Cocoa Touch Class chamada InvaderBullet que é uma subclasse da classe Bullet .

A implementação da classe InvaderBullet pode não fazer muito sentido, porque apenas chamamos o método init(imageName:bulletSound:) da superclasse no inicializador init(imageName:bulletSound:). No entanto, fará muito mais sentido porque ele está definido desta forma quando adicionamos código para detecção de colisão.

Passo 3: Crie a classe PlayerBullet

Crie uma nova Cocoa Touch Class chamada PlayerBullet que também é uma subclasse da classe Bullet . Como você pode ver, a implementação da classe PlayerBullet é idêntica a classe InvaderBullet.

Conclusão

Neste tutorial, nós criamos e implementamos algumas das classes chave para o jogo. Nós adicionamos uma grade de invasores no cenário e uma nave que o jogador irá controlar. Nós continuaremos a trabalhar com essas classe na próxima parte desta serie em que vamos implementar o gameplay.

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

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.