ZEP Guidebook (KR)
  • 👋Hello ZEP Script
  • ZEP Script 가이드
    • ZEP Script 개발 가이드
      • 쉬운 개발 가이드
      • Javascript 개발 가이드
      • Typescript 개발 가이드
      • ZEP Script 배포 가이드
    • ZEP Script 따라하기
      • 기초 예제 코드
        • ✉️메시지 출력해보기
        • ♻️ZEP APP lifecycle 이해하기
        • 👤캐릭터 이미지 바꾸기
        • 🖼️나만의 UI 만들기
        • 💢2초 스턴 효과 만들어보기
      • ZEP Script 예제 코드
        • ⏰타이머
        • ⏱️방탈출 타이머
        • 🤛사이드바 앱
        • 🧟‍♂️좀비 게임
        • 🎨페인트맨 게임
        • 🙆‍♀️초성 퀴즈
        • 💩똥피하기 게임
        • 🥊결투 게임
        • 🏃‍♂️달리기
      • Custom Label 예제 코드
        • Type-A
        • Type-B
        • Type-C
        • Type-D
        • Type-E
        • Type-F
        • Type-G
        • Type-H
        • Type-I
        • Type-J
      • 사이드 바 앱 예제 코드
        • 🔹Image List
        • 🔹Text List
        • 🔹Text Button List
        • 🔹Ranking List
        • 🔹Select List
    • ZEP Script FAQ
    • 부록
      • 🎡ZEP 스크립트 활용 사례
      • 🗺️스페이스와 맵 이해하기
      • ⌨️자바스크립트 키코드 표
      • 🎨스프라이트시트 이해하기
      • 🌀TileEffectType 상세 설명
      • 📌기준 좌표
      • 🛰️외부 API 통신하기
      • 🔰URL 쿼리스트링 활용하기
      • 🪧위젯에서 사용가능한 문법
      • 🔘모바일버튼 이미지 변경하기
      • ✳️ZEP 스크립트 상호작용 오브젝트 가이드
      • 📇오브젝트 npcProperty
  • ZEP SCRIPT API
    • 📘ZEP Script API
      • API Summary
      • ScriptApp
        • Lifecycle
        • Field
        • Storage
        • Event Listeners
        • Callbacks
        • Methods
      • ScriptMap
        • Field
        • Methods
      • ScriptPlayer
        • Field
        • Methods
      • ScriptWidget
        • Field
        • Event Listeners
        • Methods
      • UtilityClass
        • Time
Powered by GitBook
On this page

Was this helpful?

  1. ZEP Script 가이드
  2. ZEP Script 따라하기
  3. ZEP Script 예제 코드

달리기

Previous결투 게임NextCustom Label 예제 코드

Last updated 1 year ago

Was this helpful?

1) 파일

2) main.js

const STATE_INIT = 3000;
const STATE_READY = 3001;
const STATE_PLAYING = 3002;
const STATE_JUDGE = 3004;
const STATE_END = 3005;
const STATE_INTRO = 3006;

let _players = App.players; 
let _state = STATE_INIT; 
let _start = false; 
let _stateTimer = 0; 
let _countDown = 10; 
let _finishCountDown = false;
let _finishCount = 30;
let _finishTimer = 0; 
let _delayTimer = 0; 
let _playerBaseSpeed = 120; 
let _rank = 1; 
let _rankList = []; 

//모든 플레이어가 결승점을 통과한 경우 처리  
function finishCheck(){
	
	let allPlayer = 0; 
	let finishedPlayer = 0; 

	for(let p of _players){

		if(!p)
			continue; 

		if(p.tag.isNotPlayer)
			continue; 

		if(p.tag.isFinish)
			finishedPlayer++;
		
		allPlayer++; 
	}

	if(finishedPlayer == allPlayer)
		return true 
	
	return false; 
}

//달리기 맵 설정이 정상적으로 되어있는 지 확인하고, 아닌 경우 에러메세지를 리턴한다. 
function checkSetting(){

	let warningMsg = '';

	if (!Map.hasLocation("race_start_point")) {
		warningMsg = 'race_start_point';

	}
	if (!Map.hasLocation("race_end_point")) {
		warningMsg = 'race_end_point';

	}
	if (!Map.hasLocation("race_finish_point")) {
		warningMsg = 'race_finish_point';

	}
	
	return warningMsg; 
}

function startState(state){

	_state = state; 
  	_stateTimer = 0; 

  	switch (state) {
		
    	case STATE_INIT:
     		for(let p of _players){
				//달리기 앱을 실행한 유저를 확인한다.
				if(p.id == App.creatorID){
					if(p.isMobile)
					//유저의 환경이 모바일인 경우의 위젯 
						p.tag.widget = p.showWidget("setting.html", "bottom", 440, 340);
					else
					//유저의 환경이 pc인 경우의 위젯
						p.tag.widget = p.showWidget("setting.html", "middle", 440, 340);
					
					p.tag.widget.sendMessage({ 
						str_title         : 'Run',
						str_title_text1   : "A race to see who reaches the finish line the fastest",
						str_title_text2   : 'Click the Start Running button to start the game',
						str_title_start   : "Start",
						str_title_how     : "How to set up a map"
					});
					
					p.tag.widget.onMessage.Add(function (sender, msg) {
						//게임을 취소하는 경우, 나타난 위젯을 제거한다 
						if (msg.type == "cancle") {
							if(p.tag.widget_warning){
								p.tag.widget_warning.destroy();
								p.tag.widget_warning = null;
							}

							if(p.tag.widget){
								p.tag.widget.destroy();
								p.tag.widget = null;
							}
						
						} else {
							// 맵에 필요한 설정 체크							
							let warning = checkSetting();
		
							if(warning !== ''){
								if(p.tag.widget_warning){
									p.tag.widget_warning.destroy();
									p.tag.widget_warning = null;
								}
		
								if(p.isMobile)
									p.tag.widget_warning = App.showWidget("warning.html", "top", 440, 60);
								else 
									p.tag.widget_warning = App.showWidget("warning.html", "bottom", 440, 250);
								
								p.tag.widget_warning.sendMessage({
									str_warningText :  'Race track needs to be setup',
									str_warningText2 : ' needed)',
									str_warningText3 : 'Run',
									warningMsg: warning,
								})
							} else {
								if(p.tag.widget){
									p.tag.widget.destroy();
									p.tag.widget = null;
								}
								
								startState(STATE_INTRO);
								_start = true;
							}
						}
					})  
				}
			}
    		break;

		case STATE_INTRO: 
			App.showCenterLabel("\n minigame - RUN \n\n", 0xffffff, 0x000000, 120); ;
			break; 
		
		case STATE_READY:
			for(let p of _players){
				if(p.tag.start)
				   continue; 
				
				//모든 플레이어가 "race_start_point" 로케이션으로 이동한다 
				p.spawnAtLocation("race_start_point"); 

				p.moveSpeed = 0; 
			   	p.sendUpdated();
			}
			break;
		
		case STATE_PLAYING:	
			
			App.showCenterLabel("Start!!", 0xffffff, 0x000000, 120); ;
			
			for(let p of _players){
				if(p.tag.start)
				continue; 
				p.moveSpeed = _playerBaseSpeed; 
				p.sendUpdated();
			}
			break

		// 게임 결과 처리 
		case STATE_JUDGE:
			for(let i =0 ; i <_rankList.length; i++){
				let rank = ''; 
				if(i == 0)
					rank = '1st'; 
				else if(i == 1)
					rank = '2nd';
				else if(i == 2)
					rank = '3rd'; 
				else
					rank = `${i + 1}th`;
				//게임종료 후 등수 표시 
				App.sayToAll(`${rank} : ${_rankList[i].name} !`);
			}
			for(let p of _players){
				p.moveSpeed = 80; 
				p.sendUpdated();
			}
			_start = false;

			break

		// 게임 종료 처리 
		case STATE_END:
			for(let p of _players){
				//게임이 종료되면 모든 플레이어는 "race_end_point" 로케이션으로 이동한다 
				p.spawnAtLocation("race_end_point"); 
				
				if(p.tag.isNotPlayer)
					p.tag.isNotPlayer = false;
			}
			_start = false;
			
			break
  }
}

App.onLeavePlayer.add(function(p){
	_players = App.players;

	p.moveSpeed = 80; 
	p.sendUpdated();

})

// 플레이어가 해당 맵에 들어왔을 때 처리
App.onJoinPlayer.Add(function (p) {
	p.tag = {};
  
	//게임시작 후 들어온 플레이어 처리 
	if (_start) {
		p.tag.isNotPlayer = true;  

	} else {
		p.tag.isNotPlayer = false; 
		p.tag.speedTimer = 0;
		p.tag.isFinish = false;  
		p.tag.speedChnage = false; 
	  	p.sendUpdated();
	}
	//게임이 시작된 후 들어온 플레이어는 'race_end_point' 로케이션으로 이동시킨다 
	if(p.tag.isNotPlayer)
		p.spawnAtLocation("race_end_point"); 

	_players = App.players;
  });

App.onStart.Add(function(){
	startState(_state);

	//"speed_set_40", "speed_set_60", "speed_set_140", "speed_set_160" 으로 지정한 로케이션을 밟으면 
	//2초간 해당 로케이션 이름의 숫자와 같이 플레이어의 속도가 변한다. (2초 후 플레이어의 속도는 _playerBaseSpeed 가 된다 )
	//ex) "speed_set_40"를 밟으면 속도가 40으로 변함 
	let speed = [40,60,140,160]; 

	for(let i =0; i<speed.length; i++){
		App.addOnLocationTouched(`speed_set_${speed[i]}`, function(p){

			if(_state !== STATE_PLAYING)
				return; 

			p.moveSpeed = speed[i]; 
			p.tag.speedTimer = 0; 
			p.tag.speedChnage = true;

			//로케이션에 설정된 속도에 따라 "속도가 빨라졌습니다", "속도가 느려졌습니다" 등의 라벨이 해당 플레이어에게 띄워진다
			let str = '';
			if(i == 0)
				str = 'Speed greatly reduced';
			else if(i == 1)
				str = 'Speed reduced';
			else if(i == 2)
				str = 'Speed increased';
			else
				str = 'Speed greatly increased';

			p.showCenterLabel(`${str}`, 0xffffff, 0x000000, 120); 
			p.sendUpdated();	
		})
	}

	//"speed_set_random" 로케이션을 밟는 경우 플레이어의 속도가 40, 60, 140, 160 중 하나의 속도로 2초간 바뀐다 (2초 후 플레이어의 속도는 _playerBaseSpeed 가 된다 )
	App.addOnLocationTouched(`speed_set_random`, function(p){
		if(_state !== STATE_PLAYING)
			return; 

		p.moveSpeed = speed[Math.floor(Math.random() * 4)]; 
		//로케이션에 설정된 속도에 따라 "속도가 빨라졌습니다", "속도가 느려졌습니다" 등의 라벨이 해당 플레이어에게 띄워진다
		let str = '';
		if(p.moveSpeed == 40)
			str = 'Speed greatly reduced';
		else if(p.moveSpeed == 60)
			str = 'Speed reduced';
		else if(p.moveSpeed == 140)
			str = 'Speed increased';
		else
			str = 'Speed greatly increased';

		p.showCenterLabel(`${str}`, 0xffffff, 0x000000, 120); 
		p.tag.speedTimer = 0; 
		p.tag.speedChnage = true;
		p.sendUpdated();
	})

	//플레이어가 결승선을 통과하는 경우
	App.addOnLocationTouched("race_finish_point", function(p){
		if(p.tag.isFinish)
			return; 

		if(p.tag.isNotPlayer)
			return;

		_delayTimer = 0; 

		// 처음으로 플레이어가 결승선을 통과하는 경우 레이스 종료 카운트 다운을 시작한다(디폴트 30초)
		if(!_finishCountDown)
			_finishCountDown = true;

		// 플레이어가 결승선을 최초에 통과한 경우를 체크한다 
		p.tag.isFinish = true; 
		_rankList.push(p); 
		_rank++;
	})
});
 
App.onUpdate.Add(function(dt){
	_stateTimer += dt; 

	if(_start){
		for(let p of _players){
			if(p.tag.isNotPlayer)
				p.showCenterLabel("game is in progress, please wait..",0xffffff, 0x000000, 120);
		}
	}

	switch (_state) {
		case STATE_INIT:
		break;
		case STATE_INTRO: 
			if(_stateTimer >= 3){
				startState(STATE_READY);
			}
			break; 
		case STATE_READY:
			//출발선에서 _countDown 초(디폴트 10초) 간 레이스 카운트 다운을 시작한다 
			App.showCenterLabel(`${_countDown}  seconds later the race will start. `,0xffffff, 0x000000, 120); 

			if(_stateTimer >= 1){
				_stateTimer = 0; 
				_countDown --; 
			} 
			
			//카운트가 종료되면 (_countDown 가 0이 되면) 레이스가 시작된다  
			if(_countDown <= 0)
				startState(STATE_PLAYING); 
			break;
		case STATE_PLAYING:
			
			for(let p of _players){

				if(finishCheck() && _rankList.length == 0){
					p.showCenterLabel("There is no winner",0xffffff, 0x000000, 120);
					p.spawnAtLocation("race_end_point"); 
					startState(STATE_END);
				}
				// else if(finishCheck())
				// 	startState(STATE_JUDGE);
				
				if(p.tag.isNotPlayer)
					continue; 
				if(p.tag.speedChnage)
					p.tag.speedTimer += dt; 
				
				//어떤 속도 지정 타일을 밟아도 2초 후 기본 속도(_playerBaseSpeed)로 돌아온다 
				if(p.tag.speedTimer >= 2 && p.tag.speedChnage){
					p.moveSpeed = _playerBaseSpeed; 
					p.tag.speedChnage = false; 
					p.sendUpdated(); 
				}
			}
			
			if(_finishCountDown)
				{	
					_delayTimer += dt; 
					//플레이어가 결승선을 통과하면 1.5초간 플레이어의 이름과 레이스 카운트다운을 라벨로 나타낸다 
					if(_delayTimer <=1.5)
						App.showCenterLabel(`${_rankList[_rankList.length -1].name}  ${_rank - 1} place ! \n\n ${_finishCount} seconds later the race will end`,0xffffff, 0x000000, 120);
					else
						App.showCenterLabel(`${_finishCount} seconds later the race will end`,0xffffff, 0x000000, 120);

					_finishTimer += dt; 

					if(_finishTimer >= 1){
						_finishCount--; 
						_finishTimer = 0; 
					}
					// 레이스 카운트다운이 종료(0초)되었거나, 모든 플레이어가 결승선을 통과한 경우, 다음 단계로 넘어간다  
					if(_finishCount == 0 || finishCheck()){
						startState(STATE_JUDGE); 
					}
				}
			break; 
		case STATE_JUDGE:
			//5초간 우승자(1등)의 이름을 라벨로 나타낸다 
			if(_stateTimer <= 5){
				App.showCenterLabel(`- Winner - \n\n ${_rankList[0].name}`,0xffffff, 0x000000, 120);
			} 
			//5초간 "잠시 후 대기실로 이동합니다"라는 라벨을 띄웁다 
			else if(_stateTimer > 5 && _stateTimer <= 10 ){
				App.showCenterLabel("You will soon be transported to the waiting room",0xffffff, 0x000000, 120);
			}
			else {
				startState(STATE_END);
			}
			break;
		case STATE_END:
			
			break;
	}
});
🏃‍♂️
2MB
달리기.zip
archive