rogue like 게임 개발(game.js 부분)

김민재·2024년 8월 21일
0

먼저, 클래스에서 다른 클래스에 있는 메서드들을 호출할 수 있는가에 대해서 찾아보았다.
그렇지만 클래스는 독립적인 것이라 다른 클래스에 있는 메서드에 접근하는 것은 불가능하다. 라고 판별내리고 각각의 메서드를 호출하는 방식으로 접근하고자 했다.

1.클래스 선언 및 생성자



간단하게 활용할 수 있는 것들로부터 값을 넣었고 여기서 방어확률은 boolean값으로써 defence()라는 메서드에서 이를 true/false로 확인하여 공격이 성공했는지 안했는지를 확인해준다.

2.attack

(1).Player.attack()

말 그대로 플레이어가 몬스터에게 또는 몬스터가 플레이어에게 데미지를 입히는 것이다.
1.먼저 플레이어 내에 attack() 이라는 메서드를 만든다.
2.이 메서드를 호출할 때 들어갈 인자를 넣어야만 하는데, 우리는 player의 공격력과 monster의 hp를 둘다 참조하고 싶기 때문에 player와 monster를 둘다 호출하여 사용하였다.

3.해당 메서드 내부에서 이제 player의 공격력(str)과 크리티컬 계수(AtkPro)을 통해서 해당 플레이어가 공격했을경우에 monster의 hp를 제거하는 메서드를 구현한다.
4.이때 몬스터 역시 방어할 수 있게끔 만들기 위해서 몬스터가 방어하는지 안하는지 역시도 인식해와서 몬스터가 방어했을 경우 공격이 안먹히게끔 했다.

Q1. 왜 몬스터가 방어한지 안 한지를 고려하는 것과 왜 몬스터가 방어한지 안한지를 player에서 바꾸는걸까?

Q2. 왜 AtkPro - 크리티컬 계수를 결정하는 사안에서 Math.round와 같은 메서드들을 사용하지 않았는가?
Math.round / Math.ceil / Math.floor 각각 반올림,올림,버림으로 소수점 이하의 수들을 처리하는데 round와 같은 함수들을 사용하다보니 0.5(즉 절반의 공격력)이나 1.5(공격력의 1.5배)와 같은 계수들을 처리할 때 1이나 2로써 처리를 해버리는 것이었다.
그렇기에 인터넷에 찾아봐서 이를 소수점 1자리까지만 가져오는 toFixed(1) 이라는 메서드를 이용하여 값을 저장했다.

(2).Monster.attack()


플레이어와 방식은 비슷하나 플레이어와 다르게 몬스터의 고정공격력에 비례하도록 했다.

3.Player의 다른 기능들

(1).defence()

적힌 그대로 방어하는 기능이다.
1.방어를 시도할 때 먼저 방어를 할 수 있는지 없는지 확률을 확인한다.
1-1.이때 Math.random을 이용하여 1~10중 하나를 선택하였을 때 2로 나누어 떨어진다면(50%) 방어에 성공했음으로 취급한다.

(2).run()

도망가는 기능이다.
1.방어와 마찬가지로 도망갈 수 있을지 없을지 확률을 확인한다.
1-1.이때 Math.random으로 1~5중에 하나를 선택하여 2로 나누어 떨어진다면(40%) 도망에 성공했음으로 게임을 해당 라운드의 초기로 돌려 다시 시작한다.

이때 기존의 얻었던 코드에서는 startGame() 내부에 stage 변수가 존재하여

새로 시작할 때마다 stage를 1로 초기화했었지만 이를 밖으로 빼서 해당 스테이지를 다시 시작하더라도 stage 값이 초기화되지 않도록 했다.

(3).conAtk() => 연속 공격

말 그대로 연속 공격하는 기능이다.
1.최대 공격 횟수를 정한다.(이때 최대공격횟수는 0~7 사이로 랜덤으로 정한다.)
2.상대가 방어했는지 방어를 하지 않았는지에 따라서 데미지가 들어가거나 들어가지 않게끔 처리를 한다.(player.attack()와 동일)

3.만약 상대가 방어를 하지 않았을 때
3-1.공격 횟수가 0이라면 당연히 공격에 실패했으니까? 연속 공격에 실패했음을 띄우고 끝이다.
3-2.만약 그렇지않다면 for문을 활용하여 연속 공격의 횟수만큼 공격하게끔 만들었다.

이때 for문을 사용한 이유는 각 타수마다 크리티컬 확률을 따로 적용시켜보고 싶었기 때문이다.(for문이 호출될 때마다 크리티컬 확률은 변화하게 된다.)

(4). heal()

회복하는 기능이다.
이것때문에 플레이어에 Max_HP와 MP를 넣어두었다.
1.플레이어의 MP가 있거나, 플레이어의 현재 HP가 해당 stage에서 될 수 있는 최대 HP보다 작을 경우에만
2.힐이 발동하여 잃은 체력에 비례하여 회복하는 기능이다.

4.Monster의 다른 기능들

몬스터에 필요한 기능이 뭘까..
일단은 고정 공격력으로 계속 공격을 해봤자 나중가서는 힘이 부칠것이다.
그렇기에 강한 한방?과 방어를 준비하여 플레이어를 괴롭히도록 하자.

(1). defence()

몬스터 역시도 플레이어와 마찬가지로 방어를 할 수 있어야겠다.
동작은 플레이어와 똑같다.

Q. 여기서 의문점이 드는게 있다.
과연 둘다 방어를 하게되면 어떻게 되는걸까?????

둘다 방어행동을 하고 나서 다음 행동으로 넘어가게되면 방어를 켜둔(true) 상태로 넘어가게 되기때문에 다음 행동에서 상대가 공격을 하더라도 방어가 되어버리고 만다.
그렇기에 이를 처리하고자 battle 함수에서 행동이 전부다 끝났을 때 만약 서로의 방어가 true가 되어있는 것들이 있다면 둘다 false로 처리되게끔 하였다.

(2). superAttack() => 강타

리그오브 레전드의 강타싸움에서 진 정글러는 인권이 없다고 ?
LOL의 강타와는 다르게 강한 한방을 플레이어에게 먹이는 것이다.
1.Monster의 attack과 마찬가지로 먼저 플레이어가 방어를 하는지 안하는지를 확인한다.
2.상대가 방어를 하지 않을 경우엔 플레이어의 최대 HP의 30% + 몬스터의 공격력에 해당하는 피해를 준다.
(꼭 방어해야겠지? - 그렇지만 방어확률은 50%.)

4. startGame() 함수의 내부

먼저 게임 시작을 확인해보고자 한다.
1.Stage의 값이 10보다 작을 경우에 player와 monster class를 새롭게 선언한다.
2.해당 Stage의 값을 출력하고 battle에 들어가게 되는데,
3.배틀이 끝나고나서 player의 HP가 0보다 작다면 player의 패배, monster의 HP가 작다면 Stage값을 ++하고 다시 반복하게 되고
4.만약 모든 스테이지를 클리어했을 경우엔 해당 프로세스를 종료시키며 끝난다.

5. battle()함수의 내부

말 그대로 battle을 실시하는 함수이며
1.내부에서는 player나 monster의 HP가 둘중 하나가 0이 되기전까지 계속 전투를 반복하게 된다.
1-1.그리고 반복문 내부에선 플레이어나 몬스터의 스테이터스를 표시해주며(displayStatus), monster의 패턴을 설정하고 강한 공격이 올거 같거나 player의 현재 HP에 따라서 현 상황을 표시해주는 로그를 띄우거나 한다.

1-2.이후에 어떤 행동을 할 것인지를 고르는데 readlineSync라는 import 메서드를 이용하여 choice에 값을 저장하게 된다.
이때 주의할 점이 있는데 choice에 저장되는 값은 string 즉 문자형으로 저장이 되어있기 때문에 case문에서 숫자로 처리를 하고자한다면 Number(choice)를 할 필요가 있다.
이후에 저장된 값을 switch~case문을 통하여 log에 저장하고 이후에 player와 monster의 행동을 정하게 된다.

1-2-1.만약 player가 방어를 골랐다면,
1-2-1-1.monster의 패턴이 방어가 아닐경우엔 player의 방어를 먼저 활성화하고 monster의 행동을 처리한다.

1-2-1-2.monster의 패턴이 방어일 경우엔 둘다 방어 행동을 한다.
1-2-2.만약 player가 방어를 고르지 않았을때,
1-2-2-1.monster가 방어행동을 골랐다면, monster의 방어행동을 먼저 한 후 player의 나머지 행동을 개시한다.

1-2-2-2.방어행동이 아닐경우 player의 행동을 제일먼저 실시한 후 monster의 행동을 개시하게 된다.
업로드중..

이를 통해서 간단하게 로그라이크 게임을 제작해보았다.

FeedBack

1.코드 길이가 길다.
=>플레이어의 행동을 처리하는 switch문이나 monster문에 대해서 별도의 함수를 선언하여 줄일 수 있을 것 같다.
2.플레이어와 몬스터의 행동이 전부다 끝나고나서 다음 While문에 player와 monster의 HP를 비교하고 반복문을 중단시키기 때문에 모든 행동이 끝나기 전까지 player나 monster의 HP가 0이하로 떨어지게 되더라도 종료가 되지 않게 된다.
=> 이 부분에 대해서는 동작 이후에 player나 monster의 HP를 고려하는 if문을 넣게 되면 바로 처리를 할 수 있게 되지만, 동일한 코드들을 여러군데에 넣게 되어야하는 번거로움이 생길 수 있게되어서 고민을 하는 중이다.
3.heal()같은 함수에서 setInterval()을 사용해서 영창 같은 느낌으로 해보고자 했는데 이를 무시하고 넘어가는 경우가 생겨버렸다.
=> 이 부분도 좀 고민인게 아무리 생각해도 Interval이 무시되는 이유에 대해서 모르겠고 인터넷에 찾아봐도 결론이 나오지 않아서 내일 천천히 연구해보고자 한다.

위의 문제들을 질문 등을 통해서 해결해볼 예정이고,
해결이 대충 끝나면 Stage의 값을 통해서 보스 몬스터 정도를 만들어볼까 생각하고 있다.

profile
ㅇㅇ

0개의 댓글