Tutorial: Criando um jogo de desviar o objeto – Parte 3: Implementando o disparo das pedras

Foi muito legal podermos movimentar o crânio de cristal para onde queremos na tela do aparelho.

Porém, não há graça em apenas movimentá-lo, está faltando um desafio no jogo.

Vamos implementar o disparo de pedras para que possamos desviar o crânio delas.

No tutorial passado nós implementamos a principal funcionalidade do jogo de desviar o crânio de cristal das pedras: a movimentação dele. Vimos que precisávamos criar uma variável para que pudéssemos saber se o jogador estava segurando o crânio ou não. No final, conseguimos movimentar o crânio clicando nele e o arrastando na tela. Nesse tutorial nós implementaremos a segunda principal funcionalidade do nosso game: o arremesso de várias pedras de forma aleatória para que o jogador desvie o crânio delas.

Inicialmente vamos abrir os arquivos que contêm os códigos criados até esse momento. Caso você não acompanhou a programação até agora, dê uma olhada no tutorial passado. Abra o arquivo “HelloWorldScene.h” e adicione as seguintes linhas de código:

void criaPedra();

void destroiPedra(cocos2d::CCNode* s);

logo abaixo dessa linha de código:

void ccTouchesMoved(cocos2d::CCSet *pTouches,cocos2d::CCEvent *pEvent);

A edição desse arquivo é sempre mais simples. Salve-o e o feche. Agora abra o arquivo “HelloWorldScene.cpp” e apague as seguintes linhas de código:

CCSprite* pedra = CCSprite::createWithSpriteFrameName(“pedra.png”);

pedra->setScale((0.2*size.height)/pedra->boundingBox().size.height);

pedra->setPosition(ccp(size.width/2 + pedra->boundingBox().size.width/2,size.height/2));

addChild(pedra);

Incluímos essas linhas de código adicionado no primeiro tutorial dessa sequência. Estamos removendo – as agora porque essas linhas existiam apenas com o objetivo de inserirmos uma pedra na tela para sabermos como elas serão futuramente. Agora que vamos arremessá-las, podemos tirar essa pedra que estava lá apenas excluindo essas linhas de código.

Agora adicione a seguinte linha de código:

schedule(schedule_selector(HelloWorld::criaPedra),0.5);

logo abaixo dessa linha de código:

setTouchEnabled(true);

Para finalizar, adicione as seguintes linhas de código no final do arquivo:

void HelloWorld::criaPedra() {

    static unsigned int seed = time(NULL);

    CCSize size = CCDirector::sharedDirector()->getWinSize();

    CCPoint in,fi;

    CCSprite* pedra = CCSprite::createWithSpriteFrameName(“pedra.png”);

    pedra->setScale((0.2*size.height)/pedra->boundingBox().size.height);

    addChild(pedra);

    srand(seed);

    seed = rand();

    if(seed%4==0) {

        srand(seed);

        seed = rand();

        in.x = (((float)seed)/RAND_MAX)*size.width;

        in.y = size.height + pedra->boundingBox().size.height/2;

    } else if(seed%4==1) {

        srand(seed);

        seed = rand();

        in.x = size.width + pedra->boundingBox().size.width/2;

        in.y = (((float)seed)/RAND_MAX)*size.height;

    } else if(seed%4==2) {

        srand(seed);

        seed = rand();

        in.x = (((float)seed)/RAND_MAX)*size.width;

        in.y = -pedra->boundingBox().size.height/2;

    } else {

        srand(seed);

        seed = rand();

        in.x = -pedra->boundingBox().size.width/2;

        in.y = (((float)seed)/RAND_MAX)*size.height;

    }

    srand(seed);

    seed = rand();

    if(seed%4==0) {

        srand(seed);

        seed = rand();

        fi.x = (((float)seed)/RAND_MAX)*size.width;

        fi.y = size.height + pedra->boundingBox().size.height/2;

    } else if(seed%4==1) {

        srand(seed);

        seed = rand();

        fi.x = size.width + pedra->boundingBox().size.width/2;

        fi.y = (((float)seed)/RAND_MAX)*size.height;

    } else if(seed%4==2) {

        srand(seed);

        seed = rand();

        fi.x = (((float)seed)/RAND_MAX)*size.width;

        fi.y = -pedra->boundingBox().size.height/2;

    } else {

        srand(seed);

        seed = rand();

        fi.x = -pedra->boundingBox().size.width/2;

        fi.y = (((float)seed)/RAND_MAX)*size.height;

    }

    pedra->setPosition(in);

    CCMoveTo* movimento = CCMoveTo::create(2,fi);

    pedra->runAction(movimento);

    CCCallFuncN* desalocacao = CCCallFuncN::create(this,callfuncN_selector(HelloWorld::destroiPedra));

    CCRotateTo* rotacao = CCRotateTo::create(2,180);

    pedra->runAction(CCSequence::create(rotacao,desalocacao,NULL));

}

void HelloWorld::destroiPedra(CCNode* s) {

    removeChild(s);

}

O que fizemos incluindo esse código anterior? Primeiramente especificamos ao Cocos2d-x que o método “criaPedra” seja chamado a cada meio segundo. Apenas pelo nome do método vocês já podem ter uma ideia do que ele faz. A cada meio segundo, uma nova pedra é arremessada na tela. Mas, como isso é feito? Primeiramente é criado um novo Sprite com a imagem da pedra. Esse Sprite é redimensionado para que ele não fique muito grande em telas pequenas nem muito pequeno em telas grandes. Logo após, eu encontro um ponto de onde a pedra será arremessada e um ponto onde a pedrá terminará o movimento dela. Esses pontos são encontrados aleatoriamente em qualquer posição dos quatro lados da tela do aparelho. Para terminar, fazemos o Sprite da pedra percorrer o caminho do ponto de início até o ponto de fim em um tempo de 2 segundos. Para melhorar o aspecto gráfico do arremesso, fazemos as pedras rotacionarem enquanto se movimentam na tela. Pronto, temos as pedras sendo arremessadas. O resultado é algo parecido com o que é mostrado na Figura 1.

Figura 1 - Execução do jogo

Figura 1 – Execução do jogo

Quando as pedras terminam o caminho, o Sprite que foi criado é removido da memória do aparelho. Notem que ainda não há tratamento de colisão com o crânio. Se as pedras acertarem o crânio, nada acontece. Resolvi deixar para implementarmos isso no próximo tutorial, com mais calma. =]

Vimos nesse tutorial como implementar o disparo das pedras na tela do celular. Criamos um Sprite a cada meio segundo e o fazemos percorrer a tela de um ponto até outro. No próximo tutorial veremos como implementar a detecção e tratamento de colisão. Vocês hão de esperar. ;D

Um grande abraço e até mais.

Santiago Viertel

Santiago Viertel

Formado em Bacharelado em Ciência da Computação (UDESC), mestre e doutorando em Análise de Algoritmos (UFPR). Foi programador da Céu Games por 8 anos. Possui a preferência por jogos de estratégia e de tiro em primeira pessoa. Jogando bastante DotA 2, Left 4 Dead 2 e Age of Empires II HD.

Send this to a friend