# Methods

### 소개

UI, 유저 컨트롤, 사운드 등 ZEP에서 일어날 수 있는 전반적인 기능을 제공하는 함수입니다.

플레이어 개인 화면에 UI를 표시, 플레이어를 이동, 플레이어 개인에게 사운드 재생 등 편리한 기능을 제공합니다.

### UI

<table><thead><tr><th width="230">이름</th><th>설명</th></tr></thead><tbody><tr><td>showCenterLabel</td><td>플레이어에게 지정된 위치에 text를 3초간 표시하는 함수입니다.</td></tr><tr><td>showCustomLabel</td><td>플레이어에게 지정된 위치에 text를 3초간 표시하는 함수입니다.<br>text 부분에 <mark style="color:purple;background-color:yellow;">span</mark> 태그를 넣어 텍스트를 꾸밀 수 있습니다.</td></tr><tr><td>showWidget</td><td>플레이어에게 지정된 위치에 위젯을 불러오는 함수입니다.</td></tr><tr><td>showBuyAlert</td><td>플레이어에게 구매 위젯을 표시하고, 구매 후 동작하는 콜백함수를 작성할 수 있습니다.</td></tr><tr><td>hideBuyAlert</td><td>플레이어의 구매 위젯을 숨깁니다.</td></tr><tr><td>sendMessage</td><td>유저 개인에게 채팅 메시지를 보냅니다.</td></tr><tr><td>showPrompt</td><td>플레이어에게 입력창을 보여주고, 플레이어의 응답에 따라 동작하는 callback 함수를 작성할 수 있습니다.</td></tr><tr><td>showConfirm</td><td>플레이어에게 확인창을 보여주고, 플레이어가 OK를 눌렀을 때 동작하는 콜백함수를 작성할 수 있습니다.</td></tr><tr><td>showAlert</td><td>플레이어에게 경고창을 보여주고, 플레이어가 OK를 눌렀을 때 동작하는 callback 함수를 작성할 수 있습니다.</td></tr><tr><td>showImageModal</td><td>플레이어에게 입력한 이미지 주소에 해당하는 이미지를 표시합니다.</td></tr><tr><td>showNoteModal</td><td>플레이어에게 텍스트 창을 보여주는  함수입니다.</td></tr><tr><td>showWidgetResponsive</td><td>위젯의 상/하/좌/우 여백을 화면 크기에 대한 %비율로 정의하여 위젯을 표시합니다.</td></tr><tr><td>openWebLink</td><td>플레이어에게 웹 URL을 새 창이나 팝업 창으로 열어 보여줍니다.</td></tr><tr><td>showEmbed</td><td><p>URL을 임베드 형태로 표시합니다. </p><p>크기와  위치를 설정할  수 있습니다.</p></td></tr></tbody></table>

### Data Load

<table><thead><tr><th width="194">이름</th><th>설명</th></tr></thead><tbody><tr><td>isEmail</td><td>플레이어의 이메일을 비교하는 함수입니다.</td></tr><tr><td>getLocationName</td><td>플레이어가 서있는 지정 영역의 이름을 출력합니다.</td></tr></tbody></table>

### **User Control**

<table><thead><tr><th width="245">이름</th><th>설명</th></tr></thead><tbody><tr><td>spawnAt</td><td>플레이어의 캐릭터를 지정한 좌표로 이동시키는 함수입니다.</td></tr><tr><td>spawnAtLocation</td><td>플레이어의 캐릭터를 지정 영역으로 이동시키는 함수입니다.</td></tr><tr><td>spawnAtMap</td><td>플레이어를 다른 스페이스 또는 맵으로 이동시키는 함수입니다.</td></tr><tr><td>setCameraTarget</td><td>플레이어의 시점을 입한 좌표나  오브젝트로 이동시킵니다.</td></tr><tr><td>setEffectSprite</td><td>플레이어의 배경 또는 전경 이미지를 설정 할 수 있습니다.</td></tr><tr><td>playEffectSprite</td><td>플레이어에게 애니메이션 효과를 입력 횟수만큼 반복 재생하고 사라지는 효과를 적용합니다.</td></tr><tr><td>disappearObject</td><td>플레이어 개인 화면 상에서 key 값을 가지는 오브젝트를 사라지게하는 함수입니다.</td></tr></tbody></table>

### Sound

<table><thead><tr><th width="191">이름</th><th>설명</th></tr></thead><tbody><tr><td>playSound</td><td>플레이어에게 사운드 파일을 재생하는 함수입니다.</td></tr><tr><td>playSoundLink</td><td>플레이어에게 사운드 URL을 재생하는 함수입니다.</td></tr><tr><td>stopSound</td><td>플레이어에게 재생중인 사운드를 중지시키는 함수입니다.</td></tr></tbody></table>

### **공통**

<table><thead><tr><th width="197">이름</th><th>설명</th></tr></thead><tbody><tr><td>sendUpdated</td><td>Player 관련 필드 값이 변경되면 변경 값을 적용하는 함수입니다.</td></tr><tr><td>save</td><td>Player storage 값이 변경되면 변경 값을 적용하는 함수입니다.</td></tr></tbody></table>

## 📚 API 설명 및 예제

### 🎨 **UI Methods**

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

<pre class="language-jsx"><code class="lang-jsx">// 플레이어에게 지정된 위치에 해당 text를 3초간 표시
player.showCenterLabel(text: string, color: uint = 0xFFFFFF, bgColor: uint = 0x000000, offset: int = 0, time: int = 3000)

// 모든 플레이어에게 지정된 위치에 해당 text를 3초간 표시, 커스터마이징 가능
player.showCustomLabel(text: string, color: number = 0xFFFFFF, bgColor: number = 0x000000, offset: number = 0, width = 100, opacity = 0.6, time: int = 3000);

// 플레이어에게 지정된 align의 위치에 해당 html파일을 위젯으로 불러옴
player.showWidget(fileName: string, align: string, width: number, height: number): ScriptWidget

<strong>// 플레이어에게 구매 위젯을 표시하고, 구매 후 동작하는 콜백함수를 작성할 수 있습니다.
</strong>player.showBuyAlert(itemName: string, price: number, callback: function);

// 플레이어의 구매 위젯을 닫습니다.
player.hideBuyAlert();

// 플레이어 개인에게 채팅 메시지를 보냅니다.
player.sendMessage(message: string, color: number = 0xFFFFFF)

// 플레이어에게 입력창을 보여주고, 플레이어의 응답에 따라 동작하는 callback 함수를 작성할 수 있습니다.
player.showPrompt(text: string, function(inputText))

// 플레이어에게 확인창을 보여주고, 플레이어가 OK를 눌렀을 때 동작하는 콜백함수를 작성할 수 있습니다.
player.showConfirm(text: string, function(result))

// 플레이어에게 경고창을 보여주고, 플레이어가 OK를 눌렀을 때 동작하는 callback 함수를 작성할 수 있습니다.
player.showAlert(text: string, function())

// 위젯의 상/하/좌/우 여백을 화면 크기에 대한 % 비율로 정의하여 위젯을 표시합니다.
player.showWidgetResponsive(fileName:string, marginTop:number, marginRight:number, marginBottom:number, marginLeft:number)

//플레이어에게 웹 URL을 새 창이나 팝업 창으로 표시합니다.
player.openWebLink(url:string, popup:boolean);

// 지정된 align의 위치에 url 임베드창을 표시합니다.
player.showEmbed(url: string, align: string, width: number, height: number, hasBackdrop: boolean = true)
</code></pre>

### showCenterLabel

{% hint style="info" %}
&#x20;player.showCenterLabel(text: string, color: uint = 0xFFFFFF, bgColor: uint = 0x000000, offset: number = 0, time: number = 3000)
{% endhint %}

해당 플레이어에게 지정된 위치에 text를 3초간 표시하는 함수입니다.

**파라미터**

<table><thead><tr><th width="137.33333333333331">이름</th><th width="131">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>라벨에 출력할 텍스트</td></tr><tr><td>color</td><td>Uint</td><td>출력할 글씨의 색을 지정합니다. (HexCode)<br>값을 입력하지 않을 경우, 흰색(0xFFFFFF)으로 적용됩니다.<br>➡️<a href="https://www.google.com/search?q=COLOR+PICKER&#x26;sxsrf=ALiCzsbc_6XvOn9SiJdEBkLmfLurJ4tvOA%3A1658153265956&#x26;ei=MWnVYrX3Ocv4wAOXk6-wBg&#x26;ved=0ahUKEwj105mjzoL5AhVLPHAKHZfJC2YQ4dUDCA4&#x26;uact=5&#x26;oq=COLOR+PICKER&#x26;gs_lcp=Cgdnd3Mtd2l6EAMyBAgjECcyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQ6CwgAEIAEELEDEIMBOhEILhCABBCxAxCDARDHARDRAzoRCC4QgAQQsQMQgwEQxwEQrwE6CAgAEIAEELEDOhAIABCABBCHAhCxAxCDARAUOgoIABCABBCHAhAUSgQIQRgASgQIRhgAUABYhRVgvxZoAHABeACAAYwBiAHmC5IBBDAuMTKYAQCgAQHAAQE&#x26;sclient=gws-wiz"><mark style="color:purple;">구글 색상 선택 도구</mark></a></td></tr><tr><td>bgColor</td><td>Uint</td><td>메시지가 출력되는 라벨의 배경색을 지정합니다.<br>값을 입력하지 않을 경우, 검은색(0x000000)으로 적용됩니다.</td></tr><tr><td>offset</td><td>number</td><td>offset 값이 클수록 표시되는 위치가 화면 아래쪽 방향으로 가까워집니다.<br>값을 입력하지 않을 경우, 0으로 지정됩니다.</td></tr><tr><td>time</td><td>number</td><td>라벨 표시 시간 (ms), 기본 값 3000 ( 3초 )</td></tr></tbody></table>

**예제**

노란색 라벨을 2초간 출력해보기

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

```jsx
App.onJoinPlayer.Add(function(player){
	player.showCenterLabel(`${player.name}님 환영합니다.`, 0x000000, 0xFFFF00, 500, 2000); // 노란색 배경, 검정색 글씨로 표시하기
});
```

### showCustomLabel

{% hint style="info" %}
player.showCustomLabel(text: string, color: number = 0xFFFFFF, bgColor: number = 0x000000, offset: number = 0, width = 100, opacity = 0.6, time: number = 3000, option: object = null);
{% endhint %}

모든 플레이어에게 지정된 위치에 text를 3초간 표시하는 함수입니다.

text 부분에 <mark style="color:purple;">`span`</mark> 태그를 넣어 텍스트를 꾸밀 수 있습니다.

**파라미터**

<table><thead><tr><th width="121.33333333333331">이름</th><th width="112">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>라벨에 출력할 텍스트 ( span 태그 허용 )</td></tr><tr><td>color</td><td>Uint</td><td>출력할 글씨의 색 (HexCode)<br>값을 입력하지 않을 경우, 흰색(0xFFFFFF)으로 적용됩니다.<br>➡️<a href="https://www.google.com/search?q=COLOR+PICKER&#x26;sxsrf=ALiCzsbc_6XvOn9SiJdEBkLmfLurJ4tvOA%3A1658153265956&#x26;ei=MWnVYrX3Ocv4wAOXk6-wBg&#x26;ved=0ahUKEwj105mjzoL5AhVLPHAKHZfJC2YQ4dUDCA4&#x26;uact=5&#x26;oq=COLOR+PICKER&#x26;gs_lcp=Cgdnd3Mtd2l6EAMyBAgjECcyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQ6CwgAEIAEELEDEIMBOhEILhCABBCxAxCDARDHARDRAzoRCC4QgAQQsQMQgwEQxwEQrwE6CAgAEIAEELEDOhAIABCABBCHAhCxAxCDARAUOgoIABCABBCHAhAUSgQIQRgASgQIRhgAUABYhRVgvxZoAHABeACAAYwBiAHmC5IBBDAuMTKYAQCgAQHAAQE&#x26;sclient=gws-wiz"><mark style="color:purple;">구글 색상 선택 도구</mark></a></td></tr><tr><td>bgColor</td><td>Uint</td><td>메시지가 출력되는 라벨의 배경색<br>값을 입력하지 않을 경우, 검은색(0x000000)으로 적용됩니다.</td></tr><tr><td>offset</td><td>number</td><td>offset 값이 클수록 표시되는 위치가 화면 아래쪽 방향으로 가까워집니다.<br>값을 입력하지 않을 경우, 0으로 지정됩니다.</td></tr><tr><td>width</td><td>number</td><td>라벨의 너비를 n%로 설정하는 값 입니다. (기본 값 100)</td></tr><tr><td>opacity</td><td>number</td><td>라벨의 배경 투명도를 설정하는 값 입니다. (기본 값 0.6, 범위 0 ~ 1)</td></tr><tr><td>time</td><td>number</td><td>라벨 표시 시간 (ms), 기본 값 3000 ( 3초 )</td></tr></tbody></table>

**옵션**

<table><thead><tr><th width="159.33333333333331">이름</th><th width="112">타입</th><th>설명</th></tr></thead><tbody><tr><td>key</td><td>String</td><td>라벨에 키 값을 할당하여, 서로 다른 키 값을 가진 라벨은 동시에 표시할 수 있습니다.</td></tr><tr><td>borderRadius</td><td>String</td><td>라벨의 모서리에 둥글기를 설정할 수 있습니다.<br>ex) borderRadius: "8px"</td></tr><tr><td>fontOpacity</td><td>boolean</td><td>false로 설정시 폰트에 투명도가 적용되지 않습니다.</td></tr><tr><td>padding</td><td>String</td><td>라벨 내부에 padding 값을 지정 할 수 있습니다.<br>ex) padding: "8px"</td></tr></tbody></table>

**예제**

[**커스텀 라벨 예제 코드 페이지**](/creator/tutor/custom-label.md)**를 참고해주세요**

####

### showWidget

{% hint style="info" %}
player.showWidget(fileName: string, align: string, width: number, height: number): ScriptWidget
{% endhint %}

해당 플레이어에게 지정된 align의 위치에 해당 html파일을 위젯으로 불러오는 함수입니다.

**파라미터**

<table><thead><tr><th width="144.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>fileName</td><td>String</td><td>불러올 파일의 이름</td></tr><tr><td>align</td><td>String</td><td>위젯을 표시할 위치<br>’popup’, ‘sidebar’, ‘top’, ‘topleft’, ‘topright’, ‘middle’, ‘middleleft’, ‘middleright’, ‘bottom’, ‘bottomleft’, ‘bottomright’</td></tr><tr><td>width<br>height</td><td>number</td><td>위젯을 표시할 영역의 가로, 세로 크기(px)</td></tr></tbody></table>

**예제**

초성퀴즈 위젯 따라해보기

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

<div align="left"><figure><img src="/files/Eeigckjulla6Tsnz4z8s" alt=""><figcaption></figcaption></figure></div>

```jsx
let _widget = null;
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
	_widget = player.showWidget("widget.html", "top", 200, 300); // 화면 상단, 200x300 영역에 위젯을 보여줌
	_widget.sendMessage({
		timer: 15,
		answer: "ㅅㅍㅋ",
	});
});
```

### showBuyAlert

{% hint style="info" %}
player.showBuyAlert(itemName: string, price: number, callback: function, payToSpaceOwner: Boolean, option: object)
{% endhint %}

플레이어에게 구매 위젯을 표시하고, 구매 후 동작하는 콜백함수를 작성할 수 있습니다.

> 소모된 ZEM은 앱 제작자에게 돌아가며, [내 후원 내역 페이지](https://zep.us/manage/donations)에서 내역을 확인 할 수 있습니다.
>
> ZEM 정산 관련 내용은 [정산가이드 페이지](https://teamzep.notion.site/Settlement-Guide-29794e65dfaa42bc851a15ce2e4bad11)에서 확인하실 수 있습니다.

**파라미터**

<table><thead><tr><th width="194.33333333333331">이름</th><th width="115">타입</th><th>설명</th></tr></thead><tbody><tr><td>itemName</td><td>String</td><td>구매창에 표시할 아이템의 이름</td></tr><tr><td>price</td><td>number</td><td>아이템의 가격 (화폐단위: ZEM)</td></tr><tr><td>callback</td><td>function</td><td><p>구매 성공시 동작할 콜백함수</p><p>구매 성공 여부(<strong><code>success</code></strong>)와 구매정보(<strong><code>buyAlertResult</code></strong>) 데이터를 전달 받으며, buyAlertResult는 환불 기능에 사용됩니다.</p></td></tr><tr><td>payToSpaceOwner</td><td>Boolean</td><td><p>기본 값은 false로 설정되며<br>false인 경우 앱 소유자에게 수익이 전달되고,</p><p>true인 경우 맵 소유자에게 수익이 전달됩니다.</p></td></tr><tr><td>option</td><td>Object</td><td><p>다음 옵션들을 설정 할 수 있습니다.<br><strong><code>message</code></strong> : 구매창에 표시할 텍스트를 설정 할 수 있습니다.</p><p><strong><code>timer</code></strong> : 구매창을 표시할 시간(ms)을 설정할 수 있습니다.</p></td></tr></tbody></table>

**예제**&#x20;

구매정보 저장 및 환불 기능 예제

```jsx
const itemName = "ITEM";

// Q를 누르면 동작하는 함수 - 아이템을 구매하고 player.storage에 구매정보 저장하기
App.addOnKeyDown(81, function (player) {
	let pStorage = JSON.parse(player.storage);
	if (!player.tag) {
		player.tag = {};
	}
	if (pStorage == null) {
		pStorage = {};
	}
	//이미 아이템을 구매했다면 메시지 출력
	if (pStorage[itemName]) {
		player.showCenterLabel(`${itemName}을 이미 구매했습니다.`);
	} else {
		player.showBuyAlert(itemName, 0, function (success, buyAlertResult) {
			if (success) {
				App.sayToAll(`[정보] ${player.name}님이 ${itemName}을 구매했습니다!`);
				pStorage[itemName] = true;
				player.tag.buyAlertResult = buyAlertResult
				player.storage = JSON.stringify(pStorage);
				player.save();
			}
		}, 
		false,// false 인 경우 앱 소유자에게 수익전달, true이면 스페이스 소유자에게 수익 전달
		{
			message: `${itemName} custom message`,//message에 itemName에 해당하는 text가 있을 경우 강조되어 표시됨
			timer: 10000 // 10초 - 구매창 표시시간(ms)
		}
		);
	}
});

// W를 누르면 동작하는 함수 - 환불 기능
App.addOnKeyDown(87, function (player) {
	let pStorage = JSON.parse(player.storage);
	if( pStorage && player.tag.buyAlertResult )
	{	
		if( player.tag.buyAlertResult.Refund() )
		{
			App.sayToAll("===== refund success!");
			pStorage[itemName] = false;
		}
		else {
			App.sayToAll("===== refund failed");
		}
		player.tag.buyAlertResult = null;
		player.storage = JSON.stringify(pStorage);
		player.save();
	}
})
```

<div align="left"><figure><img src="/files/TgDnN90Zs3RiVLpp1pgj" alt=""><figcaption><p>구매위젯 예시</p></figcaption></figure> <figure><img src="/files/IRTQlXvH2f9W8Gi4tvAJ" alt=""><figcaption><p>timer와 message 옵션을 설정한 경우</p></figcaption></figure></div>

### hideBuyAlert

{% hint style="info" %}
player.hideBuyAlert()
{% endhint %}

플레이어의 구매 위젯을 닫습니다.

**파라미터**&#x20;

없음

### sendMessage

{% hint style="info" %}
&#x20;player.sendMessage(text: string, color: uint = 0xFFFFFF)
{% endhint %}

유저 개인에게 채팅 메시지를 보내는 함수입니다.

**파라미터**

<table><thead><tr><th width="137.33333333333331">이름</th><th width="281">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>라벨에 출력할 텍스트</td></tr><tr><td>color</td><td>Uint</td><td>출력할 글씨의 색을 지정합니다. (HexCode)<br>값을 입력하지 않을 경우, 흰색(0xFFFFFF)으로 적용됩니다.<br>➡️<a href="https://www.google.com/search?q=COLOR+PICKER&#x26;sxsrf=ALiCzsbc_6XvOn9SiJdEBkLmfLurJ4tvOA%3A1658153265956&#x26;ei=MWnVYrX3Ocv4wAOXk6-wBg&#x26;ved=0ahUKEwj105mjzoL5AhVLPHAKHZfJC2YQ4dUDCA4&#x26;uact=5&#x26;oq=COLOR+PICKER&#x26;gs_lcp=Cgdnd3Mtd2l6EAMyBAgjECcyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQ6CwgAEIAEELEDEIMBOhEILhCABBCxAxCDARDHARDRAzoRCC4QgAQQsQMQgwEQxwEQrwE6CAgAEIAEELEDOhAIABCABBCHAhCxAxCDARAUOgoIABCABBCHAhAUSgQIQRgASgQIRhgAUABYhRVgvxZoAHABeACAAYwBiAHmC5IBBDAuMTKYAQCgAQHAAQE&#x26;sclient=gws-wiz"><mark style="color:purple;">구글 색상 선택 도구</mark></a></td></tr></tbody></table>

**예제**

플레이어 개인에게만 보이는 환영메시지 출력하기.

<div align="left"><figure><img src="/files/Iy6l4xQq5WOW8HmivKUH" alt=""><figcaption></figcaption></figure></div>

```javascript

App.onJoinPlayer.Add(function(player){
    player.sendMessage(`${player.name}님 어서오세요!\nhttps://docs-kr.zep.us/ 링크 클릭시 가이드로 연결됩니다.`,0xffffff);
});

```

###

### showPrompt

{% hint style="info" %}
&#x20;player.showPrompt(title: string, function(inputText), option = {})
{% endhint %}

플레이어에게 입력창을 보여주고, 플레이어의 응답에 따라 동작하는 callback 함수를 작성할 수 있습니다.

**파라미터**

<table><thead><tr><th width="174.33333333333331">이름</th><th width="281">타입</th><th>설명</th></tr></thead><tbody><tr><td>title</td><td>String</td><td>입력창의 타이틀</td></tr><tr><td>inputText</td><td>String</td><td>플레이어가 입력한 텍스트</td></tr></tbody></table>

**옵션**

값을 입력하지 않아도 default 값이 적용됩니다.

<table><thead><tr><th width="174.33333333333331">이름</th><th width="174">타입</th><th>설명</th></tr></thead><tbody><tr><td>content</td><td>String</td><td>입력창 위에 출력할 텍스트 <strong>(Default: null)</strong></td></tr><tr><td>confirmVariant</td><td>'primary' | 'alert'</td><td>confirm 버튼의 색상 <strong>(Default: "primary")</strong><br>- 'primary': 푸른색,<br>- 'alert': 붉은색 </td></tr><tr><td>cancelText</td><td>String</td><td>cancel 버튼의 텍스트 <strong>(Default: "취소")</strong></td></tr><tr><td>confirmText</td><td>String</td><td>confirm 버튼의 텍스트 <strong>(Default: "확인")</strong></td></tr><tr><td>placeholder</td><td>String</td><td>input placeholder 텍스트 <strong>(Default: null)</strong></td></tr><tr><td>textType</td><td>'text' | 'password'</td><td><p>입력 타입 <strong>(Default: "text")</strong></p><p>- 'text': 입력 값을 텍스트로 표시<br>- 'password': 입력 값을 *로 표시</p></td></tr></tbody></table>

**예제**

"1234"를 입력하는 경우 "Correct" 메시지 출력해보기

![붉은 버튼 적용](/files/TOEpvF9rrE9GwgR2rm2Z)![](/files/Ki1iUvlZLC6ALtuO1K01)

```javascript
// Q키를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.q, function (player) {
    player.showPrompt("Password", function (inputText) {
            if (inputText == "1234") {
                player.showCenterLabel("Correct");
            } else {
                player.showCenterLabel("Incorrect");
            }
        },
        {
            content: 'Description', // 설명
            confirmVariant: 'primary', // 확인 버튼 색상 'primary' | 'alert'
            cancelText: 'custom cancel', // 취소 버튼 텍스트
            confirmText: 'custom confirm',// 확인 버튼 텍스트
            placeholder: 'Custom Placeholder',// 입력칸의 placeholder
            textType: 'password' // 입력 텍스트의 표시 형식 'text' | 'password'
        }
    );
});
```

### showConfirm

{% hint style="info" %}
&#x20;player.showConfirm(text: string, function(result), option = {})
{% endhint %}

플레이어에게 확인창을 보여주고, 플레이어가 확인 버튼을 눌렀을 때 동작하는 callback 함수를 작성할 수 있습니다. cancel을 누를 경우에는 callback 함수가 동작하지 않습니다.

**파라미터**

<table><thead><tr><th width="174.33333333333331">이름</th><th width="281">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>확인창에 출력할 텍스트</td></tr><tr><td>result</td><td>Boolean</td><td>플레이어가 OK를 누르는 경우 true</td></tr></tbody></table>

**옵션**

값을 입력하지 않아도 default 값이 적용됩니다.

<table><thead><tr><th width="174.33333333333331">이름</th><th width="174">타입</th><th>설명</th></tr></thead><tbody><tr><td>content</td><td>String</td><td>content 영역에 출력할 텍스트 <strong>(Default: null)</strong></td></tr><tr><td>confirmVariant</td><td>'primary' | 'alert'</td><td>confirm 버튼의 색상 <strong>(Default: 'primary')</strong><br>- primary: 푸른색,<br>- alert: 붉은색</td></tr><tr><td>cancelText</td><td>String</td><td>cancel 버튼의 텍스트 <strong>(Default: "취소")</strong></td></tr><tr><td>confirmText</td><td>String</td><td>confirm 버튼의 텍스트 <strong>(Default: "확인")</strong></td></tr></tbody></table>

**예제**

확인 버튼을 누른 경우 채팅창에 텍스트 출력하기

![](/files/Yl88KTekt0x5oAMkuIoe)![](/files/ECQOvzebn8HyoKfxBEsB)

```javascript
// Q 키를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.q, function (player) {
    player.showConfirm("Confirm", function (result) {
            if (result) {
                App.sayToAll("ok");
            }
        },
        {
            content: 'Description', // 설명
            confirmVariant: 'alert', // 확인 버튼 색상 'primary' | 'alert';
            cancelText: 'custom cancel', // 취소 버튼 텍스트
            confirmText: 'custom confirm',// 확인 버튼 텍스트
        }
    );
});
```

### showAlert

{% hint style="info" %}
&#x20;player.showAlert(text: string, function(), option = {})
{% endhint %}

플레이어에게 경고창을 보여주고, 플레이어가 OK를 눌렀을 때 동작하는 callback 함수를 작성할 수 있습니다.

**파라미터**

<table><thead><tr><th width="174.33333333333331">이름</th><th width="281">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>경고창에 출력할 텍스트</td></tr></tbody></table>

**옵션**

값을 입력하지 않아도 default 값이 적용됩니다.

<table><thead><tr><th width="174.33333333333331">이름</th><th width="174">타입</th><th>설명</th></tr></thead><tbody><tr><td>content</td><td>String</td><td>content 영역에 출력할 텍스트 <strong>(Default: null)</strong></td></tr><tr><td>confirmText</td><td>String</td><td>confirm 버튼의 텍스트 <strong>(Default: "확인")</strong></td></tr></tbody></table>

**예제**

버튼을 누른 경우 채팅창에 텍스트 출력하기

![](/files/ueYrgBss3A32yLUcpMKZ)

```javascript
// Q 키를 누르면 동작하는 함수
App.addOnKeyDown(81, function (player) {
    player.showAlert("Alert", function () {
            App.sayToAll("ok");
        },
        {
            content: 'Description', // 설명
            confirmText: 'custom confirm',// 확인 버튼 텍스트
        }
    );
});
```

### showWidgetResponsive

{% hint style="info" %}

```
player.showWidgetResponsive(fileName:string, marginTop:number, marginRight:number, marginBottom:number, marginLeft:number)
```

{% endhint %}

위젯의 상/하/좌/우 여백을 화면 크기에 대한 %비율로 정의하여 위젯을 표시합니다.

화면의 크기가 여백을 포함한 위젯 영역보다 작아질 경우, 위젯의 크기가 비례하여 작아집니다.

**파라미터**

<table><thead><tr><th width="206.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>fileName</td><td>String</td><td>불러올 파일의 이름</td></tr><tr><td>margin top/left/right/bottom</td><td>String</td><td>상/하/좌/우 여백의 % 값</td></tr></tbody></table>

**예제**

화면 크기를 줄이는 경우 위젯의 크기 변화

{% file src="/files/76cG0Pc8s9ezBXYSShEr" %}

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

```javascript
App.onJoinPlayer.Add(function (player) {
	player.tag = {};
});

// Q 키를 누르면 동작하는 함수
App.addOnKeyDown(81, function (player) {
	player.tag.widget = player.showWidgetResponsive("result.html", 15, 15, 15, 15);
	player.tag.widget.onMessage.Add(function (player, data) {
		if (data.type == "close") {
			player.tag.widget.destroy();
			player.tag.widget = null;
		}
	});
});
```

### openWebLink

{% hint style="info" %}

```
player.openWebLink(url:string, popup:boolean=false)
```

{% endhint %}

플레이어에게 웹 URL을 새 창이나 팝업 창으로 표시합니다.

**파라미터**

<table><thead><tr><th width="206.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>url</td><td>String</td><td>연결할 웹 url 주소</td></tr><tr><td>popup</td><td>boolean</td><td>true 인 경우, url 창을 팝업 형태로 표시합니다.</td></tr></tbody></table>

**예제**

openWebLink 팝업으로 여는 경우

```javascript
// Q 키를 누르면 동작하는 함수
App.addOnKeyDown(81, function (player) {
	player.openWebLink("https://docs-kr.zep.us", true);
});
```

<figure><img src="/files/LgUYVp6DxUNuP9jKtAwe" alt=""><figcaption><p>팝업으로 url 창을 표시</p></figcaption></figure>

### showEmbed

{% hint style="info" %}
player.showEmbed(url: string, align: string, width: number, height: number, hasBackdrop: boolean = true)
{% endhint %}

해당 플레이어에게 지정된 align의 위치에 url 임베드  화면을 표시하는 함수입니다.

**파라미터**

<table><thead><tr><th width="153.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>url</td><td>String</td><td>웹 url 주소</td></tr><tr><td>align</td><td>String</td><td>임베드를 표시할 위치<br>‘sidebar’, ‘top’, ‘topleft’, ‘topright’, ‘middle’, ‘middleleft’, ‘middleright’, ‘bottom’, ‘bottomleft’, ‘bottomright’</td></tr><tr><td>width<br>height</td><td>number</td><td>임베드 영역의 가로, 세로 크기(px)</td></tr><tr><td>hasBackdrop</td><td>boolean</td><td>true일 경우 임베드의 바깥 배경에 그림자를 표시합니다.</td></tr></tbody></table>

**예제**

url 임베드창 표시하기

![](/files/ZUeJvLmdJ7Agw2YgxAHn)![](/files/YZaCo9ElGGHQjLNiomc4)

```javascript
// Q를 누르면 동작하는 함수
App.addOnKeyDown(81, function (player) {
	player.showEmbed("https://youtu.be/ztuTrpXJyks", "middle", 900, 600, true);
});
```

### showImageModal

{% hint style="info" %}
player.showImage(url: string)
{% endhint %}

플레이어에게 입력한 이미지 주소에 해당하는 이미지를 표시합니다.

**파라미터**

<table><thead><tr><th width="136.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>url</td><td>String</td><td>표시할이미지 url</td></tr></tbody></table>

**예제**

이미지 모달창 표시하기

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

```javascript
// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
    player.showImageModal("https://cdn-static.zep.us/static/images/thumbnail.png");
});
```

### showNoteModal

{% hint style="info" %}
player.showNoteModal(text: string)
{% endhint %}

플레이어에게 텍스트 창을 보여주는  함수입니다.

**파라미터**

<table><thead><tr><th width="136.33333333333331">이름</th><th width="104">타입</th><th>설명</th></tr></thead><tbody><tr><td>text</td><td>String</td><td>표시할 텍스트</td></tr></tbody></table>

**예제**

텍스트 창 표시하기

![](/files/OfQ2TJzT7yL3J4R6NGNp)

```javascript
// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
    player.showNoteModal("Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatibus autem nisi soluta commodi a eius distinctio facilis est ea ullam. Dolorum a quis, impedit nisi voluptates magni architecto odit amet.");
});
```

## 💻 Data Load Methods

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

```jsx
// 지정한 이메일과 플레이어의 이메일을 비교
player.isEmail(email: string): boolean

// 플레이어가 서있는 구역이름을 호출
player.getLocationName(): string
```

### isEmail

{% hint style="info" %}
player.isEmail(email: string): boolean
{% endhint %}

해당 플레이어의 이메일이 파라미터 값과 같다면 true, 아니면 false를 리턴합니다.

**파라미터**

<table><thead><tr><th width="125.33333333333331">이름</th><th width="132">타입</th><th>설명</th></tr></thead><tbody><tr><td>email</td><td>String</td><td>비교할 이메일 텍스트</td></tr></tbody></table>

**예제**

플레이어의 이메일이 지정한 텍스트와 같은지 비교해보기

```jsx
// q 키를 누르면 동작하는 함수
// App.addOnKeyDown
	let check = player.isEmail("supercat@supercat.co.kr");
	App.sayToAll(`이메일 일치 여부: ${check}`)
})
```

### getLocationName

{% hint style="info" %}
player.getLocationName : string
{% endhint %}

플레이어가 서있는 지정 영역의 이름을 출력합니다.

지정 영역은 **‘맵에디터 > 타일효과’** 에서 설정 할 수 있습니다.

**파라미터**

* 없음

**예제**

캐릭터가 서있는 타일의 영역이름 출력해보기

→ 지정 영역 설정이 안되있다면 공백으로 출력됩니다

```jsx
// q 키를 누르면 동작하는 함수
// App.addOnKeyDown
App.addOnKeyDown(81,function(player){
	App.sayToAll(`현재 서있는 구역: ${player.getLocationName()}`)
})
```

###

## 🙍‍♂️ **User Control**

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

```jsx
// 플레이어를 해당 좌표로 소환
player.spawnAt(tileX: int ,tileY: int, dir: int = 0)

// 플레이어를 해당 구역으로 소환
player.spawnAtLocation(name: string ,dir:int = 0)

// 플레이어를 해당 스페이스 해당 맵으로 이동시키기
player.spawnAtMap(spaceHashID string, mapHashID:string = null)
```

### spawnAt

{% hint style="info" %}
player.spawnAt(tileX: int ,tileY: int, dir: int = 0)
{% endhint %}

플레이어의 캐릭터를 tileX, tileY 좌표로 지정한 방향을 바라보게 이동시킵니다.

**파라미터**

<table><thead><tr><th width="134.33333333333331">이름</th><th width="152">타입</th><th>설명</th></tr></thead><tbody><tr><td>tileX<br>tileY</td><td>number</td><td>플레이어를 이동시킬 x, y 좌표 값</td></tr><tr><td>dir</td><td>number</td><td>- 캐릭터가 바라볼 방향<br>• 왼쪽 : 1      • 위쪽 : 2        • 오른쪽 : 3    • 아래쪽 : 4<br>• 왼쪽위 : 5  • 왼쪽아래 : 6 • 오른쪽위: 7  • 오른쪽아래: 8</td></tr></tbody></table>

**예제**

입장하는 플레이어를 지정한 좌표로 이동시키기

```jsx
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
	player.spawnAt(5, 5, 1); // 플레이어를 5,5 위치로 왼쪽 방향을 바라보게 이동시키기
});
```

### spawnAtLocation

{% hint style="info" %}
player.spawnAtLocation(name: string, dir:int = 0)
{% endhint %}

플레이어의 캐릭터를 name에 해당하는 지정 영역으로 지정한 방향을 바라보게 이동시킵니다.

**파라미터**

<table><thead><tr><th width="135.33333333333331">이름</th><th width="132">타입</th><th>설명</th></tr></thead><tbody><tr><td>name</td><td>String</td><td>플레이어를 이동시킬 지정 영역의 이름</td></tr><tr><td>dir</td><td>number</td><td>- 캐릭터가 바라볼 방향<br>• 왼쪽 : 1      • 위쪽 : 2         • 오른쪽 : 3    • 아래쪽 : 4<br>• 왼쪽위 : 5  • 왼쪽아래 : 6  • 오른쪽위: 7  • 오른쪽아래: 8</td></tr></tbody></table>

**예제**

입장하는 플레이어를 지정 영역으로 이동시키기

:warning: 같은 이름의 지정 영역이 여러 곳 있다면 해당 영역들 중 한 곳으로 랜덤 이동합니다.

```jsx
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
// 플레이어를 "test"라는 이름의 지정영역으로 왼쪽 방향을 바라보게 소환하기
	player.spawnAtLocation("test", 1); 
});
```

### spawnAtMap

{% hint style="info" %}
player.spawnAtMap(spaceHashID string, mapHashID:string)
{% endhint %}

플레이어를 해당 스페이스 해당 맵으로 이동시킵니다.

**파라미터**

| 이름          | 타입     | 설명                         |
| ----------- | ------ | -------------------------- |
| spaceHashID | String | 이동할 스페이스의 spaceHashID      |
| mapHashID   | String | <p>이동할 맵의<br>mapHashID</p> |

**예제**

입장하는 플레이어를 ZEP 튜토리얼 맵으로 이동시키기 ([ <mark style="color:purple;">스페이스와 맵 이해하기</mark>](/creator/reference/undefined.md) )

```jsx
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
	// 플레이어를 ZEP 튜토리얼 맵으로 이동시키기
	player.spawnAtMap("65jeBA", "2YvXMJ");
});
```

### setCameraTarget

{% hint style="info" %}
**\[1]** player.setCameraTarget( tileX: Number, tileY: Number, time: Number )

**\[2]** player.setCameraTarget( key: String, time: Number )
{% endhint %}

**\[1]** 플레이어의 시점을 지정된 좌표로 중심 이동시킵니다.

**\[2]** 플레이어의 시점을 특정 오브젝트로 중심 이동시킵니다.

**파라미터**

| 이름    | 타입     | 설명                          |
| ----- | ------ | --------------------------- |
| tileX | Number | x좌표                         |
| tileY | Number | y좌표                         |
| key   | String | 오브젝트의 키 값                   |
| time  | Number | 시점이 목표 지점까지 이동하는데 걸리는 시간(초) |

**예제**

**\[1]** 플레이어가 보고 있는 화면의 중심을 입력한 좌표로 이동 및  초기화 시키기

```jsx
// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
    player.setCameraTarget(0, 0, 2); // 플레이어의 시점을 [0,0] 좌표로 2초동안 이동시킵니다.
    player.sendUpdated(); 
});

// W를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.W, function (player) {
    player.setCameraTarget("");
    player.sendUpdated();
});
```

**\[2]** 플레이어의 시점을  오브젝트로 이동 및 초기화 시키기

{% file src="/files/uhsb0mVdJOXD9HmcUcYE" %}
예제 파일
{% endfile %}

```jsx

let sprite = App.loadSpritesheet('blueman.png', 48, 64, {
    left: [5, 6, 7, 8, 9], // 좌방향 이동 이미지
    up: [15, 16, 17, 18, 19],
    down: [0, 1, 2, 3, 4],
    right: [10, 11, 12, 13, 14],
    dance: [20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],
    down_jump: [38],
    left_jump: [39],
    right_jump: [40],
    up_jump: [41],
},5);

App.onJoinPlayer.Add(function (player) {
    App.runLater(function () {
        Map.putObjectWithKey(player.tileX, player.tileY, sprite, {
            overlap: true,
            movespeed: 50,
            key: "TestBlueMan",
            useDirAnim: true
        });
        Map.moveObjectWithKey("TestBlueMan", Map.width - 1, player.tileY, false);
    }, 2);
});

// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
    player.setCameraTarget("TestBlueMan",1);
    player.sendUpdated();
});

// W를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.W, function (player) {
    player.setCameraTarget("");
    player.sendUpdated();
});
```

### setEffectSprite

{% hint style="info" %}
player.setEffectSprite(resource: ScriptDynamicResource, offsetX: Number, offsetY: Number, type: Number)
{% endhint %}

플레이어의 배경 또는 전경 이미지를 설정 할 수 있습니다.

**파라미터**

| 이름       | 타입                    | 설명                                                                 |
| -------- | --------------------- | ------------------------------------------------------------------ |
| resource | ScriptDynamicResource | 스크립트에 로드한 이미지 객체                                                   |
| offsetX  | Number                | px 단위로 x 축 방향의 오프셋을 설정할 수 있는 속성                                    |
| offsetY  | Number                | px 단위로 y 축 방향의 오프셋을 설정할 수 있는 속성                                    |
| type     | `0` \| `1`            | <p>설정타입<br>- <code>0</code>: 배경 설정<br>- <code>1</code> : 전경 설정</p> |

**사용 가능한 이펙트 애니메이션 키 값**

캐릭터의 움직임에 맞춰 애니메이션을 재생할 수 있도록 설정이 가능합니다. ([<mark style="color:purple;">**참고 문서**</mark>](/creator/reference/spritesheet.md))

{% hint style="warning" %}
캐릭터의 움직임에 대응하는 애니메이션이 정의되어 있지 않은 경우 애니메이션이 재생되지 않습니다.
{% endhint %}

```
down_idle // 정면에서 대기 상태
down // 정면에서 이동 중
left_idle // 왼쪽 방향에서 대기 상태
left // 왼쪽 방향으로 이동 중
right_idle // 오른쪽 방향에서 대기 상태
right // 오른쪽 방향으로 이동 중
up_idle // 위쪽 방향에서 대기 상태
up // 위쪽  방향으로 이동 중
dance // 춤추는 모션
down_jump, // 정면에서 점프하는 모션
left_jump, // 왼쪽 방향으로 점프하는 모션
right_jump, // 오른쪽 방향으로 점프하는 모션
up_jump, // 위쪽 방향으로 점프하는 모션
down_sit, // 정면 방향으로 앉아있는 모션
left_sit, // 왼쪽 방향에서 앉아있는 모션
right_sit, // 오른쪽 방향에서 앉아있는 모션
up_sit // 후면에서 앉아있는 모션
down_attack // 정면 방향 공격 모션
left_attack // 왼쪽 방향 공격 모션
right_attack // 오른쪽 방향 공격 모션
up_attack // 위쪽 방향 공격 모션
```

**예제**

플레이어 배경이미지 설정해보기

![](/files/EjRTroCKtrNsCMh7erp7)

{% file src="/files/JE9Hlbj9xQ5FIaZIHCvy" %}
예제 코드
{% endfile %}

```jsx
let effect = App.loadSpritesheet(
	"effect_sprite.png",
	32,
	32,
	{
		down_idle: [0, 1, 2, 3],
		down_attack: [0, 1, 2, 3],
		down: [0, 1, 2, 3],

		left_idle: [4, 5, 6, 7],
		left_attack: [4, 5, 6, 7],
		left: [4, 5, 6, 7],

		right_idle: [8, 9, 10, 11],
		right_attack: [8, 9, 10, 11],
		right: [8, 9, 10, 11],

		up_idle: [0, 1, 2, 3],
		up_attack: [0, 1, 2, 3],
		up: [0, 1, 2, 3],

		dance: [0, 1, 2, 3],

		down_jump: [0],
		left_jump: [4],
		right_jump: [8],
		up_jump: [0],

		down_sit: [0, 1, 2, 3],
		left_sit: [4, 5, 6, 7],
		right_sit: [8, 9, 10, 11],
		up_sit: [0, 1, 2, 3],
	},
	5
);

// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
	player.setEffectSprite(effect, -32, -30, 0); // 배경 이미지 설정
	player.sendUpdated();
});

// W를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.W, function (player) {
	player.setEffectSprite(null); // 배경 이미지 삭제
	player.sendUpdated();
});
```

### playEffectSprite

{% hint style="info" %}
player.playEffectSprite(resource: ScriptDynamicResource, repeatNum, offsetX: Number, offsetY: Number)
{% endhint %}

플레이어에게 애니메이션 효과를 `repeatNum` 횟수만큼 반복 재생하고 사라지는 효과를 적용합니다.

**파라미터**

<table><thead><tr><th>이름</th><th width="219.33333333333331">타입</th><th>설명</th></tr></thead><tbody><tr><td>resource</td><td>ScriptDynamicResource</td><td>스크립트에 로드한 이미지 객체</td></tr><tr><td>repeatNum</td><td>Number</td><td>애니메이션 재생을 반복할 횟수</td></tr><tr><td>offsetX</td><td>Number</td><td>px 단위로 x 축 방향의 오프셋을 설정할 수 있는 속성</td></tr><tr><td>offsetY</td><td>Number</td><td>px 단위로 y 축 방향의 오프셋을 설정할 수 있는 속성</td></tr></tbody></table>

#### 예제

1회 재생 후 사라지는 이펙트 효과

<div align="left"><figure><img src="/files/NmiXreAn648NFUMpAWkI" alt=""><figcaption></figcaption></figure></div>

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

```typescript
// 단일 애니메이션으로 정의해 사용합니다.
let effect = App.loadSpritesheet("effect_sprite.png", 32, 32, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 5);

// Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.Q, function (player) {
	player.playEffectSprite(effect, 1, -32, -30);
});
```

### disappearObject

{% hint style="info" %}
player.disappearObject(key: String)
{% endhint %}

플레이어 개인 화면 상에서 key 값을 가지는 오브젝트를 사라지게하는 함수입니다.

**파라미터**

<table><thead><tr><th>이름</th><th width="219.33333333333331">타입</th><th>설명</th></tr></thead><tbody><tr><td>key</td><td>String</td><td>사라지게할 오브젝트의 key 값</td></tr></tbody></table>

#### 예제

오브젝트와 상호작용 시 개인에게 사라지게 하기

<div align="left"><figure><img src="/files/b4VuonTwufI9mzwW0hjQ" alt=""><figcaption></figcaption></figure></div>

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

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

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

App.onTriggerObject.Add(function (player, layerID, x, y, key) {
	if(key){
	    player.disappearObject(key);
	}
});

```

### putIndividualObject

{% hint style="info" %}
player.putObjectWithKey(x: number, y: number, dynamicResource: ScriptDynamicResource, option: JsValue)
{% endhint %}

지정한 좌표에 플레이어에게만  보이는 오브젝트를 설치하는 함수입니다. ( 기준 좌표: Left Top )

`dynamicResource` 파라미터에 `null` 입력시 해당 좌표의 오브젝트를 삭제할 수 있습니다.

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

**파라미터**

<table><thead><tr><th width="183.33333333333331">이름</th><th width="214">타입</th><th>설명</th></tr></thead><tbody><tr><td>x, y</td><td>Number</td><td>오브젝트를 놓을 x, y 좌표</td></tr><tr><td>dynamicResource</td><td>ScriptDynamicResource</td><td>App.loadSpritesheet 함수로 로드한 이미지</td></tr></tbody></table>

**옵션 (option)**

값을 입력하지 않아도 Default 값이 적용됩니다

<table><thead><tr><th width="183.33333333333331">이름</th><th width="154">타입</th><th>설명</th></tr></thead><tbody><tr><td>key</td><td>String</td><td>오브젝트의 키 값<br><strong>(Default: null)</strong></td></tr><tr><td>moveSpeed</td><td>Number</td><td><p>오브젝트의 이동속도</p><p><strong>(Default: 80)</strong></p></td></tr><tr><td>useDirAnim</td><td>Boolean</td><td>방향을 인지해서 애니메이션을 재생하는 옵션<br><strong>(Default: false)</strong></td></tr><tr><td>impassable</td><td>Boolean</td><td>오브젝트 통과불가 옵션<br><strong>(Default: false)</strong></td></tr><tr><td>offsetX</td><td>Number</td><td>오브젝트 이미지의 배치 기준점의 X좌표<br><strong>(Default: 0)</strong></td></tr><tr><td>offsetY</td><td>Number</td><td>오브젝트 이미지의 배치 기준점의 Y좌표<br><strong>(Default: 0)</strong></td></tr><tr><td>npcProperty</td><td>Object</td><td>npcProperty 관련 내용은 <a href="/pages/jE090TJPep3C8JASB2tW"><strong>문서</strong></a>를 참고해주세요.<br><strong>(Default: null)</strong></td></tr><tr><td>topObject</td><td>Boolean</td><td>true 로 설정하면 오브젝트가 상단오브젝트로  설치됩니다.<br><strong>(Default: false)</strong></td></tr></tbody></table>

**예제**

키 값을 가진 블루맨 오브젝트 생성해보기

<div align="left"><figure><img src="/files/hw0SWbCUPhKQRlzloJKY" alt=""><figcaption></figcaption></figure></div>

```bash
let blueman = App.loadSpritesheet("blueman.png");
// q 키를 누르면 동작하는 함수
App.addOnKeyDown(81, function (player) {
	player.putIndividualObject(18, 6, blueman, {
		type:21, // zep-script 상호작용 오브젝트
		overlap: true, // 충돌 이벤트 감지
		movespeed: 100, // 이동속도, 기본값: 80
		key: "TestBlueMan", // 키 값
		impassalbe:true, // 통과 불가 오브젝트 설정
		useDirAnim: true, // 방향을 인지해서 애니메이션을 재생하는 옵션
        	offsetX: -8, // 오브젝트 이미지의 배치 기준점의 X좌표를 조정
              	offsetY: -32,// 오브젝트 이미지의 배치 기준점의 Y좌표를 조정
	});
});

// w 키를 누르면 동작하는 함수
App.addOnKeyDown(87, function (player) {
	// 오브젝트 삭제
	player.putIndividualObject(18, 6, null, {
		key: "TestBlueMan", // 키 값
	});
});
```

## 🔉 Sound Methods

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

```jsx
// 플레이어에게 사운드를 재생
player.playSound(fileName: string, loop: boolean = false)

// 플레이어에게 링크에 해당하는 사운드를 재생
player.playSoundLink(link: string, loop: boolean = false)
```

### playSound

{% hint style="info" %}
player.playSound(fileName: string, loop: boolean = false, overlap: boolean = false, key: string = "ambient", volume: number = 1)
{% endhint %}

해당 플레이어에게 사운드를 재생하는 함수입니다.

**파라미터**

<table><thead><tr><th width="137.33333333333331">이름</th><th width="131">타입</th><th>설명</th></tr></thead><tbody><tr><td>fileName</td><td>String</td><td>불러올 파일의 이름</td></tr><tr><td>loop</td><td>boolean</td><td>true: 반복 재생<br>false: 1회 재생</td></tr><tr><td>overlap</td><td>boolean</td><td>사운드 오버랩(겹침) 재생 가능 여부</td></tr><tr><td>key</td><td>string</td><td>재생하는 사운드를 식별하는 데 사용되는 문자열입니다. <br>기본 값은 "ambient"로 설정되어 있습니다.</td></tr><tr><td>volume</td><td>number</td><td>사운드의 볼륨을 조절하는 데 사용되는 숫자입니다. <br>값의 범위는 0에서 1까지이며, 0은 소리가 없음을 나타내고, 1은 최대 볼륨을 나타냅니다.</td></tr></tbody></table>

**예제**

입장음 설정해보기(파일)

{% file src="/files/9aGFrafFuDp3Grwpqop1" %}

```jsx
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
	player.playSound("join.mp3",false, true, "join", 0.5);
});
```

### playSoundLink

{% hint style="info" %}
player.playSoundLink(link: string, loop: boolean = false, overlap: boolean = false, key: string = "ambient", volume: number = 1)
{% endhint %}

모든 플레이어에게 사운드를 재생하는 함수입니다.

> 💡 **올바른 링크를 입력했는데 재생이 되지 않는 경우**
>
> CORS 정책을 위반한 경우일 가능성이 높습니다. CORS 정책을 맞출 수 없는 경우에는 \
> playSoundLink 대신 음악 파일을 업로드 하여 playSound 함수를 사용하는 것을 권장 드립니다.

**파라미터**

<table><thead><tr><th width="147.33333333333331">이름</th><th width="133">타입</th><th>설명</th></tr></thead><tbody><tr><td>link</td><td>String</td><td>사운드 url</td></tr><tr><td>loop</td><td>boolean</td><td>true: 반복 재생<br>false: 1회 재생</td></tr><tr><td>overlap</td><td>boolean</td><td>사운드 오버랩(겹침) 재생 가능 여부</td></tr><tr><td>key</td><td>string</td><td>재생하는 사운드를 식별하는 데 사용되는 문자열입니다. <br>기본 값은 "ambient"로 설정되어 있습니다.</td></tr><tr><td>volume</td><td>number</td><td>사운드의 볼륨을 조절하는 데 사용되는 숫자입니다. <br>값의 범위는 0에서 1까지이며, 0은 소리가 없음을 나타내고, 1은 최대 볼륨을 나타냅니다.</td></tr></tbody></table>

**예제**

입장음 설정해보기(사운드 url)

```jsx
// 플레이어가 입장할 때 실행
App.onJoinPlayer.Add(function (player) {
	player.playSoundLink("https://cdn-static-stage.zep.us/static/assets/sounds/new_donation_1.wav", false, true, "join", 0.5);
});
```

### stopSound

{% hint style="info" %}
player.stopSound(key: string)
{% endhint %}

key에 해당하는 사운드의 재생을 중지하는 함수입니다.

<table><thead><tr><th width="147.33333333333331">이름</th><th width="133">타입</th><th>설명</th></tr></thead><tbody><tr><td>key</td><td>string</td><td>중지하려는 사운드의 키 값</td></tr></tbody></table>

#### 예제

재생  중인 사운드 중지 시키기\
아래 예제 코드 실행 후 Q, W 키를 연속으로 입력해보세요.

```
//Q를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.q,(player)=>{
	player.playSoundLink("https://cdn-static-stage.zep.us/static/assets/sounds/new_donation_1.wav", false, true, "donation", 0.5);
});

//W를 누르면 동작하는 함수
App.addOnKeyDown(KeyCodeType.w, (player)=>{
    player.stopSound("donation")
});
```

## 💠 **공통 Methods**

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

```jsx
// 플레이어 필드값을 수정한 후 업데이트
player.sendUpdated()

// 플레이어 스토리지값을 저장
player.save()
```

### sendUpdated

{% hint style="info" %}
&#x20;player.sendUpdated()
{% endhint %}

App, Player 관련 필드 값이 변경되면 변경 값을 적용하는 함수입니다.

**파라미터**

* 없음

### save

{% hint style="info" %}
player.save()
{% endhint %}

App, Player storage 값이 변경되면 변경 값을 적용하는 함수입니다.

**파라미터**

* 없음

***


---

# 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/scriptplayer/methods.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.
