로그라이크 만들기 2 일차
오늘은 개인과제 필수 기능들을 주로 업데이트 해보자
★개인과제 필수기능 목록
필수기능
### 1. 단순 행동 패턴 2가지 구현
- 공격하기
- 도망치기
### 2. 플레이어 클래스에서 플레이어 스탯 (공격력, 체력 등) 관리하기
### 3. 간단한 전투 로직 구현
- 플레이어 공격, 몬스터 피격
### 4. 스테이지 클리어 시 유저 체력 회복
### 5. 스테이지의 진행과 비례해서 몬스터의 체력과 공격력 증가 시키기
### 필수 기능 공통 가이드
1. **switch 조건문**을 사용하여 유저의 각 행동에 대한 로직을 처리해보세요.
2. **while 반복문**을 사용할 때는 **종료 조건이 무조건** 있어야 합니다.
1. 스테이지 클리어 및 게임 종료 조건
2. 몬스터와의 전투 종료 조건
3. **Math.random()** 메서드를 통해서 랜덤한 숫자를 얻을 수 있습니다.
4. 플레이어의 공격은 선택에 의해서 이루어지지만, 몬스터의 공격은 자동으로 처리가 된 뒤 해당 플레이어의 로그에 보여지게 됩니다.
5. 함수의 호출 순서에 따라서 각 변수, 객체들을 관리하는 것이 중요합니다.
### 1. 확률 로직 적용
- 연속 공격, 방어, 도망치기
- 스테이지 클리어시 유저 능력치 증가, 증가량
- 몬스터의 공격력, 체력 증가량
### 2. 복잡한 행동 패턴 구현
- 연속 공격
- 방어하기
- 그 외 다른 행동
기능추가
- 스테이지 클리어시 필수 기능 작성
○ 몬스터의 체력이 0이될경우 플레이어가 레벨업하는 로직
플레이어 클래스안에 레벨업 함수를 추가 스테이지가 +1 이 될때마다 실행
플레이어의 체력이 스테이지*100의 값을 더해주고
플레이어의 회복량과 공격력을 스테이지에 비례해서 상승시켜준다.
userLevelUp(stages) { this.hp += stages * 100; this.heal = stages * 30; this.attackDmg = 20 * stages; }
생성한 함수를 조건문을 사용해서 while문 안에 호출해준다.
// 스테이지 클리어시 플레이어 체력 증가 if (monster.hp <= 0) { stage++; player.userLevelUp(stage); }
스테이지 + 체력 공격력 +
- 선택지 로직 추가
○ 방어한다 선택시 확률형 로직 추가
플레이어 클래스에 방패를 들 경우의 함수 추가
random 메서드를 사용해 1~5까지의 랜덤한 값을 가져오도록 설정하고 this.shield의 값으로 할당한후 리턴
//플레이어가 방패를 들었을 경우 막을 확률 rerollShield() { const randomShield = Math.floor(Math.random() * 5) + 1; this.shield = randomShield; return this.shield; }
플레이어 클래스에 초기값 할당class Player { constructor() { this.shield = 0; }
이후swhich 로직안에 방어한다의 선택지를 고를 경우
rerollshield 함수를 호출하고 3보다 크거나같고 5보다 작거나같을경우 방패를 들어올린다는 문구를 추가
값이 0~2라면 방패가 파괴된다를 문구를 출력하는 로직
플레이어의 로직if (player.shield >= 3 && player.shield <= 5) { logs.push( chalk.yellow(`${player.shield}! 당신이 방패를 들어올립니다!`) ); } else { logs.push(chalk.yellow(`${player.shield}! 방패가 파괴되었습니다!`)); } break;
몬스터의 경우 랜덤값은 같은값을 사용하기때문에 플레이어에서 호출된 값을 그대로 가져온후 방어에 성공했다면 몬스터가 당황한다는 문구 출력 방어에 실패할경우 방패가 파괴된단 문구와 함께 플레이어에게 몬스터의 공격력만큼의 데미지를 줌
몬스터의 로직case "4": if (player.shield >= 3 && player.shield <= 5) { logs.push( chalk.yellow( `${player.shield}! 몬스터가 공격이 막혀 당황합니다!` ) ); } else { logs.push( chalk.yellow( `${player.shield}! 몬스터의 공격이 방패를 파괴합니다!${monster.attackDmg}의 피해를 받습니다!` ) ); break;
방어 성공과 실패
○ 회복한다 선택시 회복할 수치 레벨업시 회복량 증가 로직 추가
클래스에 회복량의 기본값 설정
class Player { constructor() { this.heal = 30; }
회복한다 선택시 실행할 함수 생성selfHeal(healing) { this.hp += healing; }
3번을 선택할 경우의 로직을 추가case "3": logs.push( chalk.yellow(`당신이${player.heal}만큼의 체력을 회복합니다!`) ); player.selfHeal(player.heal); break;
회복상승량은 위에 설명한 레벨업을 할 경우 적용됨userLevelUp(stages) { this.hp += stages * 100; this.heal = stages * 30;//여기가 회복량 증가로직 this.attackDmg = 20 * stages; }
스테이지 증가에 따른 회복량 증가 / 증가량 : 선택지옆에 얼마가 회복되는지 스테이지별로 표기됨
○ 도망간다 선택지 로직 추가
1~2의 랜덤값을 생성하는 로직을 추가하고 값이 1이 나온다면 도망을 성공하고 2가나온다면 도망에 실패한후 몬스터에게 공격력만큼의 데미지를 받는 로직을 추가함
플레이어 클래스의 constructor 안에 초기값 할당
this.run = 0;
클래스 내부에 랜덤으로 1~2를 반환하는 함수를 생성함
runAway() { const randomRun = Math.floor(Math.random() * 2) + 1; this.run = randomRun; return this.run; }
battle 함수 내부에while문 안에 runAway함수를 선언해준다.
player.runAway();
불러온 함수를 도망간다 선택지를 선택한경우 값이 1이라면 도망성공! 이라는 문구와함께 플레이어와 몬스터의 체력과공격력이 스테이지 * 맥스값으로 변환 ,값이 2라면 도망실패후 몬스터에게 피격당하는 로직을 작성
플레이어의 로직
case "5": if (player.run === 1 && stage >= 1) { logs.push( chalk.yellow(`(${player.run}!) 당신은 꼴사납게 도망칩니다!`) ); player.hp = stage * 100; player.attackDmg = stage * 20; } else { logs.push( chalk.yellow(`(${player.run}!) 당신은 도망에 실패했습니다..`) ); } break;
몬스터의 로직
case "5": if (player.run === 1) { logs.push(chalk.red(`몬스터가 당신을 비웃습니다...`)); monster.hp = stage * 100; monster.attackDmg = stage * 20; } else { logs.push( chalk.red( `몬스터가 도망가는 당신에게 ${monster.attackDmg}피해를 입힙니다` ) ); player.userHitDmg(monster.attackDmg); } break;
도망 실패와 성공
○ 연속공격 선택시 로직
연속공격을 선택할 경우 1~3의 값중 랜덤한값이 나오고 값이 1이 나온다면 일반공격*2의 데미지를 준다
값이 2가 나온다면 일반공격*3의 데미지를 주며 몬스터가 아무런 행동도 하지않지만
값이 3이 나올경우 몬스터가 일반공격의*3의 데미지를 플레이어에게 준다.
플레이어 클래스에 연속공격의 초기값 추가
this.double = 0
연속공격의 함수 생성doubleAttack() { const randomAttack = Math.floor(Math.random() * 3) + 1; this.double = randomAttack; return; }
플레이어의 로직case "6": if (player.double === 1) { logs.push(chalk.yellow(`${player.double}!연속공격에 성공했습니다!`)); logs.push(chalk.yellow(`${player.attackDmg}의 피해를 입힙니다.`)); logs.push(chalk.yellow(`${player.attackDmg}의 피해를 입힙니다.`)); monster.monsterHitDmg(player.attackDmg * 2); } else if (player.double === 2) { logs.push(chalk.yellow(`${player.double}!연속공격에 성공했습니다!`)); logs.push(chalk.yellow(`${player.attackDmg}의 피해를 입힙니다.`)); logs.push(chalk.yellow(`${player.attackDmg}의 피해를 입힙니다.`)); logs.push(chalk.yellow(`${player.attackDmg}의 피해를 입힙니다.`)); monster.monsterHitDmg(player.attackDmg * 3); } else { logs.push(chalk.red(`공격에 실패했습니다!`)); } break;
몬스터의 로직case "6": if (player.double === 1) { logs.push(chalk.red(`몬스터가 막대한 피해를 입습니다!`)); } else if (player.double === 2) { logs.push(chalk.red(`몬스터가 절대한 피해를 입습니다!`)); } else { logs.push( chalk.red( `몬스터가 당신에게 ${monster.attackDmg * 3}의 절대한 피해를 입힙니다! ` ) ); player.userHitDmg(monster.attackDmg * 3); } break;
연속공격 실패시 리스크와 성공시 리턴
- 플레이어가 죽거나 모든 스테이지 클리어시 출력해줄 값들
10스테이지 전에 플레이어의 체력이 0이될경우
당신이 죽었습니다! 를 출력해줌
if (player.hp <= 0) { console.clear(); console.log(chalk.red("당신은 죽었습니다!")); break; }
10스테이지를 클리어 했을 경우
플레이어 클래스에 클리어까지 얼마나 턴을 사용했는지 카운팅해줄 turnCount추가후 선택지 입력시 카운트한다.if (choice <= 6 && choice !== "") { logs.push(chalk.green(`${choice}를 선택하셨습니다!`)); player.turnCount++; ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ this.turnCount = 0; //마지막 결과화면 랭킹을 위한 턴수
10스테이지 클리어시 축하 메시지 출력if (stage > 10) { console.clear(); console.log(chalk.blue("축하합니다! 모든 스테이지를 클리어 하셨습니다!")); console.log( chalk.red( figlet.textSync("C L E A R !", { font: "Standard", horizontalLayout: "default", verticalLayout: "default", }) ) ); console.log();
클리어시 축하 메시지 랭킹보드
1스테이지~10스테이지까지 사용한 턴수를 기준으로 1,2,3등을 출력해줌(기능구현x)
console.log(chalk.blue("랭킹")); console.log(); console.log(chalk.red("1ST")); displayStatus( stage - 1, player, monster, console.log(chalk.red`Total Choices${player.turnCount}`) ); console.log(chalk.blue("2ND")); displayStatus( stage - 1, player, monster, console.log(chalk.blue`Total Choices${player.turnCount + 10}`) ); console.log(chalk.green("3RD")); displayStatus( stage - 1, player, monster, console.log(chalk.green`Total Choices${player.turnCount + 15}`) ); break;
랭킹보드
2일차 개인과제 마무리
1일차에 게임 만든다고 신나서 일단 이것저것 만들고봤지만 초기 설계가 얼마나 중요한지 알것같다
이거 만들고 저거 만들고 왔다갔다하면서 만들다보니 작동이 안되기 시작하면 어디서 고장난건지 찾을 방도가없다
눈만 부라릴뿐.. 내가 처음부터 만든것이 아닌 스켈레톤 코드를 쓰다보니 어떤 부분이 오류가 난건지도 모르겠고
그걸 모르니 구글링도 쉽지않았다.
그래도 오늘 과제에 필요한 필수 기능들은 전부 구현했다 나는 해냈다...
'부트캠프' 카테고리의 다른 글
컴퓨터 세계 에서 의 서버와 클라이언트 (0) | 2024.08.25 |
---|---|
개인과제 JS로 로그라이크 콘솔게임 만들기 3일차(완) (0) | 2024.08.23 |
개인과제 JS로 로그라이크 콘솔게임 만들기 1일차 (0) | 2024.08.21 |
wep페이지 만들기 연습 2일차 (0) | 2024.08.09 |
wep페이지 만들기 연습 1일차 (0) | 2024.08.08 |