Post

C++ - 어트리뷰트 시스템 설계 중

C++

C++ - 어트리뷰트 시스템 설계 중

어트리뷰트 시스템 설계 중

필요한 기능들

스탯 계산 및 관리

  • 각 스탯의 값을 계산하고 관리하는 기능이 필요함. ex) 스탯을 증가시키거나, 스탯의 변화를 적용하는 기능

스탯 간의 상호작용

  • 스탯들이 서로 영향을 주고받을 수 있도록 의존성 관리가 필요. ex) 특정 스탯이 높아지면 다른 스탯이 증가

장비 및 버프

  • 장비나 버프 등으로 인해 캐릭터의 스탯 값이 변할 수 있는 기능이 필요. 이러한 요소들이 스탯을 어떻게 변경하는지 관리해야 한다.

레벨업 및 성장

  • 캐릭터가 레벨업할 때 스탯 값이 증가하는 방식, 성장 시스템을 관리하는 기능이 필요. 각 캐릭터의 레벨업 시 스탯이 어떻게 증가할지를 설정할 수 있어야 한다.

현재로는 상속 방식으로 구현하는 것이 좋다고 생각한다.

기본적인 형태 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <unordered_map>
using namespace std;

class Stat
{
public:
    Stat(float initialValue = 0) : value(initialValue) {}
    virtual ~Stat() = default;

    virtual void ApplyModifier(float value) = 0;
    virtual float GetValue() const = 0;
    virtual void Increase(int value = 1) = 0;
    virtual void ApplyLevelUp(int level = 1) = 0;

protected:
    float value;
};

// 장비, 버프와 같이 캐릭터 스탯에 영향을 주는 요소들들
class StatModifier : public Stat
{
public:
	virtual void ApplyEffect(StatManager& manager) const abstract;
	virtual ~StatModifier() {}
};

class BuffModifier : public StatModifier
{
public:
    BuffModifier(float duration)
        : duration(duration) {}

    void ApplyEffect(StatManager& manager) const override
    {
        // 스탯에 버프 효과 적용
    }

    void Update(float deltaTime)
    {
        duration -= deltaTime;
        if (duration <= 0)
        {
            isExpired = true;
        }
    }

    bool IsExpired() const { return isExpired; }

private:
    float duration;
    bool isExpired = false;
};

class EquipmentModifier : public StatModifier
{
public:
    EquipmentModifier(const std::unordered_map<StatType, float>& effects)
        : effects(effects) {}

    void ApplyEffect(StatManager& manager) const override
    {
        for (const auto& [type, value] : effects)
        {
            auto stat = manager.GetStat(type);
            if (stat)
            {
                stat->ApplyModifier(value);
            }
        }
    }
};

enum class StatType
{
	HP,
	MP,
	STR,
	INT,
	LUCK,
	DEF
};

// 캐릭터마다 레벨 업 시 증가하는 스탯을 다르게 지정하기 위해 StatManager 기본 클래스 생성
class StatManager
{
public:
	StatManager() = default;
	~StatManager() = default;

	virtual void LevelUp() abstract;

	void IncreaseStatWithPoints(StatType type, int point = 1)
	{
		auto stat = GetStat(type);
		
		if (stat != nullptr)
		{
			stat->Increase(point);
		}
	}


	Stat* GetStat(StatType type)
	{
		if (stats.end() != stats.find(type))
		{
			return stats[type];
		}

		return nullptr;
	}


protected:
	unordered_map<StatType, Stat*> stats;
};

This post is licensed under CC BY 4.0 by the author.