O desenvolvimento de jogos iOS pode ser uma experiência enriquecedora em termos pessoais e financeiro crescimento. No início deste ano, implantei um jogo baseado em Cocos2D, Bee Race , para a App Store. Sua jogabilidade é simples: um corredor infinito em que os jogadores (neste caso, as abelhas) acumulam pontos e evitam obstáculos. Vejo Aqui para uma demonstração.
Neste tutorial, explicarei o processo por trás do desenvolvimento de jogos para iOS, do Cocos2D até a publicação. Para referência, aqui está um pequeno sumário:
Antes de entrarmos nos detalhes corajosos, será útil entender a distinção entre sprites e objetos físicos.
Para qualquer entidade que apareça na tela de um jogo de corrida sem fim, a representação gráfica dessa entidade é chamada de sprite , enquanto a representação poligonal dessa entidade no motor de física é referida como um objeto físico .
Assim, o sprite é desenhado na tela, apoiado por seu objeto físico correspondente, que é então manipulado por seu mecanismo de física. Essa configuração pode ser visualizada aqui, onde os sprites são exibidos na tela, com suas contrapartes poligonais físicas destacadas em verde:
Objetos físicos não são conectados aos seus respectivos sprites por padrão, o que significa que você como o desenvolvedor iOS pode escolher qual mecanismo de física usar e como conectar sprites e corpos. A maneira mais comum é criar uma subclasse do sprite padrão e adicionar um corpo físico concreto a ele.
Com aquilo em mente…
Cocos2D-iphone é uma estrutura de código aberto para iOS que usa OpenGL para aceleração de gráficos de hardware e suporta o Esquilo e Box2D motores de física.
comunidades de aposentadoria de cuidados continuados sem fins lucrativos
Em primeiro lugar, por que precisamos de tal estrutura? Bem, para começar, os frameworks implementam os componentes mais usados do desenvolvimento de jogos. Por exemplo, o Cocos2D pode carregar sprites (em particular, folhas de sprite ( porque? )), inicie ou pare um mecanismo de física e controle o tempo e a animação de maneira adequada. E faz tudo isso com código que foi revisado e testado extensivamente - por que dedicar seu próprio tempo para reescrever códigos provavelmente inferiores?
Talvez o mais importante, no entanto - O desenvolvimento do jogo Cocos2D usa aceleração de hardware gráfico . Sem essa aceleração, qualquer jogo de corredor infinito iOS com até mesmo um número moderado de sprites será executado com desempenho notavelmente fraco. Se tentarmos fazer uma aplicação mais complicada, provavelmente começaremos a ver um efeito de “tempo de marcador” na tela, ou seja, várias cópias de cada sprite conforme ele tenta se animar.
Por fim, o Cocos2D otimiza o uso de memória, pois caches sprites . Assim, quaisquer sprites duplicados requerem memória adicional mínima, o que é obviamente útil para jogos.
Depois de todos os elogios que fiz no Cocos2D, pode parecer ilógico sugerir o uso de Storyboards . Por que não apenas manipular seus objetos com Cocos2D, etc.? Bem, para ser honesto, para janelas estáticas muitas vezes é mais conveniente usar o Interface Builder do Xcode e seu mecanismo de Storyboard.
Em primeiro lugar, permite-me arrastar e posicionar todos os meus elementos gráficos para o meu jogo de corrida sem fim com o rato. Em segundo lugar, a API Storyboard é muito, muito útil. (E sim, eu sei sobre Cocos Builder )
Aqui está uma visão rápida do meu Storyboard:
O controlador de visualização principal do jogo contém apenas uma cena Cocos2D com alguns elementos HUD na parte superior:
Preste atenção ao fundo branco: é uma cena Cocos2D, que carregará todos os elementos gráficos necessários em tempo de execução. Outras visualizações (indicadores ao vivo, dentes-de-leão, botões, etc.) são todas visualizações padrão do Cocoa, adicionadas à tela usando o Interface Builder.
Não vou insistir em detalhes - se você estiver interessado, exemplos podem ser encontrados no GitHub.
(Para fornecer mais motivação, gostaria de descrever meu jogo de corrida sem fim com um pouco mais de detalhes. Sinta-se à vontade para pular esta seção se quiser prosseguir para a discussão técnica.)
Durante o jogo ao vivo, a abelha fica imóvel, e o próprio campo está correndo, trazendo vários perigos (aranhas e flores venenosas) e vantagens (dentes-de-leão e suas sementes).
O Cocos2D possui um objeto de câmera que foi projetado para seguir o personagem; na prática, era menos complicado manipular o CCLayer que contém o mundo do jogo.
Os controles são simples: tocar na tela move a abelha para cima e outro toque a move para baixo.
A própria camada de mundo tem, na verdade, duas subcamadas. Quando o jogo começa, a primeira subcamada é preenchida de 0 a BUF_LEN e exibida inicialmente. A segunda subcamada é preenchida com antecedência de BUF_LEN a 2 * BUF_LEN. Quando a abelha atinge BUF_LEN, a primeira subcamada é limpa e instantaneamente repovoada de 2 * BUF_LEN para 3 * BUF_LEN, e a segunda subcamada é apresentada. Dessa forma, alternamos entre as camadas, nunca retendo objetos obsoletos, uma parte importante para evitar vazamentos de memória.
comparação ágil de software de gerenciamento de projeto
Em termos de motores de física, usei o Chipmunk por dois motivos:
O motor de física foi realmente usado apenas para detecção de colisão. Às vezes, me perguntam: “Por que você não escreveu sua própria detecção de colisão?”. Na realidade, não há muito sentido nisso. Os motores da física foram projetados exatamente com esse propósito: eles podem detectar colisões entre corpos de formas complicadas e otimizar esse processo. Por exemplo, os motores físicos frequentemente dividem o mundo em células e realizam verificações de colisão apenas para corpos nas mesmas células ou em células adjacentes.
Um componente-chave do desenvolvimento de jogos de corredor infinito indie é evitar tropeçar em pequenos problemas. O tempo é um recurso crucial ao desenvolver um aplicativo, e a automação pode economizar muito tempo.
Mas às vezes, a automação também pode ser um meio-termo entre o perfeccionismo e o cumprimento de prazos. Nesse sentido, o perfeccionismo pode ser um assassino do Angry Birds.
Por exemplo, em outro jogo iOS que estou desenvolvendo atualmente, construí uma estrutura para criar layouts usando uma ferramenta especial (disponível em GitHub ) Este framework tem suas limitações (por exemplo, não tem boas transições entre as cenas), mas usá-lo me permite fazer minhas cenas em um décimo do tempo.
Então, embora você não possa construir seu próprio superframework com superferramentas especiais, você ainda pode e deve automatizar o máximo possível dessas pequenas tarefas.
O perfeccionismo pode ser um assassino do Angry Birds. O tempo é um recurso crucial no desenvolvimento de jogos iOS. TweetNa construção deste corredor infinito, a automação foi a chave mais uma vez. Por exemplo, meu artista me enviaria gráficos de alta resolução por meio de uma pasta especial do Dropbox. Para economizar tempo, escrevi alguns scripts para construir automaticamente conjuntos de arquivos para as várias resoluções de destino exigidas pela App Store, adicionando -hd ou @ 2x também (esses scripts são baseados em ImageMagick )
Em termos de ferramentas adicionais, descobri TexturePacker para ser muito útil - ele pode empacotar sprites em folhas de sprites para que seu aplicativo consuma menos memória e carregue mais rápido, já que todos os seus sprites serão lidos em um único arquivo. Ele também pode exportar texturas em quase todos os formatos de frameworks possíveis. (Observe que TexturePacker não é uma ferramenta gratuita, mas acho que vale o preço. Você também pode verificar alternativas gratuitas, como ShoeBox .)
A principal dificuldade associada à física do jogo é criar polígonos adequados para cada sprite. Em outras palavras, criar uma representação poligonal de alguma abelha ou flor de forma obscura. Nem tente fazer isso manualmente - sempre use aplicativos especiais, dos quais existem muitos. Alguns são até bastante ... exóticos - como criar máscaras vetoriais com o Inkspace e depois importá-las para o jogo.
Para o meu próprio desenvolvimento de jogo de corredor sem fim, criei uma ferramenta para automatizar este processo (ver Aqui para o uso adequado), que eu chamo Andengine Vertex Helper . Como o nome sugere, foi inicialmente projetado para o Estrutura Andengine , embora funcione adequadamente com vários formatos atualmente.
Em nosso caso, precisamos usar o padrão plist:
%.5f%.5f
A seguir, criamos um arquivo plist com descrições de objetos:
jet_ant vertices -0.182620.08277 -0.14786-0.22326 0.20242-0.55282 0.470470.41234 0.038230.41234
E um carregador de objetos:
- (void)createBodyAtLocation:(CGPoint)location{ float mass = 1.0; body = cpBodyNew(mass, cpMomentForBox(mass, self.sprite.contentSize.width*self.sprite.scale, self.sprite.contentSize.height*self.sprite.scale)); body->p = location; cpSpaceAddBody(space, body); NSString *path =[[NSBundle mainBundle] pathForResource:@'obj _descriptions' ofType:@'plist']; // e = 0.7; shape->u = 1.0; shape->collision_type = OBJ_COLLISION_TYPE; cpSpaceAddShape(space, shape); }
Para testar como os sprites correspondem aos seus corpos físicos, consulte Aqui .
Muito melhor, certo?
Em resumo, sempre automatize quando possível. Até mesmo scripts simples podem economizar muito tempo. E o mais importante, esse tempo pode ser usado para programação em vez de clicar com o mouse. (Para motivação adicional, aqui está um token XKCD .)
As bolas de sopro coletadas no jogo atuam como uma moeda no aplicativo, permitindo que os usuários comprem novas peles para suas abelhas. No entanto, essa moeda também pode ser comprada com dinheiro real. Um ponto importante a ser observado com relação ao faturamento no aplicativo é se você precisa ou não realizar verificações do lado do servidor para verificar a validade da compra. Uma vez que todos os bens adquiríveis são essencialmente iguais em termos de jogabilidade (apenas alterando a aparência da abelha), não há necessidade de realizar uma verificação do servidor para a validade da compra. No entanto, em muitos casos, você definitivamente precisará fazer isso.
Para saber mais, Ray Wenderlich tem o perfeito tutorial de faturamento no aplicativo .
Em jogos para celular, socializar é mais do que apenas adicionar um botão 'Curtir' do Facebook ou configurar placares. Para tornar o jogo mais emocionante, implementei uma versão multiplayer.
Como funciona? Primeiro, dois jogadores são conectados usando o jogo em tempo real do iOS Game Center. Como os jogadores estão realmente jogando o mesmo jogo de corredor infinito, é necessário que haja apenas um único conjunto de objetos de jogo. Isso significa que a instância de um jogador precisa gerar os objetos e a outra peça irá lê-los. Em outras palavras, se os dispositivos de ambos os jogadores gerassem objetos do jogo, seria difícil sincronizar a experiência.
Com isso em mente, após o estabelecimento da conexão, os dois jogadores enviam um número aleatório um ao outro. O jogador com o maior número atua como o “servidor”, criando os objetos do jogo.
Você se lembra da discussão sobre a geração do mundo dividido? Onde tínhamos duas subcamadas, uma de 0 a BUF_LEN e outra de BUF_LEN a 2 * BUF_LEN? Essa arquitetura não foi usada por acidente - era necessário fornecer gráficos suaves em redes atrasadas. Quando uma parte dos objetos é gerada, ela é compactada em uma plist e enviada para o outro jogador. O buffer é grande o suficiente para permitir que o segundo jogador jogue, mesmo com um atraso de rede. Ambos os jogadores enviam um ao outro sua posição atual com um período de meio segundo, também enviando seus movimentos de cima para baixo imediatamente. Para suavizar a experiência, a posição e a velocidade são corrigidas a cada 0,5 segundo com uma animação suave, então, na prática, parece que o outro jogador está se movendo ou acelerando gradualmente.
Certamente há mais considerações a serem feitas em relação à jogabilidade multiplayer de corrida sem fim, mas espero que isso lhe dê uma noção dos tipos de desafios envolvidos.
Os jogos nunca terminam. Reconheço que há várias áreas em que gostaria de melhorar a minha, a saber:
A camada de mundo é movida usando a ação CCMoveBy. Isso funcionava bem quando a velocidade da camada mundial era constante, uma vez que a ação CCMoveBy era ciclada com CCRepeatForever:
-(void) infiniteMove{ id actionBy = [CCMoveBy actionWithDuration: BUFFER_DURATION position: ccp(-BUFFER_LENGTH, 0)]; id actionCallFunc = [CCCallFunc actionWithTarget:self selector:@selector(requestFillingNextBuffer)]; id actionSequence = [CCSequence actions: actionBy, actionCallFunc, nil]; id repeateForever = [CCRepeatForever actionWithAction:actionSequence]; [self.bufferContainer runAction:repeateForever]; }
Mais tarde, porém, adicionei um aumento de velocidade mundial para tornar o jogo mais difícil à medida que avança:
-(void) infiniteMoveWithAccel { float duration = BUFFER_DURATION-BUFFER_ACCEL*self.lastBufferNumber; duration = max(duration, MIN_BUFFER_DURATION); id actionBy = [CCMoveBy actionWithDuration: duration position: ccp(-BUFFER_LENGTH, 0)]; id restartMove = [CCCallFunc actionWithTarget:self selector:@selector(infiniteMoveWithAccel)]; id fillBuffer = [CCCallFunc actionWithTarget:self selector:@selector(requestFillingNextBuffer)]; id actionSequence = [CCSequence actions: actionBy, restartMove, fillBuffer, nil]; [self.bufferContainer runAction:actionSequence]; }
Essa mudança fazia com que a animação se estragasse a cada reinício de ação. Tentei consertar o problema, sem sucesso. No entanto, meus testadores beta não notaram o comportamento, então adiei a correção.
Criar seu próprio jogo de corredor infinito indie pode ser uma ótima experiência. E quando você chega à etapa de publicação do processo, pode ser uma sensação maravilhosa quando você libera sua própria criação na selva.
O processo de revisão pode variar de vários dias a várias semanas. Para saber mais, há um site útil Aqui que usa dados de crowdsourcing para estimar os tempos de revisão atuais.
Além disso, eu recomendo usar AppAnnie para examinar várias informações sobre todos os aplicativos na App Store e registrar-se em alguns serviços de análise, como Flurry Analytics pode ser útil também.
dimensões do dispositivo para web design responsivo
E se este jogo o intrigou, não deixe de conferir Bee Race na loja.