Começando com Crafty: Entidades
() translation by (you can also view the original English article)
No tutorial anterior, aprendemos o básico sobre entidades e como elas são os blocos base do jogo. Nesse tutorial, iremos além do básico e aprenderemos mais detalhes sobre entidades.
Entidades e Seus Componentes
Cada entidade é feita de vários componentes. Cada um deles adiciona sua própria funcionalidade à entidade. Crafty oferece vários componentes embutidos, mas podemos criar nossos próprios usando Crafty.c()
.
Aprendemos alguns componentes básicos como 2D
, Canvas
, Color
e Fourway
no primeiro tutorial. Comecemos criando outra entidade usando-os:
1 |
var playerBox = Crafty.e("2D, Canvas, Color, Fourway") |
2 |
.attr({ x: 50, y: 50, w: 50, h: 50 }) |
3 |
.color("black") |
4 |
.fourway(200); |
Quando temos várias entidades com diferentes componentes, pode ser necessário saber se uma dada entidade tem um dado componente anexado. Podemos fazê-lo usando o método .has()
.
Similarmente, adicionamos componentes a uma entidade usando .addComponent()
. Para adicionar vários de uma vez, podemos passá-los em um texto separado por vírgula, ou cada um deles com um argumento diferente. Nada acontecerá se a entidade já tiver o dado componente que tentamos adicionar.
1 |
playerBox.addComponent("Jumper, Gravity, Collision"); |
2 |
playerBox.addComponent("Jumper", "Gravity" , "Collision"); |
Também podemos remover componentes de uma entidade usando .removeComponente(String Component[, soft])
. Esse método recebe dois argumentos. O primeiro é o que queremos remover e o segundo determina se a exclusão do elemento é reversível ou integral. Exclusão reversível apenas fará .has()
retornar false
quando consultado para aquele componente. Exclusão integral removerá todas as propriedades associadas e métodos do componente.
Por padrão, todos os componentes são reversíveis. Podemos passar false
pro segundo argumento para exclusão integral.
Configurando Valores de Diferentes Atributos
É provável que precisemos configurar valores de atributos específicos em todas entidades do jogo. Por exemplo, uma entidade de comida do personagem no jogo deve parecer diferente que a entidade representando o personagem em si. De forma similar, energéticos serão diferentes de comidas. Crafty permite configurar valores de entidades diferentes num jogo, separadamente, ou de uma só ver via .attr()
.
A entidade principal é guardada na variável playerBox
. Então, podemos configurar diferentes propriedades diretamente usando o código abaixo:
1 |
playerBox.x = 50; |
2 |
playerBox.y = 50; |
3 |
playerBox.z = 2; |
4 |
|
5 |
playerBox.attr({ x:50, y:50, z:2 }) |
A propriedade z
configura o z-index das várias entidades. Uma com valor de z
maior será criada acima das outras. Lembremos que apenas inteiros são válidos para z-index.
Criemos uma entidade comida com tamanho, posição e rotações diferentes. A rotação é em graus e usamos valores negativos para girar na direção anti-horária.
1 |
var foodBox = Crafty.e("2D, Canvas, Color, Food") |
2 |
.attr({ x: 150, y: 250, w: 10, h: 10 }) |
3 |
.color("red"); |
4 |
|
5 |
foodBox.attr({ z:1, rotation: 45 }); |
Como podemos ver na demo abaixo, tanto a comida como o jogador são bem distinguíveis. Se tentarmos mover o jogador acima da comida, veremos que a comida é desenhada abaixo do jogador pelo valor menor de z-index.
Vinculando Eventos a Entidades
Há vários eventos que podemos responder ao criar um jogo. Por exemplo, podemos vincular uma entidade jogador ao evento KeyDown
se quisermos que ele cresça em tamanho quando a tecla for apertada. Crafty permite vincular entidade a eventos específicos usando .bind()
. Eis um exemplo:
1 |
playerBox.bind('KeyDown', function(e) { |
2 |
if (e.key == Crafty.keys.T) { |
3 |
this.alpha = 0.5; |
4 |
}
|
5 |
if (e.key == Crafty.keys.O) { |
6 |
this.alpha = 1; |
7 |
}
|
8 |
});
|
Na demo a seguir, tentemos mover o jogador sobre a comida e apertemos as teclas 'T' e 'O'. Apertar 'T' mudará a opacidade do jogador para 0.5 e apertar 'O' restaurará para 1.
Agora, vinculemos um evento de colisão a nosso jogador para ele crescer ao tocar em comida. Adicionaremos um componente de colisão ao jogador e usaremos .checkHits()
. Esse método realizará as verificações de colisão contra todas as entidades que tiverem pelo menos um dos componentes especificados ao invocar .checkHits()
.
Quando colisão ocorre, um evento HitOn
é ativado. Ele também terá informação relevante do evento de toque. Um evento HitOff
é ativado quando a colisão termina.
1 |
playerBox.checkHits("Food") |
2 |
.bind("HitOn", function(hitData) { |
3 |
this.color("green"); |
4 |
this.w = this.w + 3; |
5 |
this.h = this.h + 3; |
6 |
});
|
A largura e altura do jogador aumentam sempre que um toque acontecer. Usamos esse evento para várias coisas, incluindo mudar a posição da comida ou aumentar a pontuação do jogo. Também podemos destruir a entidade comida usando o destroy()
quando o toque for detectado.
Selecionando
Na seção anterior, mudamos as propriedades de uma única entidade. Isso pode ser feito usando a variável de cada entidade. Isso não é prático se lidamos com 20 ou mais entidades.
Quem usou jQuery sabe como ela seleciona elementos. Por exemplo, podemos usar $('p')
para selecionar todos os parágrafos. De forma similar, selecionamos todas entidades que tiverem um componente em comum com Crafty('componente')
.
Eis alguns exemplos:
1 |
// Select all entities that have the Gravity component
|
2 |
Crafty("Gravity"); |
3 |
|
4 |
// Select all entities that have either DOM or Canvas component
|
5 |
Crafty("Gravity, Jumper"); |
6 |
|
7 |
// Select all entities that have both Gravity and Jumper component
|
8 |
Crafty("Gravity Jumper"); |
Com a seleção, podemos saber quantos elementos foram selecionados usando a propriedade length. Podemos iterar por cada entidade ou vincular eventos a todas elas de uma só vez. O código a seguir mudará para púrpura todas as entidades comidas cujo valor x
seja maior que 300.
1 |
Crafty("Food").each(function() { |
2 |
if(this.x > 300) { |
3 |
this.color("purple"); |
4 |
}
|
5 |
});
|
Com a seleção, podemos usar get()
para obter um vetor com todas as entidades dela. Podemos acessar uma entidade específica usando um índica, get(índice)
.
Pensamentos Finais
Hoje, aprendemos a adicionar e remover componentes de uma entidade. Também aprendemos como selecionar aquelas com um ou mais componentes, e a manipular seus atributos e propriedades uma a uma. Tudo isso será muito útil quando manipularmos diferentes entidades na tela com base em vários eventos.
Quaisquer dúvidas sobre o tutorial, deixe um comentário abaixo.