# Event Listeners

**소개**

플레이어가 지정된 채팅을 입력하거나, 특정한 오브젝트를 공격할 와 같이 ZEP 스페이스에서 발생하는 **특정 상황에 반응하여 동작하는 함수**들 입니다.

{% hint style="danger" %}
**EventListener**가 비정상적으로 많이 추가되는 경우 앱이 종료될 수 있습니다.

onUpdate문 또는 반복적으로 실행되는 문에서 EventListener를 등록하는 것을 지양해주세요.
{% endhint %}

<table><thead><tr><th width="218">이름</th><th>설명</th></tr></thead><tbody><tr><td>onSay</td><td>플레이어가 채팅을 입력할 때 동작하는 함수입니다.</td></tr><tr><td>onPlayerTouched</td><td>캐릭터들끼리 충돌할 때 동작하는 함수입니다.</td></tr><tr><td>onObjectTouched</td><td>캐릭터가 오브젝트와 충돌할 때 동작하는 함수입니다.</td></tr><tr><td>onAppObjectTouched</td><td>플레이어가 키 값을 가진 오브젝트와 충돌할 때 동작하는 함수입니다.</td></tr><tr><td>onUnitAttacked</td><td>공격 키(Z)로 다른 캐릭터를 공격할 때 동작하는 함수입니다.</td></tr><tr><td>onObjectAttacked</td><td>공격 키(Z)로 오브젝트를 공격할 때 동작하는 함수입니다.</td></tr><tr><td>onSidebarTouched</td><td>플레이어가 사이드바 앱을 클릭(터치)할 때 실행되는 함수입니다.</td></tr><tr><td>onTriggerObject</td><td>오브젝트와 F 상호작용 시 동작하는 함수입니다.</td></tr><tr><td>onAppObjectAttacked</td><td>플레이어가 키 값을 가진 오브젝트를 공격(Z키) 할 때 동작하는 함수입니다.</td></tr></tbody></table>

## 📚 API 설명 및 예제

<mark style="background-color:yellow;">**Event Listener 함수 한 눈에 보기**</mark>

<pre class="language-jsx"><code class="lang-jsx">// 플레이어들이 채팅창에 입력하는 모든 채팅에 대해 호출 되는 이벤트
// !로 시작하는 텍스트는 채팅창에 나오지 않으나, onSay 함수에는 사용 가능
App.onSay.Add(function(player, text) {
});

// 플레이어가 다른 플레이어와 부딪혔을 때 호출 되는 이벤트
App.onPlayerTouched.Add(function(sender, target, x, y){
});
<strong>
</strong>// 플레이어가 오브젝트와 부딪혔을 때 호출 되는 이벤트
App.onObjectTouched.Add(function(sender, x, y, tileID, obj) {  
});

// 플레이어가 키 값을 가진 오브젝트와 부딪혔을 때 호출 되는 이벤트
App.onAppObjectTouched.Add(function(key, sender, x, y){});

// 플레이어가 다른 플레이어를 공격할 때 (Z키) 호출 되는 이벤트
App.onUnitAttacked.Add(function(sender, x, y, target) {
});

// 플레이어가 오브젝트를 공격(Z키)했을 때 호출 되는 이벤트
App.onObjectAttacked.Add(function(sender, x, y){
});

// 플레이어가 사이드바 앱을 클릭(터치)할 때 호출 되는 이벤트
App.onSidebarTouched.Add(function(player){
}); 

// 오브젝트와 F 상호작용 시 동작하는 함수
App.onTriggerObject.Add(function(player, layer, x, y){
});

// 플레이어가 키 값을 가진 오브젝트를 공격할 때 (Z키) 호출 되는 이벤트
App.onAppObjectAttacked.Add(function (sender, x, y, layer, key) {
});
</code></pre>

####

### onSay

{% hint style="info" %}
App.onSay.Add(function(player, text){});
{% endhint %}

플레이어가 채팅을 입력할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="114.33333333333331">이름</th><th width="97">타입</th><th>설명</th></tr></thead><tbody><tr><td>player</td><td>Player</td><td>player 파라미터는 채팅을 입력한 플레이어를 가르킴<br>player 파라미터의 이름은 임의로 변경 가능</td></tr><tr><td>text</td><td>String</td><td>text는 입력한 채팅 내용을 가르킴<br>text 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예제**

초성퀴즈 - 채팅으로 정답 맞추는 기능 만들어보기

```jsx
_answer = "ZEP" // 정답
// 플레이어가 채팅을 칠 때 실행
App.onSay.add(function(player, text) {
    if(_answer == text){
        App.showCenterLabel(player.name + '님 정답!\n정답은 ' + _answer);
    }
});
```

####

### onPlayerTouched

{% hint style="info" %}
App.onPlayerTouched.Add(function(sender, target, x, y){});
{% endhint %}

캐릭터들끼리 충돌할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="107.33333333333331">이름</th><th width="107">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 부딪힌 주체자를 가르킴</td></tr><tr><td>target</td><td>String</td><td>target은 부딪힘을 당한 플레이어를 가르킴</td></tr><tr><td>x, y</td><td>Number</td><td>x, y는 충돌한 x, y 좌표를 가르킴</td></tr><tr><td></td><td></td><td>sender, target, x, y 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예제**

캐릭터끼리 부딪힐 때 메시지 출력해보기

```jsx
// 플레이어끼리 부딪힐 때 실행
App.onPlayerTouched.Add(function (sender, target, x, y) {
	App.showCenterLabel(
		`${sender.name}님과 ${target.name}님이 좌표: (${x}, ${y}) 에서 부딪혔습니다.`
	);
});
```

####

### onObjectTouched

{% hint style="info" %}
App.onObjectTouched.Add(function(sender, x, y,  tileID, obj){});
{% endhint %}

캐릭터가 오브젝트와 충돌 또는 상호작용 할 때 한 번 실행됩니다.

**파라미터**

<table><thead><tr><th width="229.33333333333331">이름</th><th width="128">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 오브젝트와 부딪힌 플레이어를 가르킴</td></tr><tr><td>x, y</td><td>Number</td><td>오브젝트와충돌한 x, y 좌표를 가르킴</td></tr><tr><td>tileID</td><td>Number</td><td>오브젝트의 타일 ID 입니다.</td></tr><tr><td>obj</td><td>Object</td><td>오브젝트 객체</td></tr></tbody></table>

**예제**

⭐ <mark style="color:purple;">`overlap: true`</mark> 속성이 없는 오브젝트는 충돌해도 함수가 실행되지 않습니다.

{% file src="/files/xkq8ljeofl3LUxbcaDaS" %}

<pre class="language-jsx"><code class="lang-jsx"><strong>let testObject = App.loadSpritesheet("object.png");
</strong>// 사용 가능한 ObjectEffectType
const ObjectEffectType = {
    NONE = 0,
    SHOW_NOTE = 1,
    SHOW_IMAGE = 2,
    PASSWORD_DOOR = 3,
    LINK_WEBSITE = 4,
    EMBED_WEBSITE = 5,
    API_CALL = 6,
    REPLACE_IMAGE = 7,
    NFT_GIVEAWAY = 8,
    NFT_DOOR = 9,
    POST_MESSAGE = 10,
    SHOW_CHAT_BALLOON = 11,
    FT_DOOR = 12,
    POST_MESSAGE_TO_APP = 13,
    DONATION_DOOR = 14,
    IMPASSABLE = 15,
    STAMP = 16,
    TOKEN_DONATION_DOOR = 17,
    CHANGE_OBJECT = 18,
    ANIMATION = 19,
    NFT_DOOR_MOVE = 20,
    INTERACTION_WITH_ZEPSCRIPTS = 21,
    MULTIPLE_CHOICE = 22,
}

App.onStart.Add(function () {
	Map.putObject(5, 5, testObject, { overlap: true });
});

// 플레이어와 오브젝트가 부딪힐 때 실행
App.onObjectTouched.Add(function (sender, x, y, tileID, obj) {
	Map.putObject(x, y, null);
	App.showCenterLabel(
		`${sender.name}님이 좌표: (${x}, ${y}) 에서 오브젝트와 부딪혔습니다.(타입: ${obj.type})`
	);
});
</code></pre>

####

### onAppObjectTouched

{% hint style="info" %}
App.onAppObjectTouched.Add(function(sender, key, x, y){});
{% endhint %}

️ 캐릭터가 키 값을 가진 오브젝트와 충돌할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="133.33333333333331">이름</th><th width="127">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 오브젝트와 부딪힌 플레이어를 가르킴</td></tr><tr><td>key</td><td>String</td><td>오브젝트의 Key 값</td></tr><tr><td>x, y</td><td>Number</td><td>x, y는 충돌한 x, y 좌표를 가르킴</td></tr></tbody></table>

**예제**

라벨 출력 예제

⭐ <mark style="color:purple;">`overlap: true`</mark> 속성이 없는 오브젝트는 충돌해도 함수가 실행되지 않습니다.

{% file src="/files/kFUS8EILULIHiWMSqnSt" %}

```jsx
let blueman_dance = App.loadSpritesheet(
	"blueman.png",
	48,
	64,
	[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37],
	8
);

// Q를 누르면 동작 하는 함수
App.addOnKeyDown(81, function (player) {
	App.sayToAll("키 값을 가진 오브젝트 충돌 테스트");
	Map.putObjectWithKey(8, 5, blueman_dance, { overlap: true, key: "blueman" });
});

App.onAppObjectTouched.Add(function (player, key, x, y) {
	App.sayToAll(
		`${player.name}이 키 값이 ${key}인 오브젝트와 ${x},${y}에서 충돌!`
	);
});
```

####

### onUnitAttacked

{% hint style="info" %}
App.onUnitAttacked.Add(function(sender, x, y, target){});
{% endhint %}

플레이어가 공격 키(Z)로 다른 캐릭터를 공격할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="127.33333333333331">이름</th><th width="105">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 공격한 플레이어를 가르킴</td></tr><tr><td>x, y</td><td>Number</td><td>x, y는 공격한 플레이어의 x, y 좌표 값을 가르킴</td></tr><tr><td>target</td><td>Player</td><td>target은 공격 받은 플레이어를 가르킴</td></tr><tr><td></td><td></td><td>sender, x, y, target 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예제**

플레이어를 공격 할 때 메시지 출력해보기

```jsx
// Z 키로 플레이어를 공격할 때 실행
App.onUnitAttacked.Add(function (sender, x, y, target) {
	App.showCenterLabel(`${sender.name}님이 ${target.name}님을 공격했습니다.`);
	App.sayToAll(`(${x}, ${y})`);
});
```

####

### onObjectAttacked

{% hint style="info" %}
App.onObjectAttacked.Add(function(sender, x, y){});
{% endhint %}

플레이어가 공격 키(Z)로 오브젝트를 공격할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="123.33333333333331">이름</th><th width="120">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 공격한 플레이어를 가르킴</td></tr><tr><td>x, y</td><td>Number</td><td>x, y는 오브젝트의 x, y 좌표 값을 가르킴</td></tr><tr><td></td><td></td><td>sender, x, y 파라미터의 이름은 임의로 변경 가능</td></tr></tbody></table>

**예제**

오브젝트를 공격할 때 메시지 출력해보기

⭐ <mark style="color:purple;">`overlap: true`</mark> 속성이 없는 오브젝트는 공격해도 함수가 실행되지 않습니다.

{% file src="/files/uQ9d50cNL1KuyUbylNbS" %}

```jsx
let testObject = App.loadSpritesheet("object.png");

App.onStart.Add(function () {
	Map.putObject(5, 5, testObject, { overlap: true });
});
// Z 키로 오브젝트를 공격할 때 실행
App.onObjectAttacked.Add(function(sender, x, y){
	App.showCenterLabel(
		`${sender.name}님이 좌표: (${x}, ${y})에 위치 오브젝트를 공격했습니다.`
	);
})
```

####

### onSidebarTouched

{% hint style="info" %}
App.onSidebarTouched.Add(function(player){});
{% endhint %}

플레이어가 사이드바 앱을 클릭(터치) 할 때 동작합니다.

**파라미터**

<table><thead><tr><th width="139.33333333333331">이름</th><th width="125">타입</th><th>설명</th></tr></thead><tbody><tr><td>player</td><td>Player</td><td>사이드바 앱을 클릭한 player를 가르킴</td></tr></tbody></table>

**예제**

사이드바 앱 클릭 시 채팅창 메시지 출력하기.

```jsx
App.onSidebarTouched.Add(function (player) {
	App.sayToAll(`${player.name}님이 사이드바 앱을 클릭했습니다.`)
});
```

**관련 페이지**

[<mark style="color:purple;">사이드바 앱 예제</mark>](/creator/tutor/sample/sidebarapp.md)

### onTriggerObject

{% hint style="info" %}
App.onTriggerObject.Add(function(player, layerID, x, y, key){});
{% endhint %}

오브젝트와 F 상호작용 시 동작하는 함수를 작성할 수 있습니다.

맵에디터로 설치한 오브젝트 또는 스크립트에서  <mark style="color:purple;">**`type`**</mark>을  <mark style="color:purple;">**`INTERACTION_WITH_ZEPSCRIPTS`**</mark>**`(21)`**&#xB85C; 설치한 오브젝트와 상호작용 시 동작합니다.

**파라미터**

<table><thead><tr><th width="139.33333333333331">이름</th><th width="125">타입</th><th>설명</th></tr></thead><tbody><tr><td>player</td><td>Player</td><td>오브젝트와 상호작용한 player를 가르킴</td></tr><tr><td>layerID</td><td>Number</td><td>오브젝트가 설치된 레이어 ID<br>오브젝트인 경우 layerID = 3<br>상단 오브젝트인 경우 layerID = 5</td></tr><tr><td>x, y</td><td>Number</td><td>상호작용한 오브젝트의 x, y 좌표</td></tr><tr><td>key</td><td>String</td><td>상호작용한 오브젝트의 key 값</td></tr></tbody></table>

**예제**

오브젝트와 F 상호작용시 메시지 출력하기

<figure><img src="/files/QakSso0G1ozQSeLqsZBG" alt=""><figcaption></figcaption></figure>

{% file src="/files/WCZIkW2FIJOLiBBrJcPZ" %}

```javascript
let blueman = App.loadSpritesheet("blueman.png");

App.onJoinPlayer.Add(function (player) {
	Map.putObjectWithKey(player.tileX + 1, player.tileY, blueman, {
		type: ObjectEffectType.INTERACTION_WITH_ZEPSCRIPTS,
		impassable: true,
		key: "objectKey",
	});
});


App.onTriggerObject.Add(function (player, layerID, x, y, key) {
	App.sayToAll(`playerName: ${player.name} / layer: ${layerID} / coordinates:(${x}, ${y}) / key: ${key}`);
});
```

### onAppObjectAttacked

{% hint style="info" %}

```
App.onAppObjectAttacked.Add(function (sender, x, y, layer, key) {});
```

{% endhint %}

플레이어가 공격 키(Z)로 키 값을 가진 오브젝트를 공격할 때 동작합니다.

**관련 문서**: [오브젝트 npcProperty](/creator/reference/npcproperty.md)

**파라미터**

<table><thead><tr><th width="123.33333333333331">이름</th><th width="120">타입</th><th>설명</th></tr></thead><tbody><tr><td>sender</td><td>Player</td><td>sender는 공격한 플레이어를 가르킴</td></tr><tr><td>x, y</td><td>Number</td><td>x, y는 오브젝트의 x, y 좌표 값을 가르킴</td></tr><tr><td>layer</td><td>Number</td><td>오브젝트가 설치된 레이어</td></tr><tr><td>key</td><td>String</td><td>공격한 오브젝트의 키 값</td></tr></tbody></table>

**예제**

키 값을 가진 오브젝트를 공격할 때 메시지 출력해보기

![](/files/dFaA3nqaA6P2yqBfg0z1)

{% file src="/files/qqm7s6mhlMnHRXvHzt15" %}

⭐ <mark style="color:purple;">`collide: true`</mark> 속성이 없는 키 값 오브젝트는 공격해도 함수가 실행되지 않습니다.

```javascript
App.onAppObjectAttacked.Add(function (sender, x, y, layer, key) {
    App.showCenterLabel(
        `sender: ${sender.name} 
        coordinates: (${x}, ${y})
        layer: ${layer}
        key: ${key}`
    );
});
```

**관련 페이지**

[<mark style="color:purple;">사이드바 앱 예제</mark>](/creator/tutor/sample/sidebarapp.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-kr.zep.us/zep-script-api/zepscriptapi/scriptapp/event-listeners.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
