Fizemos os inimigos aparecerem e desaparecerem da tela para adicionar dinamismo ao jogo.
A nave do jogador ainda não faz nenhum tipo de movimentação… nem atira.
Hoje faremos com que ela se movimente para a esquerda ou direita.
Todos os tutoriais da sequência
Parte 1 – Parte 2 – Parte 3 – Parte 4 – Parte 5 – Parte 6
Vimos no tutorial passado como fazer os helicópteros entrarem e saírem da tela. Para isso, dividimos essas animações em duas: uma que os inimigos saem da tela; outra que os inimigos entram. No início do jogo, nós executamos a animação de entrada dos inimigos. Ao passarem cinco segundos, eles saem da tela e entram novamente para as suas posições normais. Com isso, fizemos que este processo ocorra de cinco em cinco segundos.
No tutorial de hoje implementaremos a movimentação da nave do jogador. Para isso, precisaremos adicionar os botões de interação que fazem a nave se movimentar para a esquerda ou direita. Por fim, precisaremos criar as funcionalidades de ambos os botões.
Adicionando os botões na tela
Iniciaremos a programação adicionando os botões que fazem a nave do jogador andar para a esquerda e direita. Como de praxe, precisamos declarar na classe “HelloWorld” duas variáveis de sprites que representam esses botões. Assim, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:
cocos2d::CCSprite* botaoDireita;
cocos2d::CCSprite* botaoEsquerda;
logo abaixo dessa:
cocos2d::CCSprite* sombraInimigos[6];
Agora criaremos esses dois sprites e os mostraremos na tela. Para isso, abra o arquivo “HelloWorldScene.cpp” e adicione as seguintes linhas de código:
HelloWorld::botaoEsquerda = CCSprite::createWithSpriteFrameName(“BotaoEsq.png”);
HelloWorld::botaoEsquerda->setScale((0.2*size.width)/HelloWorld::botaoEsquerda->boundingBox().size.width);
HelloWorld::botaoEsquerda->setPosition(ccp(0.1*size.width,HelloWorld::botaoEsquerda->boundingBox().size.height/2));
addChild(HelloWorld::botaoEsquerda,3);
HelloWorld::botaoDireita = CCSprite::createWithSpriteFrameName(“BotaoDir.png”);
HelloWorld::botaoDireita->setScale((0.2*size.width)/HelloWorld::botaoDireita->boundingBox().size.width);
HelloWorld::botaoDireita->setPosition(ccp(0.35*size.width,HelloWorld::botaoDireita->boundingBox().size.height/2));
addChild(HelloWorld::botaoDireita,3);
logo ACIMA dessa:
HelloWorld::entraInimigos();
Você pode notar no código que acabamos de adicionar que nós apenas criamos os sprites dos botões, os escalamos, os posicionamos na tela e os mostramos ao jogador.
Agora implementaremos as suas funcionalidades.
Programando as funcionalidades dos botões
Para podermos fazer os botões funcionarem, precisaremos implementar os métodos “ccTouchesBegan” e “ccTouchesEnded”. Além disso, para que o toque no botão de movimentação do avião não seja confundido com o toque no botão de tiro, precisaremos identificar quando o avião está se movimentando e quando ele está parado. Para isso, precisaremos adicionar na classe “HelloWorld” uma variável que armazena um valor inteiro, que identifica o toque na tela e que fez a nave se movimentar. Dessa foma, abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:
int andando;
void ccTouchesBegan(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
void ccTouchesEnded(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);
logo abaixo dessa:
cocos2d::CCSprite* botaoEsquerda;
Iniciaremos a programação das funcionalidades implementando os métodos “ccTouchesBegan” e “ccTouchesEnded”. Esses métodos são chamados, respectivamente, quando o jogador inicia um toque na tela e quando ele tira o dedo dela. Dessa forma, adicione a implementação do método “ccTouchesBegan” no final do arquivo “HelloWorldScene.cpp”.
void HelloWorld::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent) {
float tempo;
CCSize size = CCDirector::sharedDirector()->getWinSize();
CCPoint ponto = (static_cast<CCTouch*>(pTouches->anyObject()))->getLocationInView();
ponto.y = size.height – ponto.y;
if(HelloWorld::botaoEsquerda->boundingBox().containsPoint(ponto)) {
HelloWorld::jogador->stopAllActions();
HelloWorld::sombraJogador->stopAllActions();
tempo = (HelloWorld::jogador->getPositionX() – HelloWorld::jogador->boundingBox().size.width/2)/300.0;
CCMoveTo *andarJogador = CCMoveTo::create(tempo,ccp(HelloWorld::jogador->boundingBox().size.width/2,HelloWorld::jogador->getPositionY()));
CCArray* framesJogador = CCArray::create();
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador4.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador5.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador6.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador5.png”));
CCRepeatForever* frames = CCRepeatForever::create(CCAnimate::create(
CCAnimation::createWithSpriteFrames(framesJogador,0.1)));
CCMoveTo *andarSombraJogador = CCMoveTo::create(tempo,ccp(HelloWorld::jogador->boundingBox().size.width/2 + 0.15*size.width,HelloWorld::sombraJogador->getPositionY()));
HelloWorld::jogador->setFlipX(false);
HelloWorld::jogador->runAction(andarJogador);
HelloWorld::jogador->runAction(frames);
HelloWorld::sombraJogador->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“JogadorSombra2.png”));
HelloWorld::sombraJogador->setFlipX(false);
HelloWorld::sombraJogador->runAction(andarSombraJogador);
HelloWorld::andando = (static_cast<CCTouch*>(pTouches->anyObject()))->getID();
} else if(HelloWorld::botaoDireita->boundingBox().containsPoint(ponto)) {
HelloWorld::jogador->stopAllActions();
HelloWorld::sombraJogador->stopAllActions();
tempo = (size.width – HelloWorld::jogador->boundingBox().size.width/2 – HelloWorld::jogador->getPositionX())/300.0;
CCMoveTo *andarJogador = CCMoveTo::create(tempo,ccp(size.width – HelloWorld::jogador->boundingBox().size.width/2,HelloWorld::jogador->getPositionY()));
CCArray* framesJogador = CCArray::create();
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador4.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador5.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador6.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador5.png”));
CCRepeatForever* frames = CCRepeatForever::create(CCAnimate::create(
CCAnimation::createWithSpriteFrames(framesJogador,0.1)));
CCMoveTo *andarSombraJogador = CCMoveTo::create(tempo,ccp(size.width – HelloWorld::jogador->boundingBox().size.width/2 + 0.15*size.width,HelloWorld::sombraJogador->getPositionY()));
HelloWorld::jogador->setFlipX(true);
HelloWorld::jogador->runAction(andarJogador);
HelloWorld::jogador->runAction(frames);
HelloWorld::sombraJogador->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“JogadorSombra2.png”));
HelloWorld::sombraJogador->setFlipX(true);
HelloWorld::sombraJogador->runAction(andarSombraJogador);
HelloWorld::andando = (static_cast<CCTouch*>(pTouches->anyObject()))->getID();
}
}
Foram adicionados bastantes códigos, porém todos são simples de entender. Primeiramente, localizamos a posição que houve um toque na tela. Logo após, identificamos se esse toque foi no botão que faz o avião andar para a esquerda ou se foi no outro botão. Caso o toque tenha sido no primeiro botão citado, então realizamos esse tratamento. Na verdade, o método é similar, apenas espelhamos a movimentação do avião.
Note que, para realizar a movimentação de forma correta, primeiramente nós paramos todas as animações que estão em andamento dos sprites da nave e de sua sombra. Logo após, nós calculamos o tempo necessário para ela atravessar a tela e criamos as animações que farão a nave e a sua sombra se movimentarem até o final da tela. Note também que mudamos os frames da nave, para que haja a animação dela realizando uma curva. Por último, nós identificamos que a nave está em movimentação armazenando o número identificador do toque na tela na variável “andando”.
Ainda não terminamos de implementar a funcionalidade dos botões. Implementamos apenas o método que faz o tratamento necessário quando o jogador inicia um toque na tela. Agora precisamos realizar o tratamento de quando o jogador tira o dedo na tela. Para isso, adicione no final do mesmo aquivo a implementação do método “ccTouchesEnded”.
void HelloWorld::ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent) {
if(HelloWorld::andando==(static_cast<CCTouch*>(pTouches->anyObject()))->getID()) {
HelloWorld::jogador->stopAllActions();
HelloWorld::sombraJogador->stopAllActions();
CCArray* framesJogador = CCArray::create();
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador1.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador2.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador3.png”));
framesJogador->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“Jogador2.png”));
HelloWorld::jogador->setFlipX(false);
HelloWorld::jogador->runAction(CCRepeatForever::create(CCAnimate::create(
CCAnimation::createWithSpriteFrames(framesJogador,0.1))));
HelloWorld::sombraJogador->setFlipX(false);
HelloWorld::sombraJogador->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(“JogadorSombra1.png”));
HelloWorld::andando = –1;
}
}
A implementação desse método é mais simples do que a implementação do método “ccTouchesBegan”. Primeiramente é verificado se o jogador parou de realizar um toque em um dos botões de movimentação da nave. Caso isso aconteça, então são paradas todas as animações existentes nos sprites da nave e da sua sombra. É criada uma nova animação no sprite da nave que faz com que ela fique soltando fogo pelas turbinas. Também deixamos a sombra dela pertinente com a sua forma. Por último, fizemos a variável identificadora de movimentação da nave armazenar o valor -1, para que a nave não pare a animação corrente caso o jogador venha a apertar em outro lugar na tela de toque.
Por último, e não menos importante, precisamos acionar a tela de toque e inicializar a variável “andando” com o valor -1. Para isso, no mesmo arquivo, adicione as seguintes linhas de código:
HelloWorld::andando = -1;
setTouchEnabled(true);
logo ACIMA dessa:
HelloWorld::entraInimigos();
Compile o código e execute o jogo. Você verá os dois botões de interação e perceberá que a funcionalidade deles está funcionando devidamente. O resultado é algo parecido com o que é mostrado na animação a seguir.
Vimos nesse tutorial como incluir os botões que movimentam a nave do jogador e como implementar as suas funcionalidades. Precisamos de uma variável identificadora para verificar se um toque na tela recém-finalizado corresponde a um que foi iniciado em um dos botões de movimentação. Essa variável é importante para que o jogo não confunda quando o jogador parar de apertar outro botão que não seja um de movimentação.
Veremos no próximo tutorial como incluir o botão de tiro e como adicionar esta funcionalidade na nave. Também faremos com que os inimigos atirem em tempos aleatórios.
Um grande abraço e até mais. []