-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUIBounceSystem.cpp
210 lines (188 loc) · 6.71 KB
/
UIBounceSystem.cpp
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include "pch.h"
#include "UIBounceSystem.h"
#include "VisPredComponents.h"
UIBounceSystem::UIBounceSystem(std::shared_ptr<SceneManager> scenemanager):System(scenemanager)
{
}
void UIBounceSystem::Update(float deltaTime)
{
COMPLOOP(ImageBounceComponent, bouncecomp)
{
if (!bouncecomp.HasImage)
continue;
if (bouncecomp.AddedBounce)
SettingBounce(bouncecomp);
if (!bouncecomp.Isbouncing)
continue;
auto image = bouncecomp.GetComponent<ImageComponent>();
// BounceProgress 업데이트 (델타 시간을 더해 진행률을 조절)
bouncecomp.BounceProgress += deltaTime;
// BounceReturn 함수로 특정 시점 이후 CommonScale로 복귀
float currentScale= bouncecomp.CommonScele;
double BounceProgress = static_cast<double>(bouncecomp.BounceProgress);
double BouncingTime = static_cast<double>(bouncecomp.BouncingTime);
double BounceTimePercent = static_cast<double>(bouncecomp.BounceTimePercent);
double percent = BouncePercent(BounceProgress, BouncingTime, BounceTimePercent);
if (!BounceReturn(BounceProgress, BouncingTime, BounceTimePercent))
// BounceTimePercent 이하일 때는 Bounce 진행
currentScale = Lerp(bouncecomp.StartScale, bouncecomp.EndScale, percent);
else
// BounceTimePercent 초과 시 CommonScale로 돌아가는 보간
currentScale = Lerp(bouncecomp.CommonScele,bouncecomp.EndScale, percent);
// 곡선 기반의 percent로 스케일 보간
image->Scale = currentScale;
// bounce 진행이 완료되면 초기화
if (bouncecomp.BounceProgress > bouncecomp.BouncingTime)
{
bouncecomp.Isbouncing = false;
bouncecomp.BounceProgress = 0.0f;
bouncecomp.StartScale = {};
bouncecomp.EndScale = {};
image->Scale = bouncecomp.CommonScele; // 원래 스케일로 복원
}
}
// Text Bounce Update (similar to Image Bounce)
COMPLOOP(TextBounceComponent, bouncecomp)
{
if (!bouncecomp.HasText)
continue;
if (bouncecomp.AddedBounce)
SettingBounce(bouncecomp);
if (!bouncecomp.Isbouncing)
continue;
auto text = bouncecomp.GetComponent<TextComponent>();
// BounceProgress 업데이트 (델타 시간을 더해 진행률을 조절)
bouncecomp.BounceProgress += deltaTime;
// BounceReturn 함수로 특정 시점 이후 CommonScale로 복귀
float currentScale = bouncecomp.CommonScele;
double BounceProgress = static_cast<double>(bouncecomp.BounceProgress);
double BouncingTime = static_cast<double>(bouncecomp.BouncingTime);
double BounceTimePercent = static_cast<double>(bouncecomp.BounceTimePercent);
double percent = BouncePercent(BounceProgress, BouncingTime, BounceTimePercent);
if (!BounceReturn(BounceProgress, BouncingTime, BounceTimePercent))
// BounceTimePercent 이하일 때는 Bounce 진행
currentScale = Lerp(bouncecomp.StartScale, bouncecomp.EndScale, percent);
else
// BounceTimePercent 초과 시 CommonScale로 돌아가는 보간
currentScale = Lerp(bouncecomp.CommonScele, bouncecomp.EndScale, percent);
// 곡선 기반의 percent로 스케일 보간
text->Scale = currentScale;
// bounce 진행이 완료되면 초기화
if (bouncecomp.BounceProgress > bouncecomp.BouncingTime)
{
bouncecomp.Isbouncing = false;
bouncecomp.BounceProgress = 0.0f;
bouncecomp.StartScale = {};
bouncecomp.EndScale = {};
text->Scale = bouncecomp.CommonScele; // 원래 스케일로 복원
}
}
}
void UIBounceSystem::SettingBounce(ImageBounceComponent& bouncecomp)
{
// Bouncing 시작 설정
bouncecomp.Isbouncing = true;
auto text = bouncecomp.GetComponent<ImageComponent>();
bouncecomp.BounceProgress = 0;
// StartScale과 EndScale 설정
bouncecomp.StartScale = text->Scale;
bouncecomp.EndScale = bouncecomp.StartScale + bouncecomp.AddScale;
// MaxScale 제한 적용
if (bouncecomp.EndScale > bouncecomp.MaxScale)
bouncecomp.EndScale = bouncecomp.MaxScale;
bouncecomp.AddedBounce = false;
}
void UIBounceSystem::SettingBounce(TextBounceComponent& bouncecomp)
{
// Bouncing 시작 설정
bouncecomp.Isbouncing = true;
auto text = bouncecomp.GetComponent<TextComponent>();
bouncecomp.BounceProgress = 0;
// StartScale과 EndScale 설정
bouncecomp.StartScale = text->Scale;
bouncecomp.EndScale = bouncecomp.StartScale + bouncecomp.AddScale;
// MaxScale 제한 적용
if (bouncecomp.EndScale > bouncecomp.MaxScale)
bouncecomp.EndScale = bouncecomp.MaxScale;
bouncecomp.AddedBounce = false;
}
void UIBounceSystem::Initialize()
{
COMPLOOP(ImageBounceComponent, bouncecomp)
{
Start(bouncecomp.GetEntityID());
}
COMPLOOP(TextBounceComponent, bouncecomp)
{
Start(bouncecomp.GetEntityID());
}
}
void UIBounceSystem::Start(uint32_t gameObjectId)
{
if (GetSceneManager()->HasComponent< ImageBounceComponent>(gameObjectId))
{
auto bouncecomp = GetSceneManager()->GetComponent< ImageBounceComponent>(gameObjectId);
if (bouncecomp->HasComponent<ImageComponent>())
{
bouncecomp->HasImage = true;
auto image = bouncecomp->GetComponent<ImageComponent >();
bouncecomp->CommonScele = image->Scale;
bouncecomp->AddScale = image->Scale * bouncecomp->AddScalePercent / 100.f;
bouncecomp->MaxScale = bouncecomp->CommonScele + (bouncecomp->CommonScele * bouncecomp->MaxScalePercent / 100.f);
}
}
if (GetSceneManager()->HasComponent< TextBounceComponent>(gameObjectId))
{
auto bouncecomp = GetSceneManager()->GetComponent< TextBounceComponent>(gameObjectId);
if (bouncecomp->HasComponent<TextComponent>())
{
bouncecomp->HasText = true;
auto text = bouncecomp->GetComponent<TextComponent >();
bouncecomp->CommonScele = text->Scale;
bouncecomp->AddScale = text->Scale * bouncecomp->AddScalePercent / 100.f;
bouncecomp->MaxScale = bouncecomp->CommonScele + (bouncecomp->CommonScele * bouncecomp->MaxScalePercent / 100.f);
}
}
}
float UIBounceSystem::Lerp(float start, float end, float percent)
{
return start + percent * (end - start);
}
double UIBounceSystem::BouncePercent(double progress, double bounceTime, double bounceTimePercent)
{
// bounceTimePercent 값을 0과 1 사이의 값으로 변환
double b = bounceTimePercent / 100.0;
// progress 값이 0 이하일 경우 0 반환
if (progress <= 0)
return 0.0f;
if (progress < bounceTime * b)
{
// 첫 번째 절반: 스케일 증가 (아래로 볼록한 포물선)
double delta = progress - bounceTime * b;
return -(delta * delta) / (b * b * bounceTime * bounceTime) + 1;
}
else if (progress >= bounceTime)
{
// bounceTime을 초과한 경우, 원래 스케일로 복원
return 0.0;
}
else
{
// 두 번째 절반: 스케일 감소 (위로 볼록한 포물선)
double delta = progress - bounceTime;
return (delta * delta) / ((1 - b) * (1 - b) * bounceTime * bounceTime);
}
}
bool UIBounceSystem::BounceReturn(double progress, double totalBounceTime, double bounceTimePercent)
{
// BounceTimePercent 값을 0과 1 사이의 값으로 변환
double threshold = bounceTimePercent / 100.0f;
// progress가 기준 시간을 초과했는지 확인
return (progress >= totalBounceTime * threshold);
}
void UIBounceSystem::Finish(uint32_t gameObjectId)
{
}
void UIBounceSystem::Finalize()
{
}