# Escuchadores de eventos

Hay varios eventos a los que la escena puede suscribirse para conocer las acciones del jugador mientras está dentro o cerca de la escena.

Para eventos de botón y clic realizados por el jugador, vea [Eventos de botón](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events).

## El jugador entra o sale de la escena

Siempre que un avatar pise dentro o fuera de los parcels de tierra que componen tu escena, o se teletransporte dentro o fuera, esto crea un evento al que puedes suscribirte.

Este evento es activado por todos los avatares, incluido el del jugador.

```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)
	})
}
```

En el `onEnterScene` evento, la función puede acceder a todos los datos devueltos por [obtener datos del jugador](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/user-data#get-player-data) vía el `player` propiedad. En el `onLeaveScene` evento, la función solo tiene acceso al ID del jugador.

### Solo jugador actual

Puedes filtrar los eventos activados para reaccionar únicamente al avatar del jugador, en lugar de a otros avatares que puedan estar alrededor.

```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 ejemplo primero obtiene el id del jugador, luego se suscribe a los eventos y compara el `userId` devuelto por el evento con el del jugador.

### Consultar todos los jugadores en la escena

Revisa la lista completa de jugadores que están actualmente en tu escena iterando sobre todas las entidades con un `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 })
	}
}
```

## El jugador cambia el modo de cámara

Conocer el modo de cámara puede ser muy útil para ajustar la mecánica de tu escena y adaptarla mejor a lo que resulta más cómodo usando ese modo. Por ejemplo, los objetivos pequeños son más difíciles de clicar en 3rd person.

El siguiente fragmento usa la `onChange` función para disparar un evento cada vez que la cámara cambia. También lanza un evento cuando la escena se carga, con el modo de cámara inicial del jugador.

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

Ver [Comprobar el modo de cámara del jugador](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/user-data#check-the-players-camera-mode).

## El jugador reproduce una animación

Usa la `onChange` función en el `AvatarEmoteCommand` componente para disparar un evento cada vez que el jugador reproduce un emote. Esto incluye tanto emotes base (dance, clap, wave, etc.) como emotes desde 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)
	})
}
```

El evento incluye la siguiente información:

* `emoteUrn`: Nombre del emote realizado (p. ej.: *wave*, *clap*, *kiss*)
* `loop`: Si el emote está en bucle o se reproduce una vez
* `timestamp`: Cuando se disparó el emote.

También puedes detectar emotes de otros jugadores en la escena; simplemente pasa una referencia al otro jugador en lugar de `engine.PlayerEntity`.

## El jugador cambia el perfil

Usa la `onChange` función en el `AvatarEquippedData` componente para disparar un evento cada vez que el jugador cambia uno de sus wearables, o sus emotes listados en la rueda de acceso rápido. De manera similar, usa el `onChange` función en el `AvatarBase` para disparar un evento cada vez que el jugador cambia sus propiedades base de avatar, como color de cabello, color de piel, avatar shape o nombre.

```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)
	})
}
```

El evento en `AvatarEquippedData` incluye la siguiente información:

* `wearableUrns`: La lista de wearables que el jugador tiene actualmente equipados.
* `emoteUrns`: La lista de emotes que el jugador tiene actualmente equipados en la rueda de acceso rápido.

El evento en `AvatarBase` incluye la siguiente información:

* `name`: El nombre del jugador.
* `bodyShapeUrn`: Los ids correspondientes al tipo de cuerpo masculino o femenino.
* `skinColor`: Color de piel del jugador como un `Color4`
* `eyeColor`: Color de ojos del jugador como un `Color4`
* `hairColor`: Color de cabello del jugador como un `Color4`

También puedes detectar cambios en wearables o avatares de otros jugadores en la escena; simplemente pasa una referencia al otro jugador en lugar de `engine.PlayerEntity`.

{% hint style="info" %}
**💡 Tip**: Al probar en preview con el editor web legado, para evitar usar un avatar aleatorio, ejecuta la escena en el navegador conectado con tu wallet Metamask.
{% endhint %}

También puedes detectar cambios en los perfiles de otros jugadores en la escena; simplemente pasa una referencia al otro jugador en lugar de `engine.PlayerEntity`.

## El jugador bloquea o desbloquea el cursor

Los jugadores pueden alternar entre dos modos de cursor: *cursor bloqueado* modo para controlar la cámara o *cursor desbloqueado* modo para mover el cursor libremente sobre la UI.

Los jugadores desbloquean el cursor haciendo clic con el *Botón derecho del ratón* o presionando la *Esc* tecla, y bloquean el cursor de nuevo haciendo clic en cualquier parte de la pantalla.

Agrega un `PointerLock` componente al `engine.CameraEntity` entidad en tu escena, y usa el `onChange` función en el `PointerLock` componente para disparar un evento cada vez que el jugador cambia entre los dos 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 pista sobre el modo de cursor
		   }
	})
}
```

Puedes usar esta información para empujar sutilmente al jugador, como mostrar un popup de UI que diga que este juego se disfruta mejor con el cursor desbloqueado. O también puedes forzar el modo de cursor del jugador cambiando el `isPointerLocked` en el componente. El siguiente ejemplo siempre establece el modo de cursor en desbloqueado:

```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
		   }
	})
}
```
