과정명 : 내일배움캠프 Unity 게임개발 3기
전체진행도 : 13일차
부분진행도 : Chapter2.2 - 2일차
작성일자 : 2024.01.10(수)
개발일지 목록 : 클릭
1. 진행중인 과정에 대해
콘솔 텍스트 던전 RPG 게임의 팀 과제 진행중.
구현할 기능별로 역할을 분담하여 진행하는 방식을 택하였다. 수정할 파일이 서로 겹치는 경우가 빈번할 것 같아 Merge도중 충돌이 많이 일어날 것 같았는데, 걱정과는 달리 엄청 순조로운 진행을 보였다.
나는 던전 전투 중 데미지 계산(일정 확률의 치명타, 일정 확률의 적 회피) 메서드의 작성을 먼저 맡아 완료한 후, Potion 클래스에 관해서도 새로 작성 한 후 포션과 관련된 게임 내 기능들을 작성중에 있다.
필수적인 요소는 모두 마무리가 되어 각자 선택요소 중 원하는 기능들을 구현하고 있다.
본인은 포션 관련한 기능을 모두 작성하면, 게임을 계속 돌려보며 디자인적으로 계속 개선해보는 역할도 맡았다.
2. 오늘 학습에 대해
오전에는 Stack, Queue, 정렬알고리즘(Quick 등)에 대한 내용의 특강이 있었다. 해당 요소들을 코드적으로 어떻게 구현하는지가 주된 내용이었는데, --index 처럼 전위연산을 수행한다던가 하는 자잘한 스킬로 구현을 더 쉽게 하는 부분이 인상적이었다. 함께 정리를 하고싶지만, 밤이 늦어 일단 팀 과제에 대한 내용을 먼저 주로 작성. 특강에 관해서는 복습한다던가 하면 이 포스트에 추가 작성을 할 것 같다.
데미지 계산(일정 확률의 치명타, 일정 확률의 적 회피) 메서드 구현
데미지 계산 메서드를 어떻게 구현할지 고민을 많이 하였고, 계속 정제를 한 끝에 편의성 측면에서 나름 정답을 찾은 것 같아 구현을 깔끔하게 할 수 있었다.
public (bool, bool, int) CalculateExDamage(int originDamage, bool isSkill)
{
// 입력: 원래의 데미지, 스킬사용여부
// 반환: 치명타 성공 여부, 회피 여부, 실 데미지
// 반환값 목록 선언 및 초기화
bool isCritical = false;
bool isDodged = false;
int calculatedDamage = originDamage;
// 치명타 계산
Random random = new Random();
double chance = random.NextDouble();
if (chance <= 0.15) // 15% 의 확률로 치명타 발생
{
isCritical = true;
calculatedDamage = (int)(originDamage * 1.6f); // 160% 데미지
}
// 회피 계산
chance = random.NextDouble();
if (chance <= 0.1 && !isSkill) // 스킬공격이 아닐 시, 10% 의 확률로 회피
{
isDodged = true;
calculatedDamage = 0; // 0의 데미지
}
return (isCritical, isDodged, calculatedDamage);
// (bool val1, bool val2, int val3) = player.CalculateExDamage(originDamage, isSkill); 와 같이 사용
}
계산된 데미지 수치 이외에도, 치명타가 터지거나 적 몬스터가 회피할 경우 전투 장면 내에 이와 관련한 텍스트를 보여주어야 했기 때문에, isCritical 과 isDodged 의 반환도 필요했다. 즉 여러 개의 변수를 한번에 리턴하고 싶은상황.
이러한 경우, 소괄호를 사용하여 return (값1, 값2, 값3); 과 같이 튜플값의 반환을 해 주는 걸로 해결을 할 수 있었다.
매개변수로는 int의 기본공격력, bool의 스킬사용여부를 받아와, 두 변수로부터 치명타와 회피를 계산하도록 하였다.
전투 장면에서는 아래 코드처럼 메서드를 호출, 세 개의 변수에 대입하여 사용 할 수 있다.
(bool isCrit, bool isDodge, int calculatedDamage) = player.CalculateExDamage(originDamage, isSkill);
포션 클래스 및 관련 기능 작성
Item을 상속받는 Potion 클래스를 아래와 같이 작성했다.
class Potion : Item
{
public int heal { get; private set; }
public int count { get; private set; }
public Potion(int id, string name, string desc, int price, int heal) : base(id, name, "체력회복", desc, price)
{
this.heal = heal;
this.count = 3;
}
public void UsePotionOnDungeon()
{
// 포션 사용 구현.
// 선택1. 플레이어 객체를 함께 받아, player.Hp += heal;
// 선택2. heal값을 반환하여 장면 내에서 구현하기
// 2번 선택. 이유가 있었는데, 밥먹다가 망각함... 곧 작성.
}
public void UsePotionOnInventory() => count--;
public void GetPotion(int n) => count += n;
}
메인 메뉴에서 포션을 사용할 시에는 UsePotionOnInventory(), 던전 내에서 포션을 사용할 시에는 UsePotionOnDungeon() 의 메서드를 사용하도록 설계하였다. 현재 계속 구현 중인 부분이라 미완성이다.
메인메뉴의 '회복 아이템' 메뉴로 진입하면 아래와 같은 사양의 장면을 구성한다.
즉 당장 요구되는 사양으로는 한 종류의 포션만 구현하는 것.
그렇기 때문에, items 배열에는 Potion클래스를 갖는 객체는 현재로써는 유일하기 때문에, 아래와 같이 FirstOrDefault() 메서드를 활용하여 포션 객체참조를 하였다.
// 정말 만약에 Potion 객체가 shop.items에 없을 경우를 위해 대비한 로직
// 참조 타입 변수에 null이 할당될 가능성이 있을 때 나오는 경고문 때문에 아래와 같이 라인 수 많아짐.
Potion? potion = shop.items.OfType<Potion>().FirstOrDefault();
if (potion != null)
{
Console.WriteLine($"포션을 사용하면 체력을 30 회복 할 수 있습니다. (남은 포션 : {potion.count}개)");
}
else
{
Console.WriteLine("게임에 포션이 구현되지 않아 갯수를 표시 할 수 없습니다.");
}
또한 아래와 같이 두줄 작성도 가능하긴 하였지만, 위 코드의 주석에도 적혀있듯 참조 타입 변수에 null이 할당 될 가능성이 있으면 보기 좋지 않은 경고문이 나오기 때문에 코드가 길어지더라도 위와 같이 작성하였다.
또한 아래처럼 작성하더라도 items에 Potion객체가 하나도 없다면 "0"을 출력할 것이기 떄문에 큰 문제는 없을 것으로 보인다.
Potion potion = items.OfType<Potion>().FirstOrDefault();
Console.WriteLine($"{(potion != null ? potion.count.ToString() : "0")}")
이외로는 사양에 맞추어 여러 조건식에 따라 기능을 구현한 내용이 대부분이기 때문에 이 정도로 마무리.
3. 과제에 대해
필수 구현 사양은 모두 만족한 것으로 보이고, 선택 구현사항을 각자 또 정하여 구현중에 있다. 큰 문제는 없을것으로 보여 계속 기능을 넣고 점검을 하며 완성도를 높이는 것이 좋겠다.
4. 참고자료
없음
'다이어리 > 내일배움 개발일지' 카테고리의 다른 글
게임개발캠프 - 팀과제(B) 4일차 (2) | 2024.01.12 |
---|---|
게임개발캠프 - 팀과제(B) 3일차 (0) | 2024.01.11 |
게임개발캠프 - 팀과제(B) 1일차 (0) | 2024.01.10 |
게임개발캠프 - 개인과제(A) 6일차, 과제 제출 (0) | 2024.01.08 |
게임개발캠프 - 개인과제(A) 5일차 (0) | 2024.01.05 |