-
JavaScript 입문 : textRPG 만들기 - 각 단계별 최종 작업컴퓨터 알아가기/JavaScript 2022. 9. 13. 19:30728x90반응형
이 글은 제로초 TV의 자바스크립트 강좌를 기본으로 하고 있습니다.
텍스트 롤플레이게임을 만들면서 더 추가로 꾸며보고 싶은 생각이 많이 들었습니다만, 지금 참조하고 있는 강좌도 거의 끝나가고 있기때문에 진도를 먼저 내보고 계속적으로 다듬어 보고자 합니다.
1. 일반 게임 모드 (휴식과 종료 코드 업데이트)
일반 게임 모드에서는 휴식과 종료 코드가 필요합니다. 휴식하는 동안 체력을 최대치로 확보하도록 하여 강한 상대가 나타나도 문제가 없게 하고 게임이 끝나는 종료 코드에서는 this.quit( )메소드를 사용하면서 화면에 떠있는 메시지를 없애면 되겠습니다.
2. 사냥 게임 모드 (회복과 도망 관련 코드)
사냥 게임 모드에서 추가 필요한 코드는 회복과 도망 관련 코드입니다. 회복은 사냥하다가 체력이 손실 되었을때 일부 충전하는 기능을 넣는 코드인데 여기서는 체력을 20정도 회복하는 것으로 설정합니다. 물론 회복의 조건을 하나 붙혔는데 회복 기능을 사용하면 바로 앞 사냥감에게 한번 더 공격을 당하는 순서로 정했구요.
도망은 말 그대로 싸워도 승산이 없는 게임에서 줄행랑 치는 겁니다. 다음과 같이 코드를 업데이트 가능합니다.
이제는 가능한 시나리오에서 작동이 잘 되는것을 확인할 수 있습니다.
다음은 textrpg의 HTML과 JS 전체코드를 공유합니다. 아마 복사가 안될 수 있지만 복사 붙혀넣기해서 공부하는 것보다 차례대로 타이핑을 해가며 익히는게 훨씬 기억에 남고 도움이 됩니다.
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>RPG 첫걸음</title> <link rel="stylesheet" href="textrpg.css"> </head> <body> <!--시작준비 html 기본구조--> <form id="start-screen"> <input id="name-input" placeholder="당신의 이름을 입력하시오."> <button id="start">시작</button> </form> <!--시작되면 바뀔화면--> <div id="screen"> <!--주인공 현황--> <div id="hunter-status"> <span id="hunter-name"></span> <span id="hunter-level"></span> <span id="hunter-power"></span> <span id="hunter-upgrade"></span> <span id="hunter-attack"></span> </div> <!-- 일반메뉴: 전투메뉴와 상호작용으로 form태그 display: none--> <form id="general-menu" style="display: none;"> <div id="general-1">1. 모험</div> <div id="general-2">2. 휴식</div> <div id="general-3">3. 종료</div> <input type="text" id="general-input"> <button id="general-button">입력</button> </form> <!-- 전투메뉴: 일반메뉴와 상호작용으로 form태그 display: none--> <form id="battle-menu" style="display: none;"> <div id="battle-1">1. 공격</div> <div id="battle-2">2. 회복</div> <div id="battle-3">3. 도망</div> <input type="text" id="battle-input"> <button id="battle-button">입력</button> </form> <!--메시지 표시--> <div id="message"></div> <!--적군 현황--> <div id="animal-status"> <span id="animal-name"></span> <span id="animal-level"></span> <span id="animal-power"></span> <span id="animal-upgrade"></span> <span id="animal-attack"></span> </div> </div> <script src="trpgself.js"></script> </body> </html>
// selfCheck : 나머지 코드 완성 // 일반메뉴 : 휴식과 종료 (휴식: 최대회복) // 전투메뉴 : 회복과 도망 (회복: 체력20 회복 but 1번의 동물 공격 필수, 최대체력 넘지못함) const $startScreen = document.querySelector('#start-screen'); const $screen = document.querySelector('#screen'); const $generalMenu = document.querySelector('#general-menu'); const $battleMenu = document.querySelector('#battle-menu'); const $message = document.querySelector('#message'); // 주인공 Status 연결 const $hunterStatus = document.querySelector('#hunter-status'); const $hunterName = document.querySelector('#hunter-name'); const $hunterLevel = document.querySelector('#hunter-level'); const $hunterPower = document.querySelector('#hunter-power'); const $hunterUpgrade = document.querySelector('#hunter-upgrade'); const $hunterAttack = document.querySelector('#hunter-attack'); // 적군 현황 연결 const $animalStatus = document.querySelector('#animal-status'); const $animalName = document.querySelector('#animal-name'); const $animalLevel = document.querySelector('#animal-level'); const $animalPower = document.querySelector('#animal-power'); const $animalUpgrade = document.querySelector('#animal-upgrade'); const $animalAttack = document.querySelector('#animal-attack'); // hunter와 animal을 class로 재구성 (OOP), 상호작용 및 상호접근 용이 class General { // 생성자는 대문자로, constructor(name) { // 이름 매개변수로 생성 this.animal = null; this.hunter = null; // new General(name)으로부터 받아서 this.animalList = [ {name: '멧돼지', power: 10, att: 10, upgrade: 10}, {name: '사자', power: 20, att: 15, upgrade: 20}, {name: '호랑이', power: 30, att: 20, upgrade: 30}, {name: '코끼리', power: 50, att: 40, upgrade: 50}, {name: '공룡', power: 100, att: 70, upgrade: 100}, ]; this.start(name); // General객체내 start시킴 } start(name) { // 특정 동작을 같이 묶는게 좋다 // addEventListener가 있으니까 여기서 this는 향후 화살표 함수로 받음 $generalMenu.addEventListener('submit', this.onGeneralMenuInput); $battleMenu.addEventListener('submit', this.onBattleMenuInput); this.changeScreen('general'); this.hunter = new Hunter(this, name); this.updateHunter(); } changeScreen(screen) { // screen 변하는 기능 한곳에 if (screen === 'start') { // 처음 시작이라는 표시, 어떤 단어도 OK $startScreen.style.display = 'block'; $generalMenu.style.display = 'none'; $battleMenu.style.display = 'none'; } else if (screen === 'general') { $startScreen.style.display = 'none'; $generalMenu.style.display = 'block'; $battleMenu.style.display = 'none'; } else if (screen === 'battle') { $startScreen.style.display = 'none'; $generalMenu.style.display = 'none'; $battleMenu.style.display = 'block'; } } // addEventListener가 붙으면 this는 화살표 함수로 풀어야 한다 (암기) // 화살표함수의 this는 밖에 있는 this를 그대로 가져옴 onGeneralMenuInput = (event) => { // start()에서 generalMenu 활성화 event.preventDefault(); const general = event.target['general-input'].value; // id가져와서 활성화, value는 text if (general === '1') { // 모험 this.changeScreen('battle'); // 전투메뉴로 만들고 console.log(this); // 여기서 this는 General // 랜덤하게 animal 생성 const randomIndex = Math.floor(Math.random() * this.animalList.length); const randomAnimal = this.animalList[randomIndex]; // new Animal( ) 생성 this.animal = new Animal( this, randomAnimal.name, randomAnimal.power, randomAnimal.att, randomAnimal.upgrade, ); this.updateAnimal(); this.showMessage(`사냥할 동물이 나타났다! ${this.animal.name}인것 같다!`); } else if (general === '2') { // 휴식 // 전투가 끝나고 쉴때 체력이 회복되는 기능 \ this.hunter.power = this.hunter.maxPower; // 최대치까지 파워를 충전하고 this.updateHunter(); // 헌터 업데이트 하고 this.showMessage(`쉬지 않았으면 체력을 회복하기 힘들었다. `); // 에의상 메시지 넣고 } else if (general === '3') { // 종료 // 종료할때는 메시지를 없애주고 quit() this.showMessage(``); // 종료이기에 메시지 없애고 this.quit(); } }; onBattleMenuInput = (event) => { // start()에서 battleMenu 활성화 event.preventDefault(); const battle = event.target['battle-input'].value; // id가져와서 활성화 if (battle === '1') { // 공격, 서로 공격 const { hunter, animal } = this; hunter.attack(animal); animal.attack(hunter); // 기본적인 공격 메시지 // this.showMessage(`헌터가 ${hunter.att}의 데미지를 주고 ${animal.att}의 데미지를 받았다.`); // 공격해서 나올수 있는 경우의 수를 고민 // 1. hunter power가 0이하면 전사 및 새로운 hunter생성 // 2. animal power가 0이하면 animal의 upgrade power를 얻음 (get) // 3. 1,2가 아닌 경우 기본적인 공격메시지 송출 if (hunter.power <= 0) { // 1. this.showMessage(`${hunter.level}레벨에서 전사. 새 주인공을 생성하세요`); this.quit(); // 게임종료에 대한 함수 } else if (animal.power <= 0) { // 2. this.showMessage(`사냥에 성공하여 사냥감이 가지고 있는 ${animal.upgrade}의 힘을 얻었다.`); hunter.getUpgrade(animal.upgrade); // 사냥감 힘 얻는 함수, hunetr내 설정 this.animal = null; // 없어지고 this.changeScreen('general'); // 일반모드로 } else { // 3. this.showMessage(`헌터가 ${hunter.att}의 데미지를 주고 ${animal.att}의 데미지를 받았다.`); } // 각 상태가 업데이트되야 함 this.updateHunter(); this.updateAnimal(); } else if (battle === '2') { // 회복 const { hunter, animal } = this; // 변수 선언하고 // 내체력 + 20 but 최대체력은 넘을수 없고, 최소값 구하는 메소드 활용 hunter.power = Math.min(hunter.maxPower, hunter.power + 20); animal.attack(hunter); // 회복시 한번 공격당하고 this.showMessage(`조금 체력을 회복했으나 ${animal.name}에게 한번 더 공격을 당했다.`); this.updateHunter(); } else if (battle === '3') { // 도망 : 일반메뉴로 전환 this.changeScreen('general'); // 일반메뉴 this.showMessage(`상대가 안되어 도망갔다.`); this.animal = null; // 동물 사라짐 (초기화) this.updateAnimal(); } }; // hunter상태 update, 없으면 빈칸, 레벨과 파워변하는 상황 (초기선언) updateHunter() { const { hunter } = this; // 업데이트 할 변수선언, 구조분해할당 모습 if (hunter === null) { // hunter가 없으면 $hunterName.textContent = ''; $hunterLevel.textContent = ''; $hunterPower.textContent = ''; $hunterUpgrade.textContent = ''; $hunterAttack.textContent = ''; return; // return 하고 } // hunter가 있으면 $hunterName.textContent = hunter.name; $hunterLevel.textContent = `레벨: ${hunter.level}`; $hunterPower.textContent = `파워: ${hunter.power} / ${hunter.maxPower}`; $hunterUpgrade.textContent = `업그레이드: ${hunter.upgrade} / ${15 * hunter.level}`; $hunterAttack.textContent = `공격력: ${hunter.att} `; } updateAnimal() { const { animal } = this; // 업데이트 할 변수선언, 구조분해할당 모습 if (animal === null) { // animal이 없으면 $animalName.textContent = ''; $animalPower.textContent = ''; $animalAttack.textContent = ''; return; // return 하고 } // animal이 있으면 $animalName.textContent = animal.name; $animalPower.textContent = `파워: ${animal.power} / ${animal.maxPower}`; $animalAttack.textContent = `공격력: ${animal.att} `; } showMessage(text) { // 메시지 보이게 $message.textContent = text; } // 게임종료 quit() quit() { this.hunter = null; this.animal = null; this.updateHunter(); this.updateAnimal(); $generalMenu.removeEventListener('submit', this.onGeneralMenuInput); $battleMenu.removeEventListener('submit', this.onBattleMenuInput); general = null; } } // 비숫한 캐릭터의 부모 class를 만들고 나머지는 상속시킴 // 부모클래스는 기본적 변수처리 class Unit { constructor(general, name, power, att, upgrade) { this.general = general; this.name = name; this.maxPower = power; this.power = power; this.att = att; this.upgrade = upgrade; } attack(target) { target.power -= this.att; } } // Hunter는 공통점빼고 정의 class Hunter extends Unit { constructor(general, name) { super(general, name, 100, 10, 0); this.level = 1; } // 사냥감 파워 획득 getUpgrade(upgrade) { this.upgrade += upgrade; // upgrade 될때마다 아래 if문을 한번씩 검토, 에러방지 if (this.upgrade >= this.level * 15) { // 경험치를 다 채우면 this.upgrade -= this.level * 15 // 레벨이 오르기 위한 필요power는 15이기에 레벨바뀌고 다시 0으로 세팅 this.level += 1; this.maxPower += 20; // upgrade되면 최대체력은 10늘어나고 this.att += 20; // upgrade되면 공격력도 10늘어나고 this.power = this.maxPower; // upgrade되면 최대체력은 현재체력으로 되고 this.general.showMessage(` 사냥에 성공하여 사냥감이 가지고 있는 ${upgrade}의 힘을 얻었다. 레벨업 완료! 현재레벨 ${this.level} `); } } } // animal도 공통점 빼고 정의 class Animal extends Unit { constructor(general, name, power, att, upgrade) { super(general, name, power, att, upgrade); } } // 게임 시작 프로그램 let general = null; // start-screen 활성화 $startScreen.addEventListener('submit', (event) => { event.preventDefault(); const name = event.target['name-input'].value; // hunter 이름 입력 general = new General(name); // 이름 입력받아 새로운 게임 만들기, 생성자 실행조건 new 필요 });
반응형'컴퓨터 알아가기 > JavaScript' 카테고리의 다른 글
JavaScript 입문 : 카드맞추기 게임 - 기본프레임 잡기 (카드뒤집기 애니메이션 CSS 포함) (0) 2022.09.28 JavaScript 입문 : 카드맞추기 게임 - 순서도 (0) 2022.09.27 JavaScript 입문 : textRPG 만들기 - 사냥감 변경, 클래스간 상호 작용(클래스 상속) (2) 2022.09.11 JavaScript 입문 : textRPG 만들기 - 사냥모드 업데이트 및 성공한 사냥감 업그레이드 파워 얻기 (2) 2022.09.10 JavaScript 입문 : textRPG 만들기 - 헌터내역 및 동물내역 업데이트, 일반게임모드, 메시지 표시, 게임종료 메소드 (0) 2022.09.09