um if. No código da nossa engine abaixo, faremos exatamente isso.
Vale citar que a engine é o código responsável por manter o loop de objetos, e
com o Cocos2D, utilizamos métodos de agendamento para isso. Ou seja, criaremos
um schedule para que a engine analise se deve ou não atualizar e incluir um novo
objeto inimigo na tela.
Abaixo, o código da primeira Engine do game, a classe MeteorsEngine. No
header MeteorsEngine.h iremos definir um protocolo, que é o método que o de-
legate (a GameScene) terá que implementar para responder às requisições da engine de inimigos:
@protocol MeteorsEngineDelegate;
@interface MeteorsEngine : CCLayer
@property (nonatomic, assign) id<MeteorsEngineDelegate>delegate;
+ (MeteorsEngine *)meteorEngine;
@end
@protocol MeteorsEngineDelegate <NSObject>
- (void)meteorsEngineDidCreateMeteor:(CCNode *)meteor;
@end
No implementation MeteorsEngine.m, vamos escrever a lógica de criação de
meteoros:
82
Casa do Código
Capítulo 5. Tela do jogo e objetos inimigos
# import "MeteorsEngine.h"
@implementation MeteorsEngine
+ (MeteorsEngine *)meteorEngine
{
return [[[MeteorsEngine alloc] init] autorelease];
}
- (id)init
{
self = [super init];
if (self) {
[self schedule:@selector(meteorsEngine:) interval:(1.0f/10.0f)];
}
return self;
}
- (void)meteorsEngine:(float)dt
{
// sorte: 1 em 30
gera um novo meteoro!
if(arc4random_uniform(30) == 0) {
if ([self.delegate respondsToSelector:
@selector(meteorsEngineDidCreateMeteor:)]){
// Pede para o delegate criar o meteoro
// (por enquanto, não estamos informando qual o meteoro)
[self.delegate meteorsEngineDidCreateMeteor:nil];
}
}
}
@end
Para fechar o link entre ambas as camadas, implementaremos o protocolo
MeteorsEngineDelegate na tela do jogo, o que obrigará ela a ter um método
para receber os objetos criados por essa Engine e colocá-los na tela.
Primeiramente, vamos informar na GameScene.h que ela deverá implementar
o protocolo:
# import "MeteorsEngine.h"
83
5.3. Engines
Casa do Código
@interface GameScene : CCLayer <MeteorsEngineDelegate>
+ (CCScene *)scene;
@end
E na GameScene.m crie o método que será responsável pelos meteoros que
criaremos em seguida.
- (void)meteorsEngineDidCreateMeteor:(CCNode *)meteor
{
// Aqui incluiremos o meteoro na tela
}
Mantendo as referências
Um outro ponto importante para o controle do jogo e toda a orquestração é man-
ter todos os objetos criados de uma forma fácil para que possam ser analisados depois. Um exemplo nesse caso é a comparação com o tiro ou com o próprio player
para detectar colisões, que serão tratados mais à frente.
Vamos guardar a referência de cada meteoro criado em uma propriedade &&NSMutableArray na classe GameScene , e também uma propriedade com
referência à engine de inimigos. Declare estas propriedades
na GameScene.h
# import "MeteorsEngine.h"
@interface GameScene : CCLayer <MeteorsEngineDelegate>
+ (CCScene *)scene;
// Engines
@property (nonatomic, retain) MeteorsEngine *meteorsEngine;
// Arrays
@property (nonatomic, retain) NSMutableArray *meteorsArray;
@end
O Cocos2D não suporta ARC (Automatic Reference Counting), por isso, todas
as propriedades que criarmos como retain deverão ser retiradas da memória no
método dealloc de nossas classes.
84
Casa do Código
Capítulo 5. Tela do jogo e objetos inimigos
Crie o método dealloc no final da GameScene.m e inclua:
- (void)dealloc
{
[_meteorsEngine release];
[_meteorsArray release];
[super dealloc];
}
Lembre-se de incluir o dealloc em todas as demais classes que criarmos com
propriedades declaradas com retain.
5.4
Meteor
Chegamos ao objeto inimigo propriamente dito. As principais responsabilidades
desse objeto são:
Carregar imagem ( CCSprite)
Posicionar elemento na tela
Guardar a posição do objeto para que o mesmo possa ser movimentado com
o tempo
Esse é o primeiro objeto de jogo realmente que criaremos. Até o momento, cri-
amos telas preenchendo-as com elementos, botões de menu e classes de engine para
dar a base a esses elementos principais do jogo.
A primeira coisa a se fazer é adicionar o asset do meteoro na Assets.h.
@interface Assets : NSObject
# define kMETEOR
@"meteor.png"
@end
Vamos criar a classe Meteor. Inicialmente, cada meteoro nasce no topo da tela
(é o valor de SCREEN_HEIGHT()), e numa posição x randômica. Declare no header
Meteor.h duas propriedades para guardar a posição x e y do meteoro, o método
construtor meteorWithImage: e o método start, que será implementado pos-
teriormente:
85
5.4. Meteor
Casa do Código
# import "CCSprite.h"
@interface Meteor : CCSprite
@property (nonatomic, assign) float positionX;
@property (nonatomic, assign) float positionY;
+ (Meteor *)meteorWithImage:(NSString *)image;
- (void)start;
@end
No implementation Meteor.h, nosso construtor irá sortear uma posição inicial
do meteoro:
# import "Meteor.h"
@implementation Meteor
+ (Meteor *)meteorWithImage:(NSString *)image
{
Meteor *meteor = [Meteor spriteWithFile:image];