# Event Listeners

Existem vários eventos aos quais a cena pode se inscrever para conhecer as ações do jogador enquanto estiver dentro ou próximo da cena.

Para eventos de botão e clique realizados pelo jogador, veja [Eventos de botão](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/click-events).

## Jogador entra ou sai da cena

Sempre que um avatar entra ou sai das parcelas de terra que compõem sua cena, ou teleporta-se para dentro ou fora, isso cria um evento ao qual você pode escutar.

Este evento é acionado por todos os avatares, incluindo o do jogador.

```ts
import { onEnterScene, onLeaveScene } from '@dcl/sdk/src/players'

export function main() {
	onEnterScene((player) => {
		if (!player) return
		console.log('ENTERED SCENE', player)
	})

	onLeaveScene((userId) => {
		if (!userId) return
		console.log('LEFT SCENE', userId)
	})
}
```

Na seção `onEnterScene` evento, a função pode acessar todos os dados retornados por [get player data](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/user-data#get-player-data) através da `player` propriedade. No `onLeaveScene` evento, a função tem acesso apenas ao ID do jogador.

### Apenas jogador atual

Você pode filtrar os eventos acionados para reagir apenas ao avatar do jogador, em vez de outros avatares que possam estar por perto.

```ts
import { getPlayer, onEnterScene, onLeaveScene } from '@dcl/sdk/src/players'

export function main() {
	let myPlayer = getPlayer()

	onEnterScene((player) => {
		if (!player) return
		console.log('ENTERED SCENE', player)

		if (myPlayer && player.userId == myPlayer.userId) {
			console.log('I CAME IN')
		}
	})

	onLeaveScene((userId) => {
		if (!userId) return
		console.log('LEFT SCENE', userId)

		if (myPlayer && userId == myPlayer.userId) {
			console.log('I LEFT')
		}
	})
}
```

Este exemplo primeiro obtém o id do jogador, então se inscreve nos eventos e compara o `userId` retornado pelo evento com o do jogador.

### Consultar todos os jogadores na cena

Percorra a lista completa de jogadores que estão atualmente na sua cena iterando sobre todas as entidades com um `PlayerIdentityData` componente.

```ts
import { PlayerIdentityData, Transform } from '@dcl/sdk/ecs'

export function main() {
	for (const [entity, data, transform] of engine.getEntitiesWith(
		PlayerIdentityData,
		Transform
	)) {
		console.log('PLAYER: ', { entity, data, transform })
	}
}
```

## Jogador altera modo da câmera

Saber o modo da câmera pode ser muito útil para ajustar melhor as mecânicas da sua cena ao que é mais confortável ao usar esse modo. Por exemplo, alvos pequenos são mais difíceis de clicar quando em terceira pessoa.

O trecho a seguir usa a `onChange` função para disparar um evento cada vez que a câmera muda. Também dispara um evento quando a cena carrega, com o modo de câmera inicial do jogador.

```ts
export function main() {
	CameraMode.onChange(engine.CameraEntity, (cameraComponent) => {
		if (!cameraComponent) return
		console.log('Camera mode changed', cameraComponent?.mode)
		// 0 = primeira pessoa
		// 1 = terceira pessoa
	})
}
```

Veja [Verificar modo da câmera do jogador](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/user-data#check-the-players-camera-mode).

## Jogador reproduz animação

Use a `onChange` função no `AvatarEmoteCommand` componente para disparar um evento cada vez que o jogador reproduz um emote. Isso inclui tanto emotes básicos (dança, palmas, aceno, etc.) quanto emotes de tokens.

```ts
import { AvatarEmoteCommand } from '@dcl/sdk/ecs'

export function main() {
	AvatarEmoteCommand.onChange(engine.PlayerEntity, (emote) => {
		if (!emote) return
		console.log('Emote played: ', emote.emoteUrn)
	})
}
```

O evento inclui as seguintes informações:

* `emoteUrn`: Nome do emote executado (ex.: *wave*, *clap*, *kiss*)
* `loop`: Se o emote está em loop ou tocando uma vez
* `timestamp`: Quando o emote foi acionado.

Você também pode detectar emotes de outros jogadores na cena; basta passar uma referência ao outro jogador em vez de `engine.PlayerEntity`.

## Jogador altera perfil

Use a `onChange` função no `AvatarEquippedData` componente para disparar um evento cada vez que o jogador altera uma de suas wearables, ou seus emotes listados na roda de acesso rápido. De forma semelhante, use o `onChange` função no `AvatarBase` para disparar um evento cada vez que o jogador altera suas propriedades básicas de avatar, como cor do cabelo, cor da pele, body shape ou nome.

```ts
import { AvatarEquippedData, AvatarBase } from '@dcl/sdk/ecs'

export function main() {
	AvatarEquippedData.onChange(engine.PlayerEntity, (equipped) => {
		if (!equipped) return
		console.log('New wearables list: ', equipped.wearableUrns)
		console.log('New emotes list : ', equipped.emoteUrns)
	})

	AvatarBase.onChange(engine.PlayerEntity, (body) => {
		if (!body) return
		console.log('New eyes color: ', body.eyesColor)
		console.log('New skin color: ', body.skinColor)
		console.log('New hair color: ', body.hairColor)
		console.log('New body URN: ', body.bodyShapeUrn)
	})
}
```

O evento em `AvatarEquippedData` inclui as seguintes informações:

* `wearableUrns`: A lista de wearables que o jogador atualmente tem equipadas.
* `emoteUrns`: A lista de emotes que o jogador atualmente tem equipados na roda de acesso rápido.

O evento em `AvatarBase` inclui as seguintes informações:

* `campo name`: O nome do jogador.
* `bodyShapeUrn`: Os ids correspondentes ao tipo de corpo masculino ou feminino.
* `skinColor`: Cor da pele do jogador como um `Color4`
* `eyeColor`: Cor dos olhos do jogador como um `Color4`
* `hairColor`: Cor do cabelo do jogador como um `Color4`

Você também pode detectar mudanças em wearables ou avatares de outros jogadores na cena; basta passar uma referência ao outro jogador em vez de `engine.PlayerEntity`.

{% hint style="info" %}
**💡 Tip**: Ao testar em preview com o editor web legado, para evitar usar um avatar aleatório, execute a cena no navegador conectado com sua carteira Metamask.
{% endhint %}

Você também pode detectar mudanças nos perfis de outros jogadores na cena; basta passar uma referência ao outro jogador em vez de `engine.PlayerEntity`.

## Jogador trava ou destrava o cursor

Os jogadores podem alternar entre dois modos de cursor: *cursor travado* modo para controlar a câmera ou *cursor destravado* modo para mover o cursor livremente sobre a UI.

Os jogadores destravam o cursor clicando com o *Botão direito do mouse* ou pressionando a tecla *Esc* , e travam o cursor novamente clicando em qualquer lugar da tela.

Adicione um `PointerLock` componente ao `engine.CameraEntity` entidade na sua cena, e use o `onChange` função no `PointerLock` componente para disparar um evento cada vez que o jogador muda entre os dois modos de cursor.

```ts
import {PointerLock} from '@dcl/sdk/ecs'

export function main() {
    PointerLock.onChange(engine.CameraEntity, (pointerLock) => {
		    if (!pointerLock) return
		    if(pointerLock.isPointerLocked){
			    // Mostrar dica sobre o modo do cursor
		   }
	})
}
```

Você pode usar essa informação para incentivar o jogador sutilmente, como mostrar um popup de UI dizendo que este jogo é melhor experimentado com o cursor destravado. Ou você também pode forçar o modo do cursor do jogador alterando o `isPointerLocked` no componente. O exemplo a seguir sempre define o modo do cursor como destravado:

```ts
import {PointerLock} from '@dcl/sdk/ecs'

export function main() {
    PointerLock.createOrReplace(engine.CameraEntity, {isPointerLocked: false});
    PointerLock.onChange(engine.CameraEntity, (pointerLock) => {
		    if (!pointerLock) return
		    if(pointerLock.isPointerLocked){
			    PointerLock.getMutable(engine.CameraEntity).isPointerLocked = false
		   }
	})
}
```
