Repare que já
possuíamos enemyRadius e playerY:
@property (nonatomic) int playerX;
@property (nonatomic) int playerY;
@property (nonatomic) int playerRadius;
@property (nonatomic) int enemyX;
@property (nonatomic) int enemyY;
@property (nonatomic) int enemyRadius;
No init da Impossible.m, vamos definir os valores padrão destas proprie-
dades:
- (id)init
{
//...
// Posição inicial do jogador
self.playerRadius = 25;
self.playerX = 160;
self.playerY = 275;
// Posição inicial do inimigo
self.enemyX = 0;
self.enemyY = 0;
self.enemyRadius = 0;
//...
}
36
Casa do Código
Capítulo 2. Protótipo de um jogo
Altere os métodos de desenho do player e inimigo para que utilizem as variáveis
que foram criadas:
// Desenha o Player
- (void)drawPlayerInContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextAddArc(context,
self.playerX,
self.playerY,
self.playerRadius,
0,
(2 * M_PI),
YES); // Círculo de 360° (0 ~ 2pi)
CGContextSetRGBFillColor(context, 0.0f, 0.9f, 0.0f, 1.0f);
CGContextFillPath(context);
UIGraphicsPopContext();
}
// Desenha o Inimigo
- (void)drawEnemyInContext:(CGContextRef)context
{
UIGraphicsPushContext(context);
CGContextBeginPath(context);
CGContextAddArc(context,
self.enemyX,
self.enemyY,
self.enemyRadius,
0,
(2 * M_PI),
YES); // Círculo de 360° (0 ~ 2pi)
CGContextSetRGBFillColor(context, 0.4f, 0.4f, 0.4f, 1.0f);
CGContextFillPath(context);
UIGraphicsPopContext();
}
O método que identifica a colisão segue a matemática que já vimos e utiliza as
funções pow (power) para potenciação e a função sqrt (square root) para raiz qua-
drada.
// Verifica Colisões
37
2.6. Detectando colisões e mostrando resultados
Casa do Código
- (void)checkCollision
{
double distance = 0.0f;
// Teorema de Pitágoras
distance = pow(self.playerY - self.enemyY, 2)
+ pow(self.playerX - self.enemyX, 2);
distance = sqrt(distance);
if (distance <= (self.playerRadius + self.enemyRadius)) {
self.running = NO;
}
}
Adicione a chamada ao método que detectará a colisão, dentro do nosso run:
// Game Loop
- (void)run
{
if (self.running == YES) {
// Aumenta raio do inimigo
self.enemyRadius++;
// Checa colisões
[self checkCollision];
// Informa ao iOS que a tela deve ser redesenhada
[self setNeedsDisplay];
}
}
Rode o jogo, quando houver colisão entre o inimigo e nosso player, o jogo irá
parar! Isto acontece porque quando ocorre a colisão nós alteramos a propriedade
running para falso, que é checada no início dos métodos run e moveDown.
Seria mais bonito um Game Over mais convincente, não? Vamos colocar na tela
uma mensagem de Game Over. Para os textos de nosso game utilizaremos a classe
UILabel própria do iOS.
Crie uma propriedade que exibirá o texto de game over na Impossible.h.
@property (nonatomic, strong) UILabel *gameOverLabel;
38
Casa do Código
Capítulo 2. Protótipo de um jogo
No init da Impossible.m vamos instanciar o label gameOverLabel, só que
sem nenhum texto para que ele não apareça na tela neste momento.
- (id)init
{
//...
// Criação do Label que exibirá a mensagem de "Game Over!"
self.gameOverLabel = [[UILabel alloc]
initWithFrame:CGRectMake(20.0f, 40.0f, 300.0f, 50.0f)];
self.gameOverLabel.font = [UIFont systemFontOfSize:40.0f];
self.gameOverLabel.textColor = [UIColor lightGrayColor];
self.gameOverLabel.backgroundColor = [UIColor clearColor];
self.gameOverLabel.text = @"";
[self addSubview:self.gameOverLabel];
//...
}
Ainda na Impossible.m, altere o método checkCollision para que exiba
a mensagem de Game Over quando ocorrer uma colisão.
// Verifica Colisões
- (void)checkCollision
{
double distance = 0.0f;
// Teorema de Pitágoras
distance = pow(self.playerY
- self.enemyY, 2)
+ pow(self.playerX - self.enemyX, 2);
distance = sqrt(distance);
if (distance <= (self.playerRadius + self.enemyRadius)) {
self.gameOverLabel.text = @"GAME OVER!";
self.running = NO;
}
}
A partir daqui, o jogo já detecta as colisões e para em Game Over caso o inimigo
alcance o player. Essa é uma maneira de se pensar em games que foi utilizada por
muito tempo. Atualmente, com o avanço do hardware e com velocidades de pro-
cessamento cada vez maiores, detecções de colisões muito mais complexas foram
criadas.
39
2.7. Adicionando um placar
Casa do Código
Figura 2.14: Player aparece na tela.
2.7
Adicionando um placar
Vamos ver agora um próximo conceito importante para a maioria dos jogos, a atuali-zação do placar. A maioria dos jogos atualiza alguma forma de pontuação de tempos em tempos. Essa atualização de placar pode ocorrer de diversas formas, como pela
detecção de colisões entre objetos, por exemplo. No protótipo o placar será simples, a cada toque na tela o player se afasta do inimigo e se movimenta, ganhando pontos.
Crie a propriedade score na Impossible.h, além de um UILabel que exi-
birá o texto do score. Crie também um método que aumenta o score:
@property (nonatomic) int score;
40