Uma colisão é o choque entre dois corpos num determinado espaço. É, basicamente, o que acontece quando 2 carros se batem em alta velocidade. Também é por causa disto que você não atravessa paredes, tendo sua liberdade de andar e explorar o espaço limitada. Este conceito é bastante utilizado na criação de jogos, pois, na grande maioria deles, há colisão ou choque entre corpos. Sem a aplicação deste conceito, seu objeto poderia tranquilamente atravessar uma parede sem que você queira.
O nosso exemplo se baseará no mesmo apresentado na postagem anterior: Criando animações com EaselJs. Porém ,com algumas diferenças. Nesta demonstração, será utilizado canvas (Onde se desenham animações específicas), javascript (Linguagem de script utilizada nos navegadores) e easeljs (Biblioteca javascript que encapsula alguns métodos próprios para lidar com CANVAS). A documentação desta biblioteca está disponível em EaselJs.
Será criada uma animação que se consistirá no seguinte: Duas bolas (Vermelha e azul). A bola azul irá onde sempre seguir o quadrado laranja. O quadrado laranja será o ponto onde você pode fazer clique ou toque (Caso utilize um dispositivo TOUCH). Depois de um tempo, irá aparecer um círculo negro, que é aonde, empregando os métodos de colisão, você deverá levar a bola vermelha.
Então, seguem abaixo as propriedades das 2 bolas:
function constroe(){
pos = definePosicaoRandomica(w,l);
bola.x = pos.x;
bola.y = pos.y;
bola.vx = 4;
bola.vy = 4;
bola.r = r;
pos = definePosicaoRandomica(w,l);
red.x = pos.x;
red.y = pos.y;
red.vx = 2;
red.vy = 2;
red.r = r;
pos = definePosicaoRandomica(w,l);
saida.x = pos.x;
saida.y = pos.y;
saida.r = 20;
}
Quando a página é carregada, é executado o método init(). Este método, basicamente, instancia os objetos, desenha os mesmos na tela, e associa eventos de clique e de toque á determinados métodos.
function init() {
w = document.getElementById("demoCanvas").width;
l = document.getElementById("demoCanvas").height;
stage = new createjs.Stage("demoCanvas");
r = 10;
bola = new createjs.Shape();
red = new createjs.Shape();
es = new createjs.Shape();
saida = new createjs.Shape();
saida.ex = false;
var is_touch_device = 'ontouchstart' in document.documentElement;
constroe();
desenha();
createjs.Ticker.init();
createjs.Ticker.on("tick", tick);
createjs.Ticker.setFPS(50);
if(is_touch_device === true){
document.getElementById("demoCanvas").addEventListener("touchstart",handleTouch,false);
}else{
document.getElementById("demoCanvas").onclick = function(e){
handleClique(e);
}
}
}
Como você deve perceber, quando houve clique em alguma área delimitada pelo canvas, ou algum toque, são executados métodos específicos de toque ou de clique. Porém, ambos fazem a mesma coisa: Capturar coordenadas do mouse ou do toque. Isto para que, onde você tocar ou clicar, ficará o ponto laranja. O ponto laranja será seguido pela bola azul, graças ao método perseguicao().
function handleTouch(e){
es.x = 0;
es.y = 0;
var coords = getCoordsTouch(e);
es.x = coords.x;
es.y = coords.y;
}
function getCoordsTouch(event){
var saida = {};
saida.x = event.targetTouches[0].pageX - document.getElementById("demoCanvas").offsetLeft;
saida.y = event.targetTouches[0].pageY - document.getElementById("demoCanvas").offsetTop;
return saida;
}
function handleClique(e){
es.x = 0;
es.y = 0;
var pX;
var pY;
pX = e.pageX - document.getElementById("demoCanvas").offsetLeft;
pY = e.pageY - document.getElementById("demoCanvas").offsetTop;
es.x = pX;
es.y = pY;
}
function perseguicao(obj1,obj2){
// Animação de perseguição
if(obj1.x < obj2.x){
if(obj1.vx < 0){
obj1.vx *= -1;
}
}else if(obj1.x > obj2.x){
if(obj1.vx > 0){
obj1.vx *= -1;
}
}
if(obj1.y < obj2.y){
if(obj1.vy < 0){
obj1.vy *= -1;
}
}else if(obj1.y > obj2.y){
if(obj1.vy > 0){
obj1.vy *= -1;
}
}
}
A função tick() será executada á cada 50 milisegundos, sendo a função responsável pela continuidade e por dar vida á animação.
function tick(event) {
perseguicao(bola,es);
bola.x += bola.vx;
bola.y += bola.vy;
red.x += red.vx;
red.y += red.vy;
if(checaColisao(bola,red) === true ){
if(red.x > bola.x){
if(red.vx < 0){
red.vx *= -1;
bola.vx *= -1;
}
}else if(red.x < bola.x){
if(red.vx > 0){
red.vx *= -1;
bola.vx *= -1;
}
}
if(red.y > bola.y){
if(red.vy < 0){
red.vy *= -1;
bola.vy *= -1;
}
}else if(red.y < bola.y){
if(red.vy > 0){
red.vy *= -1;
bola.vy *= -1;
}
}
}
checaLimites(bola);
checaLimites(red);
if(createjs.Ticker.getTime() > 10000){
saida.ex = true;
if(checaColisao(red,saida) === true){
alert("FINISH");
createjs.Ticker.reset();
// Rever como reexecutar o ticker
init();
}
}
stage.removeAllChildren();
desenha();
stage.update(event);
}
Vejamos como serão tratadas as colisões nesta animação, que ocorrem entre a bolinha azul e a vermelha:
Primeiramente, na função tick(), especificamente no método checaColisao(), é feita uma verificação. Nesta checagem, basicamente, é calculada a distância entre estes dois objetos, utilizando o princípio de distância de dois pontos. Caso queira saber mais, acesse Distância entre dois pontos. Se houve colisão, a bolinha vermelha é empurrada, graças ao impacto trazido pela bola azul. Logo, como houve resistência, o mesmo acontece com a bolinha azul.
function checaColisao(obj1,obj2){
var dX = obj2.x - obj1.x;
var dY = obj2.y - obj1.y;
var distance = Math.sqrt((dX * dX) + (dY * dY));
if(distance < (obj1.r + obj2.r )){
return true;
}
return false;
}
É verificado se algum dos elementos se choca com as bordas da tela, através do método checaLimites(), chamado dentro de tick(). Se sim, então a parede reflete o impacto recebido pelo corpo.
function checaLimites(obj){
if( (obj.x + obj.r) > w ){
obj.vx *= -1;
}else if( (obj.x-obj.r ) < 0){
obj.vx *= -1;
}
if( (obj.y + obj.r) > l ){
obj.vy *= -1;
}else if( (obj.y-obj.r) < 0){
obj.vy *= -1;
}
}
Depois de 10 segundos, aparece um círculo negro, que é para onde você deve levar o círculo azul. Se houve colisão entre a bola azul e o círculo negro, então, o jogo se encerra.
Links:
Página de testes
Download
Outro exemplo de colisões (De um cara que manja muito, que não sou eu!)
Nenhum comentário:
Postar um comentário