Sie sind auf Seite 1von 34

Tutorial de Programao Swift para iOS 8 Introduo

Xcode 6

Swift a nova linguagem de programao que j lhe falamos em


postes anteriores e voc pode usar para criar aplicativos para iOS ou para OSX.

Esta nova linguagem substitui Objective-C como a linguagem de padro para aplicaes
mveis da Apple. Neste tutorial de programao Swift vamos apresentar-lhe a sintaxe
Swift essencial que voc vai precisar para comear a criar as suas aplicaes, bem como
uma introduo Xcode 6 esta nova ferramenta da Apple.

Baixar Xcode 6
As primeiras coisas primeiro: voc deve ter ou baixar Xcode 6 e o iOS 6 para trabalhar
com Swift. O beta do SDK ja est disponvel mas apenas para desenvolvedores da
Apple registradas em http://developer.apple.com .

Na nossa opinio vale a pena a pagar a taxa de inscrio de $99 para se tornar um
desenvolvedor Apple. Caso contrrio voc tem esperar at que o Xcode 6 esteja fora da
verso beta o que acontecer no outono e ai sim disponvel gratuitamente na App Store
para todos.

Caso no queira esperar at ao outono nem queira gastar dinheiro pode sempre
aproveitar o j circula pela internet clicando Aqui .

Ento, baixe o Xcode 6 continuemos com este tutorial.

Ol Mundo
Como no podia deixar de ser vamos comear este tutorial com o clssico aplicativo
Ol Mundo Hello World.

Apenas iremos usar Swift para dizer o texto Ol Mundo. Para que isso acontea vamos
precisar de criar um novo playground com o Xcode 6. Playgrounds so uma espcie
de rascunho que voc pode usar para testar e brincar com o seu cdigo Swift.

Criar um Novo Playground

1
Vamos abrir o Xcode 6 (beta) e ser apresentada uma tela que lhe dar
algumas opes e uma lista de arquivos j abertos em outras verses do Xcode.

Clique na opo que diz Comece com um playground Get started with
aplayground.

Xcode ir solicitar qual o nome e onde pretende guardar o projeto. Escolha o que
preferir, eu simplesmente mantive o nome padro do MyPlayground.

Agora ser apresentada uma tela que funciona como um rascunho. Este o
playground. Voc vai usar isso para digitar cdigo e ver imediatamente os
resultados. Na verdade Xcode j coloca algum cdigo l para voc.

1 // Playground - noun: a place where people can play


2
3 import Cocoa
4 var str = "Hello, playground"

Ento foi fcil?

Existem duas linhas no cdigo de exemplo fornecido pelo Xcode. A primeira uma
declarao de importao que necessrio para importar o Framework Cocoa.

1 <p style="color: #141412;">import Cocoa</p>

Cocoa uma livraria que usada para criar aplicativos Mac, ns precisamos dela
porque estamos a executar este playground em um Mac.

A segunda parte uma declarao de uma varivel.

1 var str = "Hello, playground"

Assim como outras linguagens de programao, Swift usa variveis para armazenar
informaes que podem variar ao longo do tempo. A instruo var informa-nos que
uma varivel str com valor inicial de Hello, playground.

2
Bem, parabns voc acabou de ver o seu primeiro programa em Swift. Como poder
ver, o resultado da varivel str automaticamente apresentado direita.
Mantenha o playground aberto de forma a poder us-lo para brincar com o cdigo que
voc ver neste tutorial.

Vamos seguir em frente, agora iremos criar um simples aplicativo com Xcode em Swift.
Por agora poder continuar o tutorial e fechar o seu playground.

Criar um novo iOS App com Swift


Clique em Xcode> File> New> Project

E escolha iOS> Application > Single View Application

Aparecer uma caixa deste gnero:

Certifique-se de que escolhe Swift como Linguagem e clique Next.

Agora poder clicar no boto Build and Run para executar a aplicao como voc faria
com uma aplicao Objective-C construda numa verso anterior do Xcode. Mas claro
que ao fazer isso agora voc apenas vai obter um aplicativo com uma tela branca vazia.

Veja o Cdigo Swift


No Project Explorer, clique no ficheiro chamado ViewController.swift para ver o seu
contedo com cdigo escrito em Swift. Ele ser parecido com este:

3
<p class="p1"><strong><span class="s1">import</span> UIKit</strong></p>
<p class="p1"><strong><span class="s1">class</span> ViewController: <span
class="s2">UIViewController</span> {</strong><strong>
</strong></p>
<p class="p1"><strong> <span class="s1">override</span> <span
1 class="s1">func</span> viewDidLoad() {</strong></p>
2 <p class="p1"><strong> <span class="s1">super</span>.<span
3 class="s3">viewDidLoad</span>()</strong></p>
4 <p class="p3"><strong><span class="s4"> </span>// Do any additional setup
5 after loading the view, typically from a nib.</strong></p>
6 <p class="p1"><strong> }</strong></p>
7 <p class="p1"><strong> <span class="s1">override</span> <span
8 class="s1">func</span> didReceiveMemoryWarning() {</strong></p>
9 <p class="p4"><strong><span class="s4"> </span><span
10 class="s1">super</span><span
11 class="s4">.</span>didReceiveMemoryWarning<span
class="s4">()</span></strong></p>
<p class="p3"><strong><span class="s4"> </span>// Dispose of any resources
that can be recreated.</strong></p>
<p class="p1"><strong> }</strong></p>
<p class="p1"><strong>}</strong></p>

Se voc est familiarizado com aplicaes para iOS escritas em Objective-C este cdigo
certamente familiar para voc. Voc pode ver como Swift referencia os mesmos
frameworks UIKit que voc est acostumado.

Agora vamos trabalhar na nossa aplicao um pouco com a nova verso do Xcode
6. Vamos adicionar um boto e uma legenda com a ajuda do Editor Assistente.

Adicionar controlos de utilizador


Clique no ficheiro chamado Main.storyboard para abrir a interface do aplicativo em
Interface Builder.

Use a Object Library, o widget no canto inferior direito do Xcode, para localizar e
arrastar um boto e uma Label para o View Controller.

4
Agora use o Editor Assistente para ligar a Label ao ficheiro ViewController. Voc
deve ter um @IBOutlet para a sua label.

5
NOTA: A criao de interfaces no Xcode no mudou muito, mas se voc nunca fez isso
antes no se preocupe ns abordamos este tema em outro tutorial para que se sinta
vontade com qualquer tema.

Agora use o Assistant Editor para codificar e receber um @IBAction do boto. O seu
ficheiro de cdigo deve ficar assim:

import UIKit
1
2
class ViewController: UIViewController {
3
4
<span id="inlinecode" style="font-weight: bold; color: blue;">@IBOutlet var
5
Label1 : UILabel</span>
6
7
override func viewDidLoad() {
8
super.viewDidLoad()
9
// Do any additional setup after loading the view, typically from a nib.
10
}
11
12
override func didReceiveMemoryWarning() {
13
super.didReceiveMemoryWarning()
14
// Dispose of any resources that can be recreated.
15
}
16
17
}

6
Voc pode ver a sada e a ao?

Agora ns podemos adicionar o uso dessa interface para apresentar a mensagem Ol


Mundo usando o boto. O texto ser apresentado na label conectada. Use o
cdigo abaixo como um guia para adicionar o mtodo de ao do seu prprio projeto.

import UIKit
1
2
class ViewController: UIViewController {
3
4
@IBOutlet var Label1 : UILabel
5
6
override func viewDidLoad() {
7
super.viewDidLoad()
8
// Do any additional setup after loading the view, typically from a nib.
9
}
10
11
override func didReceiveMemoryWarning() {
12
super.didReceiveMemoryWarning()
13
// Dispose of any resources that can be recreated.
14
}
15
16
<span id="inlinecode" style="font-weight: bold; color: blue;">@IBAction func
17
myAction(sender : AnyObject) {
18
Label1.text = "Ol Mundo"
19
}</span>
20
21
}

Depois de codificar e execute a aplicao para um teste.

Se a sua aplicao no est a funcionar certifique-se de que seus outlets aes esto
ligados. Voc tambm pode reposicionar os seus controlos de utilizador para se
certificar de que voc consegue v-los no simulador.

NOTA a nova verso do Xcode tem mudanas na maneira como o autolayout


apresentado pelo que voc pode encontrar-se em um novo territrio, se voc est
acostumado a lidar com o layout de uma forma particular. No se preocupe muito
com isso estes tutoriais so apenas para demonstrar como um simples problema se
resolve em Swift.

7
Tutorial Como Desenhar Fsica em Swift
AVISO: Usando o Xcode 6 Beta 5, o cdigo em baixo s ir funcionar quando usado
em um dispositivo real. O simulador em Beta 5 deu um enorme passo para trs e no
funciona l muito bem. Esperemos que isso mude na prxima verso beta.

Bem-vindo mais uma vez, hoje vamos voltar a usar Swift, a lngua recm-lanada da
Apple e que j nos estamos a habituar. Com sorte, voc um developer e tem acesso ao

novo Xcode 6 beta, caso contrario hoje o seu dia de sorte veja aqui como o
obter Tutorial de Programao Swift para iOS 8 Introduo Xcode 6.

O objetivo do Tutorial Como Desenhar Fsica em Swift criar um ambiente em que a


fsica permita que voc desenhe qualquer forma que imagine e ela ir tornar-se num
objeto de fsica com peso e colises.

Para comear, voc precisa configurar seu ambiente.

Selecione um novo projecto Game.

Iremos escolher Swift como a nossa lngua e SpriteKit como o Game Technology.
Escolha o nome que quiser para o seu projecto.

8
Agora temos o nosso projeto com base SpriteKit que quando simulada (eu vou
usar iPad Retina, como simulador) apresenta um Ol Mundo SKLabel. Se voc
tocar na tela, voc ver uma nave espacial girando fora de controle. Legal!

Primeiro vamos nos livrar desse lixo. A demo da nave espacial legal mas vamos fazer
algo muito melhor. Abra o seu arquivo GameScene.swift e a funo didMoveToView.
Voc achou? Boa! Agora limp-la:

1 override func didMoveToView(view: SKView)


2{
3}

Continue na limpeza e livre-se da funo touchesBegan. Esta uma funo que


reconhece o toque mas no tm utilidade para aqui. Alm disso, ns no precisamos da
funo de update para este projeto, mas uma boa prtica mant-lo no GameScene.
No fim, o arquivo GameScene.swift deve ser parecido com este:

1 // GameScene.swift
2 // FisicaDesenhada
3 import SpriteKit
4
5 class GameScene: SKScene {

9
6 override func didMoveToView(view: SKView)
7 {
8 }
9
10 override func update(currentTime: CFTimeInterval)
11 {
12 }
13 }

J limpamos tudo e est na hora de escrever cdigo! Vamos adicionar muito codigo no
GameScene.

Por agora ns s precisamos fazer uma mudana rpida no arquivo


GameViewController.swift. Se o GameScene a tela de seu projeto SpriteKit, o
GameViewController pode ser visto como o cavalete.

Abra o arquivo GameViewController.swift e encontre a funo viewDidLoad. E


tornea parecida com a seguinte:

override func viewDidLoad() {


1
super.viewDidLoad()
2
3
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
4
// Configure the view.
5
let skView = self.view as SKView
6
skView.showsFPS = true
7
skView.showsNodeCount = true
8
9
/* Sprite Kit applies additional optimizations to improve rendering
10
performance */
11
skView.ignoresSiblingOrder = true
12
13
/* Set the scale mode to scale to fit the window */
14
scene.scaleMode = .AspectFill
15
scene.size = skView.bounds.size
16
skView.presentScene(scene)
17
}
18
}

A linha 15 foi adicionada a esta funo. Isso permite-nos referenciar o tamanho da cena
ao criar o nosso esquema de fsica que ir manter os nossos desenhos e evitar que eles
vo cair no espao infinito. Tambm ir ajudar com a traduo das posies de sprites
quando estamos desenhando. Se no percebeu no se preocupe isso vai fazer sentido em

10
breve. Voltamos para GameScene.swift e adicione a seguinte funo abaixo da funo
de update:

func setupScene(){
1
self.backgroundColor = UIColor.whiteColor()
2
self.physicsWorld.gravity = CGVectorMake(0, -9.8)
3
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRect(x: 0, y: 0, width:
4
self.size.width, height: self.size.height))
5
}

Esta funo faz trs coisas:

Define a cor de fundo para branco


Cria gravidade.
Cria um corpo fsica edgeloop que ir manter os nossos desenhos contidos no ecr
visvel.

Agora actualize a didMoveToView para chamar a nossa nova funo:

1 override func didMoveToView(view: SKView) {


2 setupScene()
3}

Na prxima parte vamos precisar de trs variveis globais. Vamos para cima e
encontramos a declarao de classe:

1 class GameScene: SKScene {


2 var currentPath = CGPathCreateMutable()
3 var currentDrawing = SKShapeNode()
4 let lineWidth : CGFloat = 4

Nas linhas 2,3 e 4 acrescentam as trs globais que precisamos:

currentPath O caminho que vai usar para acompanhar onde o usurio est
desenhando
currentDrawing O desenho que ir alterar continuamente para dar o efeito de desenho

11
na tela
lineWidth A largura do trao do desenho

Prosseguindo ! Adicione a seguinte funo abaixo da funo setupScene:

1 func setupGlobals(){
2 currentDrawing.strokeColor = UIColor.blackColor()
3 currentDrawing.lineWidth = lineWidth
4}

Isso s para configurar o nosso desenho com a cor certa e a largura da linha.
Novamente abaixo da funo setupScene adicione a seguinte:

func setupGestureRecognizers()
1
{
2
self.view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action:
3
Selector("handlePan:")))
4
}

A funo setupGestureRecognizers acrescenta a UIPanGestureRecognizer na nossa


cena. Este tipo de reconhecedor detecta quando um usurio est arrastando o dedo
pela tela. Observe que o reconhecedor de gestos est esperando um Selector
handlePan:. Este o lugar onde a segunda funo entra.

1 func handlePan(panReco:UIPanGestureRecognizer){
2 let touchLoc =
3 self.convertPointFromView(panReco.locationInView(panReco.view))
4
5 if panReco.state == UIGestureRecognizerState.Began{
6 CGPathMoveToPoint(currentPath, nil, touchLoc.x, touchLoc.y)
7 }
8 else if panReco.state == UIGestureRecognizerState.Changed{
9 CGPathAddLineToPoint(currentPath, nil, touchLoc.x, touchLoc.y)
10 //adjustDrawing()
11 }
12 else if panReco.state == UIGestureRecognizerState.Ended{
13 CGPathAddLineToPoint(currentPath, nil, touchLoc.x, touchLoc.y)

12
CGPathCloseSubpath(currentPath)
14
15
//addObject()
16
17
currentDrawing.removeFromParent()
18
currentPath = CGPathCreateMutable()
19
}
20
}

Repare que as linhas 9 e 15 esto comentadas. Ns no adicionamos essas funes


ainda, ento vamos deixa-las assim por agora.

Agora uma explicao do que handlePan faz ! A primeira coisa que


fazemos em handlePan descobrir onde o dedo do usurio est na tela. Em seguida
usamos isso para resto da funo. A parte restante do handlePan pode ser dividida em
trs partes:

Se o gesto pan acaba de comear, precisamos comear o caminho. Pense nisso como
o colocar a caneta no papel.
Se o local gesto pan mudou, precisamos mover o caminho para esse local, e em
seguida mostrar a mudana para o usurio.
Se o gesto pan acabou, precisamos fechar nosso caminho e criar o corpo de fsica.

Prosseguindo vamos adicionar ao didMoveToView as nossos funes setupGlobals


e setupGestureRecognizers:

1 override func didMoveToView(view: SKView) {


2 setupScene()
3 setupGlobals()
4 setupGestureRecognizers()
5}

Agora precisamos adicionar as duas funes que tratam da exibio do nosso desenho e
criao de objetos. Estas so tambm as duas funes que atualmente so comentadas
na funo handlePan. Primeiro vamos adicionar a funo adjustDrawing.

13
1 func adjustDrawing(){
2 currentDrawing.removeFromParent()
3 currentDrawing.path = currentPath
4 self.addChild(currentDrawing)
5}

Esta funo faz:

Remove o currentDrawing da cena temporariamente.


Actualiza o caminho do currentDrawing (Caminho desenhado pelo usurio
naquele momento).
Adiciona o currentDrawing, volta para a cena com as alteraes feitas.

No assim to difcil! Vamos agora adicionar a segunda funo que vamos precisar:

func addObject(){
let shapeNode = SKShapeNode(path: currentPath)
shapeNode.strokeColor = getRandomColor()
1
shapeNode.fillColor = getRandomColor()
2
shapeNode.lineWidth = lineWidth
3
4
// COMPLICADO: Voc deve adicionar o n na cena antes de chamar
5
self.view.textureFromNode() ou voc no vai ter a verso retina(HQ) da textura para
6
passar para o SKSpriteNode
7
self.addChild(shapeNode)
8
let spriteNode = SKSpriteNode(texture: self.view.textureFromNode(shapeNode),
9
size: shapeNode.frame.size)
10
shapeNode.removeFromParent()
11
12
// COMPLICADO: Voc deve definir a posio do spriteNode no centro do quadro
13
do shapeNode para manter o alinhamento
14
spriteNode.position = CGPoint(x: shapeNode.frame.width/2, y:
15
shapeNode.frame.height/2)
16
spriteNode.physicsBody = SKPhysicsBody(texture: spriteNode.texture,
17
alphaThreshold: 0.99, size: spriteNode.size)
self.addChild(spriteNode)
}

Esta funo exige tambm uma outra bem simples que nos d uma cor aleatria ,
prosseguindo:

14
1 func getRandomColor() -> UIColor{
2 let hue = (CGFloat(arc4random() % 256)) / 256.0
3 let saturation = ((CGFloat(arc4random() % 128)) / 256.0) + 0.5
4 let brightness = ((CGFloat(arc4random() % 128)) / 256.0) + 0.5
5
6 return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1)
7}

A funo addObject um pouco complicada para dissecar, mas depois de perceber


no assim to ruim. Vou dividi-la por partes:

1 let shapeNode = SKShapeNode(path: currentPath)


2 shapeNode.strokeColor = getRandomColor()
3 shapeNode.fillColor = getRandomColor()
4 shapeNode.lineWidth = lineWidth

Esta parte cria um novo SKShapeNode usando o caminho (agora fechado) do usurio.
Adiciona uma cor aleatria na linha e outra no fundo da forma. A largura da linha fica
igual a nossa varivel global lineWidth.

// COMPLICADO: Voc deve adicionar o n na cena antes de chamar


self.view.textureFromNode() ou voc no vai ter a verso retina(HQ) da textura para
1
passar para o SKSpriteNode
2
self.addChild(shapeNode)
3
let spriteNode = SKSpriteNode(texture: self.view.textureFromNode(shapeNode), size:
4
shapeNode.frame.size)
shapeNode.removeFromParent()

Assim como diz no comentrio, o que o mtodo faz um pouco complicado. O que
queremos fazer obter uma textura (imagine isso como uma imagem) do SKShapeNode
que acabamos de criar na primeira parte. Usando esta textura, pode-se criar uma
SKSpriteNode do mesmo tamanho e forma como a SKShapeNode. E porqu? Vamos
ver isso na terceira parte.

A parte difcil existe porque ns queremos uma textura/imagem SKShapeNode de alta


qualidade. Para esse fim temos de fazer isto:

Primeiro temos que adicion-lo cena, em seguida criar uma SKSpriteNode usando
essa textura, em seguida removemos o SKShapeNode da cena j que no mais
necessrio. Como experincia, tente remover as linhas 2 e 4 acima, voc vai notar uma
grande diferena na qualidade.

15
// COMPLICADO: Voc deve definir a posio do spriteNode no centro do quadro do
shapeNode para manter o alinhamento
1
spriteNode.position = CGPoint(x: shapeNode.frame.width/2, y:
2
shapeNode.frame.height/2)
3
spriteNode.physicsBody = SKPhysicsBody(texture: spriteNode.texture,
4
alphaThreshold: 0.99, size: spriteNode.size)
self.addChild(spriteNode)

Em seguida, precisamos definir a posio do SKSpriteNode (mais uma manobra

complicada ). Finalmente temos de usar uma das novas APIs do SpriteKit!


Linha 3 acima o culminar de todo este trabalho DURO. Ao utilizar o construtor
SKPhysicsBody acima, podemos utilizar a textura/imagem que temos do nosso
SKShapeNode original (agora a textura da SKSpriteNode) e obter assim um contorno
de pixel perfeito. Isto permite uma perfeita representao fsica da forma que
desenhamos. A ltima linha simplesmente adiciona o novo SKSpriteNode cena, fsica
e tudo mais.

S um ltimo passo! Volte at a funo handlePan e descomente(retirar as //) as duas


funes adjustDrawing e addObject.

Agora, ligue o simulador e desenhe ate no poder mais!

16
17
O simulador pode ser um pouco lento, dependendo de quantos objectos desenhar. A
fsica de pixel-perfeito tem o seu preo. Em um dispositivo acredite que muito mais
rpido.

Sinta-se a vontade para tirar duvidas sobre o FisicaDesenhada na seo de comentrios.


Fique atento aos prximos tutoriais e siga-nos no facebook!

18
Tutorial como Criar Flappy Bird em Swift 1/2
Hoje vamos iniciar um tutorial como criar Flappy Bird em Swift. Este popular jogo para
IOS e android tem sido muito falado pelas mais variadas razes.

Este jogo chegou a categoria de fenmeno pois apesar da sua extrema simplicidade
atingiu o primeiro lugar do ranking das aplicaes mais descarregadas.

Para quem no sabe, este simples jogo consiste em fazer passar um pequeno pssaro
pelo maior numero de tubos possveis, sem o deixar tocar em nenhum obstculo, para
isso a nica coisa que o jogador tem que fazer tocar na tela para que o pssaro d
pequenos voos.

Neste tutorial como criar Flappy Bird em Swift, vamos explicar em detalhe o cdigo
que far o jogo funcionar, no entanto alguns dos objectos e funes apenas faremos uma
breve explicao. Faremos um aprofundamento dessas mesmas funes e objectos,
alguns dos quais muito teis, em outros artigos dedicados ao tema.

Este jogo tambm est a tornar-se mundialmente famoso por se dizer que o novo Ol
Mundo do sculo XXI.

19
Bem, vamos comear

Primeiro criamos um novo projecto de jogo no novo xcode 8 Game.

Em seguida, certifique-se que escolhe a linguagem Swift com tecnologia SpritKit e o


equipamento pode ser Universal.

20
E este o ambiente onde vamos trabalhar durante este tutorial,

podemos ver a esquerda os vrios ficheiros que foram gerados automaticamente ao


criarmos o projecto.

Para comear vamos a GameViewController.swift e vamos fazer apenas duas


alteraes,

comentar a seguinte linha :

1 // scene.scaleMode = .AspectFill

Pois no queremos que a escala se ajuste a janela.

E adicionar

21
1 scene.size = skView.bounds.size

Depois da inicializao da varivel skView, poderemos mais a frente utilizar scene.size


para obtermos as dimenses do ecr.

A funo viewDidLoad() em GameViewController.swift ficar com este aspecto:

override func viewDidLoad() {


1
2
super.viewDidLoad()
3
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
4
5
// Configure the view.
6
let skView = self.view as SKView
7
skView.showsFPS = true
8
skView.showsNodeCount = true
9
10
/* Sprite Kit applies additional optimizations to improve rendering
11
performance */
12
skView.ignoresSiblingOrder = true
13
14
/* Set the scale mode to scale to fit the window */
15
//scene.scaleMode = .AspectFill
16
scene.size = skView.bounds.size
17
18
skView.presentScene(scene)
19
}
20
}

Neste momento se executarmos a nossa aplicao vamos ver uma aplicao de


demonstrao que criada por defeito.
Como o Xcode j criou esta mini aplicao e no o que nos interessa vamos voltar
para o ficheiro GameScene.swift e vamos limpar tudo o que est dentro das funes
didMoveToView, touchesBegan e update.

Agora vamos iniciar a escrita do nosso jogo Flappy Bird mas, iremos colocar j todo o
cdigo final e explic-lo passo a passo ou linha a linha por comentrios.

Vamos fazer uma alterao na class GameScene vamos adicionar o


SKPhysicsContactDelegate para podermos utilizar contactos durante o jogo.

class GameScene: SKScene, SKPhysicsContactDelegate

Iniciamos com a declarao das variveis necessrias dentro da classe GameScene

22
//Sprite Node que representar o nosso pssaro
1
var passaro: SKSpriteNode = SKSpriteNode()
2
//Sprite Node uma tela cinza para cobrir o ecr quando o jogo termina
3
var cobrir: SKSpriteNode = SKSpriteNode()
4
//Duas imagens de fundo iremos necessitar de duas irei explicar o porque
5
var Fundo1: SKSpriteNode = SKSpriteNode()
6
var Fundo2: SKSpriteNode = SKSpriteNode()
7
//Tambem duas imagens para o cho
8
var Chao1: SKSpriteNode = SKSpriteNode()
9
var Chao2: SKSpriteNode = SKSpriteNode()
10
//A textura para o passaro com a imagem "bird.png"
11
var TexturaPassaro = SKTexture(imageNamed: "bird" )
12
//Label para exibir a pontuao
13
var pontuacaoL: SKLabelNode = SKLabelNode(fontNamed: "System-bold")
14
//Uma nova class Pipe para os tubos j veremos como criada
15
var TuboBase: Pipe = Pipe()
16
//O espao entre o tubo de cima e o de baixo
17
var Espaco: Float = 250
18
//Variveis que nos permitem colocar os tubos mais a cima ou mais a baixo
19
aleatoriamente
20
var prevNum: Float = 0
21
var maxRange: Float = 175
22
var minRange: Float = -100
23
//Velocidade a que o jogo se desenrola
24
var Velocidade: Float = 3.0
25
//Inteiro para a pontuao
26
var Pontuacao: Int = 0
27
//Bool para controlarmos se o jogo j se iniciou ou ainda no
28
var emMovimento:Bool = false
29
//Variveis para coliso
30
var birdCategory: UInt32 = 1
31
var pipeCategory: UInt32 = 2
32
//Array para guardar os tubos que existem no jogo
33
var Tubos: Pipe[] = []

Estas so as variveis globais que iremos necessitar ao longo jogo.

No prximo passo vamos implementar a funo didMoveToView.

23
1 override func didMoveToView(view: SKView)
2 {
3 //Definir o tubo padro com cor preta, largura igual a largura da
4 //tela a dividir por 6, e altura de 480
5 TuboBase = Pipe(color: UIColor.blackColor(), size: CGSize(width:
6 (view.bounds.size.width) / 6, height: 480))
7
8 //O Cobrir fica do tamanho da nossa tela, cor cinzenta meio transparente "alpha
9 = 0.7"
10 cobrir = SKSpriteNode(color: UIColor.grayColor(),
11 size:CGSize(width:view.bounds.size.width, height:view.bounds.size.height))
12 cobrir.alpha = 0.7
13 // a posio Z de 11 para que quando ela aparecer se sobreponha a tudo
14 cobrir.zPosition = 11
15 cobrir.position.x = view.bounds.size.width / 2
16 cobrir.position.y = view.bounds.size.height / 2
17
18 //A Label pontuao colocada no canto superior esquerdo, mas para j fica
19 escondida
20 pontuacaoL.position.x = 13
21 pontuacaoL.position.y = view.bounds.size.height - 50
22 pontuacaoL.text = "Pontos: 0"
23 pontuacaoL.horizontalAlignmentMode =
24 SKLabelHorizontalAlignmentMode.Left
25 pontuacaoL.hidden = true
26
27 //No objecto Cho vamos colocar a imagem "Ground.png"
28 Chao1 = SKSpriteNode(imageNamed: "Ground")
29 Chao1.size.width = view.bounds.width + 2
30 Chao1.position.x = view.bounds.width * 0.5
31 Chao1.position.y = Chao1.size.height * 0.4
32 Chao1.texture.filteringMode = SKTextureFilteringMode.Nearest
33 //O seu corpo fisico ser do mesmo tamanho da imagem que iremos visualizar
34 Chao1.physicsBody = SKPhysicsBody(rectangleOfSize: Chao1.size)
35 //dynamic = false para que no reaja a colises ou foras de gravidade
36 Chao1.physicsBody.dynamic = false
37 Chao1.zPosition = 10
38
39 //As duas variveis Chao so quase iguais s diferencia a sua posio, enquanto
40 // a primeira fica no centro do ecr esta fica direita do ecr, com isto iremos
41 // criar uma noo de movimento em que o cenrio parece no acabar :)
42 Chao2 = SKSpriteNode(imageNamed: "Ground")
43 Chao2.size.width = view.bounds.width + 2
44 Chao2.position.x = view.bounds.width * 1.5
45 Chao2.position.y = Chao2.size.height * 0.4
46 Chao2.texture.filteringMode = SKTextureFilteringMode.Nearest
47 Chao2.physicsBody = SKPhysicsBody(rectangleOfSize: Chao2.size)
48 Chao2.physicsBody.dynamic = false
49 Chao2.zPosition = 10
50

24
//Os fundos seguem a mesma lgica do cho, para estes
// vamos colocar a imagem "Background.png"
Fundo1 = SKSpriteNode(imageNamed: "Background")
51
Fundo1.position.x = view.bounds.width * 0.5
52
Fundo1.position.y = view.bounds.height * 0.5
53
Fundo1.texture.filteringMode = SKTextureFilteringMode.Nearest
54
55
//Mesma logica do Chao2
56
Fundo2 = SKSpriteNode(imageNamed: "Background")
57
Fundo2.position.x = view.bounds.width * 1.5
58
Fundo2.position.y = view.bounds.height * 0.5
59
Fundo2.texture.filteringMode = SKTextureFilteringMode.Nearest
60
61
//Este filteringMode serve para ajustarmos o tamanho da imagem do passaro
62
// ao seu objecto
63
TexturaPassaro.filteringMode = SKTextureFilteringMode.Nearest
64
passaro = SKSpriteNode(texture: TexturaPassaro)
65
passaro.physicsBody = SKPhysicsBody(circleOfRadius: 5)
66
//Para j e como o jogo ainda no comeou vamos colocar o pssaro estatico
67
passaro.physicsBody.dynamic = false
68
passaro.physicsBody.contactTestBitMask = pipeCategory
69
passaro.physicsBody.collisionBitMask = pipeCategory
70
passaro.zPosition = 9
71
passaro.position = CGPoint(x: 150, y: view.bounds.width / 2 - 10)
72
73
//Aqui colocamos a fsica do nosso mundo onde a gravidade vai ser y = -0.5
74
self.physicsWorld.contactDelegate = self
75
self.physicsWorld.gravity = CGVectorMake(0, -5.0)
76
77
//Adicionar ao ecr os objectos criados anteriormente menos o Cobrir
78
// que apenas ser colocado no fim do jogo
79
self.addChild(Fundo1)
80
self.addChild(Fundo2)
81
self.addChild(Chao1)
82
self.addChild(Chao2)
83
self.addChild(pontuacaoL)
84
self.addChild(passaro)

Durante a explicao do cdigo anterior deve ter se perguntado como se adiciona as


imagens no projecto. Ok aqui que iremos explicar como funciona.

Na primeira pasta com o nome do projecto click o boto direito e escolha New Group.

25
Editamos o nome pretendido Imagens.

Agora arrastamos as imagens pretendidas para dentro da pasta criada

Escolhemos a opo Copy items if needed para copiar as imagens para dentro do
projecto.

26
E pronto a partir daqui para nos referirmos a uma imagem basta colocar o seu nome.

Download das imagens disponvel no final do tutorial.

Para no tornar este post demasiado grande o tutorial foi dividido em dois,

acompanhe a segunda parte onde iremos finalizar este jogo bem como disponibilizar
cdigo e mdia para este projecto.

Espero que esteja a gostar deste tutorial explicativo, estou ao dispor para esclarecer
qualquer dvida ou critica.

27
Tutorial como Criar Flappy Bird em Swift 2/2
Este post a segunda e ultima parte do tutorial como criar Flappy Bird em Swift.

Se no viu a primeira parte pode ver aqui Tutorial Como Criar Flappy Bird em Swift
1/2 .

Continuando

Agora vamos criar uma funo que nos permita automatisar a criao dos pares de tubos
que vo aparecendo consecutivamente na direita e movendo-se para a esquerda.

A Funo SpawnPipeRow()

1 //Na spawnPipeRow temos um parmetro de entrada offs que representa


2 //quanto os tubos vo subir ou descer.
3 func spawnPipeRow(offs: Float)
4 {
5 //Com base no offs e no Espaco podemos determinar o deslocamento exato do
6 tubo.
7 let offset = offs - Espaco / 2
8 //Declarao dos dois tubos
9 let pipeBottom = TuboBase.copy() as Pipe
10 let pipeTop = TuboBase.copy() as Pipe
11 //A posio x onde termina a tela
12 let xx = Float(self.view.bounds.size.width)
13
14 //Aqui definimos para o tubo de baixo a imagem, se um tubo de cima ou de
15 baixo
16 // e sua posio baseada no offset e no xx
17 pipeBottom.texture = SKTexture(imageNamed: "BotPipe")
18 pipeBottom.texture.filteringMode = SKTextureFilteringMode.Nearest
19 pipeBottom.isBottom = true
20 //A funo SetRelativePositionBot ser explicada mais a frente para j basta
21 sabermos
22 // que tem o objectivo de colocar o nosso tubo no sitio certo
23 self.SetRelativePositionBot(pipeBottom, x: xx, y: offset)
24 //Definio das dimenses do seu corpo fsico
25 pipeBottom.physicsBody = SKPhysicsBody(rectangleOfSize: pipeBottom.size)
26 pipeBottom.physicsBody.dynamic = false
27 pipeBottom.physicsBody.contactTestBitMask = birdCategory
28 pipeBottom.physicsBody.collisionBitMask = birdCategory
29 //Adicionamos o tubo ao nosso array
30 Tubos.append(pipeBottom)

28
//E por fim adicionamos ao cenrio
self.addChild(pipeBottom)
31
32
//Neste pedao de cdigo vamos repetir o mesmo a cima mas
33
// para o tubo de cima.
34
pipeTop.texture = SKTexture(imageNamed: "TopPipe")
35
pipeTop.texture.filteringMode = SKTextureFilteringMode.Nearest
36
//Temos aqui uma variante no Y pois vamos adicionar ao offset o Espaco
37
// assim ao seu deslocamento adicionamos mais o valor do espao que
38
// provocar o intervalo entre os 2 tubos
39
self.SetRelativePositionTop(pipeTop, x: xx, y: offset + Espaco)
40
pipeTop.physicsBody = SKPhysicsBody(rectangleOfSize: pipeTop.size)
41
pipeTop.physicsBody.dynamic = false
42
pipeTop.physicsBody.contactTestBitMask = birdCategory
43
pipeTop.physicsBody.collisionBitMask = birdCategory
44
Tubos.append(pipeTop)
45
self.addChild(pipeTop)
}

Prxima etapa, as funes SetRelativePositionBot e SetRelativePositionTop que


determinam a posio exata onde os tubos sero criados.

1 //Temos como parmetros de entrada o tubo alvo, a posio x e y


2 func SetRelativePositionBot(node: SKSpriteNode, x:Float, y:Float)
3 {
4 //O x fcil o nosso parmetro X mais metade da largura do nosso tubo,
5 // temos de acrescentar metade da largura porque o tubo ser criado a partir
6 // do seu centro, logo teremos de dar um desconto.
7 let xx = (Float(node.size.width) / 2) + x
8 //No y temos o centro da altura da tela mais o parmetro Y mais metade
9 // da altura como explicado anteriormente
10 let yy = Float(self.view.bounds.size.height) / 2 - (Float(node.size.height) / 2 ) +
11 y
12
13 node.position.x = CGFloat(xx)
14 node.position.y = CGFloat(yy)
15 }
16
17 //Funo SetRelativePositionTop igual a anterior mas para o tubo de cima
18 func SetRelativePositionTop (node: SKSpriteNode, x:Float, y:Float)
19 {
20 let xx = (Float(node.size.width) / 2) + x
21 let yy = Float(self.view.bounds.size.height) / 2 + (Float(node.size.height) / 2 ) +
22 y
23 node.position.x = CGFloat(xx)
node.position.y = CGFloat(yy)

29
}

Feito isto vamos programar o que o jogo far de cada vez que tocamos na tela. Para isso
temos a funo touchesBegan que invocada de cada vez que ha um toque na tela.

1 override func touchesBegan(touches: NSSet, withEvent event: UIEvent)


2 {
3 //Se o Passaro tem physicsBody.dynamic = false ento o primeiro toque,
4 // e o vai iniciar-se
5 if(!passaro.physicsBody.dynamic)
6 {
7 //Chamar spawnPipeRow para crias os primeiros dois tubos
8 self.spawnPipeRow(0)
9 //Tornar o pssaro influencivel pelo ambiente
10 passaro.physicsBody.dynamic = true
11 //Colocamos uma velocidade de 175 na vertical que far,
12 // o pssaro dar o primeiro salto
13 passaro.physicsBody.velocity = CGVectorMake(0, 175)
14 //Deixamos de esconder a label da pontuao
15 pontuacaoL.hidden = false
16 //Identificamos que o movimento do pssaro de iniciou
17 emMovimento = true
18 }
19 else if(emMovimento)
20 {
21 //Velocidade de salto por defeito de 200
22 var vel: Float = 200
23 //Se o pssaro se encontrar perto do cimo reduzir a velocidade do salto
24 if(self.view.bounds.size.height - passaro.position.y
25 &amp;amp;amp;amp;amp;lt; 85)
26 {
27 vel -= 85 - (self.view.bounds.size.height - position.y )
28 }
29 passaro.physicsBody.velocity = CGVectorMake(0, vel)
30 }
31
32 //Se o jogo se encontrar parado por Game Over recomear de novo
33 else
34 {
35 //Remover aTela que cobre o ecr
36 cobrir.removeFromParent()
37 //Apagar todos os tubos no array da tela
38 for pi in Tubos
39 {
40 pi.removeFromParent()
41 }

30
//E remover tambm do array
42
Tubos.removeAll(keepCapacity: false)
43
//Colocar pontuao a Zero
44
Pontuacao = 0
45
//E colocar Passaro com posio e definies de inicio de jogo
46
passaro.physicsBody.dynamic = false
47
passaro.position = CGPoint(x: 150, y: view.bounds.width / 2 - 10)
48
pontuacaoL.hidden = true
49
emMovimento = false
50
}
51
52
}

A funo seguinte a update, esta funo bastante til para a nossa aplicao pois ela
invocada consecutiva-mente para podermos actualizar os objectos envolvidos.

1 override func update(currentTime: CFTimeInterval)


2 {
3 //Se jogo a decorrer
4 if(emMovimento)
5 {
6 //Mover o fundo ligeiramente para a esquerda: o valor da velocidade/2
7 //A velocidade dividida por 2 para nos dar um efeito paralaxe no movimento
8 Fundo1.position.x -= Velocidade / 2
9 Fundo2.position.x -= Velocidade / 2
10
11 //Aqui vamos controlar cada vez que um dos fundos sai da tela pela sua
12 esquerda,
13 // vamos move-la instantaneamente para a direita da tela, para que esta
14 comece
15 // a entrar pela direita. Parece confuso mas no .
16 if(Fundo1.position.x &amp;amp;amp;amp;amp;lt;= -view.bounds.width / 2)
17 {
18 Fundo1.position.x = view.bounds.width * 1.5 - 2
19 }
20 if(Fundo2.position.x &amp;amp;amp;amp;amp;lt;= -view.bounds.width / 2)
21 {
22 Fundo2.position.x = view.bounds.width * 1.5 - 2
23 }
24
25 //O cdigo seguinte segue a mesma lgica do fundo mas para o cho
26 Chao1.position.x -= Velocidade
27 Chao2.position.x -= Velocidade
28 if(Chao1.position.x &amp;amp;amp;amp;amp;lt;= -view.bounds.width / 2)
29 {
30 Chao1.position.x = view.bounds.width * 1.5 - 2

31
31 }
32 if(Chao2.position.x &amp;amp;amp;amp;amp;lt;= -view.bounds.width / 2)
33 {
34 Chao2.position.x = view.bounds.width * 1.5 - 2
35 }
36
37 //A cada um dos tubos criados
38 for(var i = 0; i &amp;amp;amp;amp;amp;lt; Tubos.count; i++)
39 {
40 let pipe = Tubos[i]
41
42 //Se um tubo de baixo j passou pelo pssaro ento somamos um ponto e
43 // marcamos o tubo para que no pontue mais
44 if(pipe.position.x + pipe.size.width / 2 &amp;amp;amp;amp;amp;lt;
45 passaro.position.x
46 &amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp; pipe.isBottom
47 &amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp; !pipe.jaPontuo)
48 {
49 Pontuacao++
50 pipe.jaPontuo = true
51 }
52
53 //Mover o tubo para a esquerda com a velocidade definida
54 pipe.position.x -= Velocidade
55 //Se temos tubos a menos e j est na altura de criar novos tubos ento
56 if(i == Tubos.count - 1)
57 {
58 if(pipe.position.x &amp;amp;amp;amp;amp;lt; self.view.bounds.width -
59 pipe.size.width * 2.0)
60 {
61 //Criamos novos tubos com um Offset aleatrio
62 self.spawnPipeRow(self.randomOffset())
63 }
64 }
65 }
66
67 //Atualizamos a label pontuao
68 pontuacaoL.text = "Pontos: \(Pontuacao)"
69
70 for(var i = 0; i &amp;amp;amp;amp;amp;lt; Tubos.count; i++)
71 {
72 let pipe = Tubos[i]
73
74 //Se tubo ja saiu da tela ser apagado
75 if (pipe.position.x + (pipe.size.width / 2) &amp;amp;amp;amp;amp;lt; 0)
76 {
77 Tubos.removeAtIndex(i)
78 pipe.removeFromParent()
79 continue
}

32
}

}
}

Agora a funo didBeginContact que entra em ao cada vez que ha contacto entre
objectos.

1 func didBeginContact(contact: SKPhysicsContact!)


2 {
3 //Se aconteceu algum contacto ento
4 if(emMovimento)
5 {
6 //Paramos o movimento
7 emMovimento = false
8 //Paramos o pssaro
9 passaro.physicsBody.velocity = CGVectorMake(0, 0 )
10 //Eliminamos os tubos
11 for pi in Tubos
12 {
13 pi.physicsBody = nil
14 }
15 //E por fim cobrir o ecr com a tela cinzenta
16 self.addChild(cobrir)
17 }
18 else
19 {
20 passaro.physicsBody.velocity = CGVectorMake(0, 0 )
21 }
22 }

J quase a terminar mas ainda temos de criar a funo randomOffset que apenas vou
resumir.

Ela ir nos devolver um numero aleatrio que iremos utilizar para colocar os tubos mais
a cima ou mais a baixo.

1 func randomOffset() -&amp;amp;amp;amp;amp;gt; Float


2 {
3 let max = maxRange - prevNum
4 let min = minRange - prevNum

33
5 var rNum: Float = Float(arc4random() % 61) + 40
6 var rNum1: Float = Float(arc4random() % 31) + 1
7 if(rNum1 % 2 == 0)
8 { var tempNum = prevNum + rNum
9 if(tempNum &amp;amp;amp;amp;amp;gt; maxRange)
10 { tempNum = maxRange - rNum }
11 rNum = tempNum
12 }else
13 { var tempNum = prevNum - rNum
14 if(tempNum &amp;amp;amp;amp;amp;lt; minRange)
15 { tempNum = minRange + rNum }
16 rNum = tempNum
17 }
18 prevNum = rNum
19 return rNum
20 }

Por fim falta-nos a class Pipe.

Poderia-mos utilizar a class SKSpriteNode mas neste caso optamos por criar esta class
para podermos adicionar estas duar propriedades isBottom e jaPontuou.

1 class Pipe: SKSpriteNode


2 {
3 var isBottom: Bool = false
4 var jaPontuo: Bool = false
5
6 }

E com isto terminamos o nosso tutorial. Ao executar o jogo ir reparar que est muito
fcil, agora o objectivo que possa alterar alguns parmetros como o Espaco a
Velocidade ou ate mesmo as imagens do jogo.

34

Das könnte Ihnen auch gefallen