A box2D é uma biblioteca com métodos que simplificam a aplicação de física nas aplicações. A utilização da box2D na Gideros depende da inclusão do recursos através da instrução require “box2d”, como ilustrado no código a seguir. Para a aplicação faremos uso de 2 sprites da Gideros que se encontram em /examples/physics/ e que são o grass.png e box.png.
Após adicionar a biblioteca, precisamos criar um mundo e adicionar elementos nesse mundo. A definição de um mundo é realizada através do método b2.World.new() que espera até 3 parâmetros, sendo:
- Primeiro uma gravidade horizontal: aplicada para simular o vento. Valores positivos fazem essa gravidade “empurrar” para a direita e valores negativos levam para a esquerda;
- O segundo parâmetro é a gravidade: a gravidade da Terra é muitas vezes simplificada para 9,8; e
- Como terceiro parâmetro tem-se se a física deve ser aplicada para objetos inativos. Normalmente deixa-se os elementos sem simulação para diminuir o custo computacional, sendo necessário informar, nessa situação, o valor true para método que já o valor padrão.
A instrução seguinte mostrada não código é responsável por criar um novo corpo no mundo. Criaremos dois corpos nesse exemplo, onde o primeiro representará a bola e o segundo representará o chão da aplicação. Começando pela bola, foi especificado dois itens de sua criação, onde primeira foi informado o tipo e como a bola irá mover-se utilizando a física do jogo, esta foi definida como dinâmica e foi definida uma posição inicial para início do objeto.
O primeiro passo para detalhar um corpo é especificar sua forma primitiva. No código abaixo está inicialmente instanciando uma forma de polígono e em seguida configurando essa forma para o formato de uma caixa. Como parâmetros para o método setAsBox são fornecidos os tamanhos de metade da largura e metade da altura o objeto (como a figura box.png será utilizada para representar essa forma e ela possui altura e largura de 80 pixels, foi informado o valor 40 para cada parâmetro).
Na terceira instrução mostrada no código abaixo, é adiciona uma série de propriedades física ao elemento que está sendo especificado. O primeiro parâmetro informado é a nossa forma e depois são informadas três propriedades principais dos corpos físicos:
- Densidade (density): a densidade é multiplicada pela área do formato do corpo para determinar sua massa. A base para este cálculo é que 1.0 é equivalente à água.
- Elastidade/restituição (restitution): usada para calcular o quanto de velocidade do objeto é retornada depois que uma colisão ocorre. Um valor de 1.0 significada que o objeto mantém toda sua velocidade e nada é perdido durante a colisão. O valor padrão é 0.2.
- Fricção (friction): A fricção é aplicada quando um corpo se move através do ambiente. O padrão é 0.3.
As 3 linhas finais do código são para adicionar a representação gráfica nessa forma especificada. Duas das instruções já são conhecidas, enquanto a instrução do meio utiliza o método setAnchorPoint() que é novo. Esse método é para determinar o ponto de ancoragem do gráfico, sendo que esse ponto afeta o posicionamento. A definição com os valores 0.5, desloca o ponto de origem da figura para o centro dela (o valor padrão é 0,0).
Para adicionar o chão de grama, fazemos inclusão do elemento gráfico da grama e a posicionamos na parte inferior da tela. Para poder interagir com a física de nosso outro objeto, precisamos defini-la também como um corpo. O chão será um corpo estático o que já é padrão do método createBody(), então não serão especificados valores para essa definição. Já a forma foi definida pelo método EdgeShape.new() que solicita o ponto inicial e o ponto final.
Agora temos criados dois objetos e duas representações gráficas, uma para cada objeto. A representação do chão é fixa já que estão o corpo que representa o chão e seu gráfico, parados no mesmo lugar. O mesmo não acontece com a caixa, onde precisaremos fazer a representação gráfica da caixa seguir o corpo que está sofrendo as forças físicas. Para fazer o acompanhamento do corpo e do gráfico, precisamos adicionar um evento que a cada frame sincronize os dois. O código abaixo realiza essa tarefa fazendo o gráfico seguir a mesma posição e ângulo do corpo.
Uma rápida alteração no código: altere a gravidade horizontal para 2, incorpore ao projeto a imagem da bola e adicione ela no lugar da box.png. Em seguida, troque a definição da forma da caixa para local para shape = b2.CircleShape.new(0,0,40), sendo 40 o raio correspondente da figura da bola. Teste agora o resultado e veja a física sendo aplicada a esse corpo agora redondo e que precisa girar.