Iniciamos a criação de um jogo ao estilo Robot Unicorn Attack.
Vimos como o jogo ficará no final, porém ainda não implementamos qualquer funcionalidade.
Começaremos a programação para termos alguma jogabilidade inicial.
Criamos no último tutorial o projeto do nosso próximo game. Adicionamos os arquivos de sprite sheet e tile set e vimos como o jogo ficará quando estiver executando. Nesse tutorial, nós incluiremos a funcionalidade que faz com que o Sonic (créditos a SEGA) salte quando o jogador clicar na tela. Além disso, adicionaremos a gravidade de forma que ele também caia. Para que ele não vá em direção ao infinito, adicionaremos também o tratamento de colisão específico entre o personagem jogável e o chão.
Primeiramente, vamos adicionar na classe HelloWorld todas as variáveis necessárias para a nossa simulação. Para isso, abra o arquivo “HelloWorldScene.h” e, logo abaixo dessa linha de código,
static cocos2d::CCScene* scene();
adicione essas linhas:
float gravidade;
float posicaoYInicial;
float velocidadeYInicial;
float tempoCorrido;
cocos2d::CCSprite* sonic;
cocos2d::CCTMXTiledMap* plataforma;
Note que declaramos quatro variáveis que armazenam valores reais e duas variáveis que fazem referência a dois objetos gráficos do nosso jogo. As quatro variáveis reais existem porque faremos uma simulação física de gravidade utilizando alguns conceitos de movimento uniformemente variado. Optei por reimplementar a física e não utilizar o motor físico Box2D para eu mostrar uma boa aplicação daquela Física que você viu no Ensino Médio.
Relembrando, as variáveis existentes no movimento uniformemente variado são: posição inicial (S0), posição final (S), velocidade inicial (V0), velocidade final (V), aceleração (a) e tempo (t). Para o nosso problema, são suficientes declarar apenas as variáveis: aceleração (gravidade, no nosso exemplo), posição inicial, velocidade inicial e tempo. Também adicionamos uma referência ao sprite do Sonic e uma ao tiled map da plataforma. Isso porque, a cada novo quadro mostrado, faremos modificações na posição do Sonic e utilizaremos informações da plataforma para isso.
Ainda no mesmo arquivo, adicione as seguintes linhas de código logo abaixo das declarações de variáveis realizadas anteriormente.
void atualiza(float dt);
void ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
void ccTouchesEnded(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
Acabamos de declarar os protótipos dos métodos necessários para realizar a simulação física desejada. O método “atualiza” será chamado para modificar a cena a cada novo quadro processado, o método “ccTouchesBegan” será chamado quando o jogador iniciar um toque na tela e o método “ccTouchesEnded” será chamado quando o jogador terminar o toque na tela. Precisamos desses dois métodos de tratamento de toques porque faremos com que o Sonic pule mais alto quando o jogador segurar o dedo na tela do que quando o jogador apenas encostar rapidamente. Salve o arquivo “HelloWorldScene.h”.
Agora modificaremos algumas linhas de código no arquivo “HelloWorldScene.cpp”, para que tenhamos a referência do sprite do Sonic e do tiled map da plataforma quando precisarmos. Abra esse arquivo e modifique a seguinte linha de código:
CCSprite* sonic = CCSprite::createWithSpriteFrameName(“SonicCorrendo1.png”);
para isso:
sonic = CCSprite::createWithSpriteFrameName(“SonicCorrendo1.png”);
Da mesma forma, modifique a seguinte linha de código:
CCTMXTiledMap* plataforma = CCTMXTiledMap::create(“plataforma.tmx”);
para isso:
plataforma = CCTMXTiledMap::create(“plataforma.tmx”);
Agora iniciaremos a inclusão de código que implementa a física que desejamos. Primeiramente, vamos inicializar as variáveis físicas que declaramos no arquivo “HelloWorldScene.h”. Insira as seguintes linhas de código:
HelloWorld::gravidade = 0.0;
HelloWorld::posicaoYInicial = HelloWorld::sonic->getPositionY();
HelloWorld::velocidadeYInicial = 0.0;
HelloWorld::tempoCorrido = 0.0;
setTouchEnabled(true);
schedule(schedule_selector(HelloWorld::atualiza));
logo abaixo dessa:
addChild(plataforma);
Todas as variáveis foram criadas com o objetivo de realizar a simulação física apenas na vertical. Como o nosso Sonic não anda para frente nem para trás, não há necessidade de incluir outras variáveis físicas para isso. Dessa forma, como o personagem jogável está, inicialmente, sobre uma plataforma, então inicializamos as variáveis gravidade, velocidade inicial vertical e tempo corrido como iguais a zero. Isso fará com que o Sonic permaneça sempre no mesmo lugar, pelo fato da velocidade inicial e gravidade serem zeradas. Note que também acionamos a tela de toque e especificamos a necessidade de executar o método “atualiza” a cada novo quadro gerado.
Para finalizar, adicione as seguintes linhas de código no final do arquivo:
void HelloWorld::atualiza(float dt) {
CCRect s = HelloWorld::sonic->boundingBox();
s.origin.y++;
if(s.intersectsRect(HelloWorld::plataforma->boundingBox())) {
HelloWorld::gravidade = 0.0;
HelloWorld::posicaoYInicial = HelloWorld::plataforma->getPositionY()+
HelloWorld::plataforma->boundingBox().size.height+HelloWorld::sonic->boundingBox().size.height/2;
HelloWorld::velocidadeYInicial = 0.0;
HelloWorld::tempoCorrido = 0.0;
}
HelloWorld::tempoCorrido += dt;
HelloWorld::sonic->setPosition(ccp(HelloWorld::sonic->getPositionX(),HelloWorld::posicaoYInicial+
HelloWorld::velocidadeYInicial*HelloWorld::tempoCorrido+
(HelloWorld::gravidade*HelloWorld::tempoCorrido*HelloWorld::tempoCorrido)/2));
}
void HelloWorld::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent) {
if(HelloWorld::gravidade==0.0) {
HelloWorld::gravidade = -20*HelloWorld::sonic->boundingBox().size.height;
HelloWorld::posicaoYInicial = HelloWorld::sonic->getPositionY();
HelloWorld::velocidadeYInicial = 13*HelloWorld::sonic->boundingBox().size.height;
HelloWorld::tempoCorrido = 0.0;
}
}
void HelloWorld::ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent) {
if(HelloWorld::gravidade==-20*HelloWorld::sonic->boundingBox().size.height) {
HelloWorld::velocidadeYInicial += HelloWorld::gravidade*HelloWorld::tempoCorrido;
HelloWorld::gravidade = -40*HelloWorld::sonic->boundingBox().size.height;
HelloWorld::posicaoYInicial = HelloWorld::sonic->getPositionY();
HelloWorld::tempoCorrido = 0.0;
}
}
Iniciarei a explicação do código adicionado pelo método “atualiza”. Nele, nós primeiramente capturamos o quadrado que limita as beiradas do Sonic e verificamos se ele está encostando na plataforma. Caso isso aconteça, então precisamos deixá-lo exatamente sobre ela. Isso porque, quando o Sonic está caindo, ele poderá entrar na frente dos blocos marrons que formam plataforma. Note que igualamos as variáveis físicas “gravidade”, “posicaoYInicial” e “tempoCorrido” a zero. Como o Sonic estaria sobre o chão, então não há movimentação vertical. No mesmo método, nós incrementamos a variável “tempoCorrido” com o tempo entre quadros e atualizamos a posição do Sonic. Dessa forma, quando o Sonic estiver no ar, ele cairá e, quando ele encostar na plataforma, não sofrerá movimentação vertical.
Nos métodos “ccTouchesBegan” e “ccTouchesEnded” nós modificamos as variáveis físicas para que seja inclusa a funcionalidade de saltos. Note que, caso o jogador inicie um toque na tela, nós inicializamos a velocidade inicial do Sonic com um valor positivo (para ele subir) e a gravidade com um valor negativo (para ele ir descendo com o tempo). Note também, que, para fazer com que o Sonic dê um salto maior caso o jogador segure o dedo na tela, a gravidade é modificada para um valor modular menor quando o jogador inicia o toque e ela é ela modificada para um valor modular maior caso ele solte o dedo da tela. Salve e compile o código e execute o jogo. O resultado é algo como o que é mostrado na animação a seguir. Veja como o Sonic salta mais alto quando o dedo é segurado na tela.
Vimos nesse tutorial como adicionar a funcionalidade de saltar com o Sonic e incluímos a simulação física de gravidade e de detecção e resposta de colisão com o chão. Como nós mesmos implementamos o motor físico, precisamos criar quatro variáveis físicas referentes ao movimento uniformemente variado. Fizemos também com que o Sonic pule mais alto caso o jogador segure o dedo na tela. No próximo tutorial, incluiremos a criação de plataformas com blocos marrons para que possamos fazer com que o Sonic corra no ambiente.
Um grande abraço e até mais. []