You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
이번 예제에서 가장 중요하게 생각한 부분은 프레임 수가 아닌 시간을 기준으로 이동하는 것입니다.
프레임마다 고정된 거리만큼 로고를 이동하면 컴퓨터 성능이나 렌더링 엔진에 따라 이동 속도가 달라질 수 있습니다. 반면 속도에 실제로 지난 시간을 곱하면 FPS가 달라져도 로고가 비슷한 속도로 움직입니다.
충돌 처리에서는 속도의 방향만 변경하지 않고 로고의 위치도 경계 안으로 함께 보정했습니다. 이를 통해 순간적으로 프레임 간격이 커져도 로고가 화면 밖에 남거나 벽을 뚫고 지나가는 문제를 방지했습니다.
또한 속도에 단순히 -1을 곱해 방향을 토글하지 않았습니다. 왼쪽 벽에서는 std::abs()로 속도를 항상 오른쪽 방향으로, 오른쪽 벽에서는 -std::abs()로 항상 왼쪽 방향으로 고정했습니다. 위쪽과 아래쪽 벽도 같은 방식으로 화면 안쪽을 향하도록 처리했습니다. 따라서 접촉 상태가 연속된 프레임에서 두 번이나 세 번 판정되더라도 속도가 매번 반대로 뒤집히지 않고, 로고는 계속 화면 안쪽으로 이동합니다.
또한 이동 상태, 사각형 충돌, 로고 렌더링, Canvas 갱신의 책임을 각각 Object, Rect, Logo, UserExample로 나눴습니다. 작은 예제지만 각 구조체가 담당하는 역할을 구분해 애니메이션의 흐름을 쉽게 확인할 수 있도록 했습니다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
예제 만들어보기
1주차에는 ThorVG와 예제 프로젝트를 빌드하고 실행할 수 있는 작업 환경을 구성했습니다.
이번에는 구축한 환경을 이용해 새로운 예제를 직접 만들어보겠습니다. 과거 DVD 화면 보호기처럼 로고가 화면 안을 대각선으로 이동하고, 벽에 부딪히면 진행 방향과 색상이 바뀌는 예제입니다.
1. 예제 실행 화면
로고는 화면 안을 일정한 속도로 움직입니다. 화면 가장자리에 도달하면 반대 방향으로 튕겨 나오며, 충돌 여부를 쉽게 확인할 수 있도록 로고의 색상도 함께 변경됩니다.
완성된 Bounce 예제의 실행 화면은 아래 영상에서 확인할 수 있습니다.
ThorVG.Bounce.Example.mp4
코드 설명
1. 움직이는 객체 구조 정의
움직이는 객체가 공통으로 갖는 위치와 속도는
Object가 관리합니다.Rect는Object를 상속받고 사각형 충돌 판정에 필요한 정보를 추가하며 이를Logo가 상속받아 사용합니다.구조를 정리하면 다음과 같습니다.
Object: 위치와 속도 관리Rect: 크기와 사각형 충돌 처리Logo: ThorVG로 그릴 로고 관리2. 로고 이동과 충돌 처리
로고의 새로운 위치는 현재 위치에
속도 × 지난 시간을 더해 계산합니다.이후 로고의 위치와 크기를 Canvas 크기와 비교해 충돌을 확인합니다. 다음은 왼쪽 벽과 충돌했을 때의 처리입니다.
충돌 시 속도의 방향만 바꾸고 위치를 보정하지 않으면 프레임 간격이 커졌을 때 로고 일부가 화면 밖에 남을 수 있습니다. 따라서 위치를
0.0f로 보정하고, X축 속도를 항상 오른쪽을 향하는 양수로 변경합니다.오른쪽, 위쪽, 아래쪽 벽도 같은 방식으로 위치를 화면 안으로 보정한 뒤 속도의 방향을 변경합니다. X축과 Y축을 각각 검사하기 때문에 로고가 모서리에 닿았을 때도 두 방향을 함께 처리할 수 있습니다.
3. ThorVG 로고 만들기
Logo는Rect를 상속받아 이동과 충돌 기능을 사용하고, 로고를 그리기 위한 이름과 ThorVG 객체를 추가로 관리합니다.생성자에는 이름, 위치, 속도, 크기의 기본값을 지정했습니다. 현재 예제에서는
Logo logo;만으로 사용할 수 있지만, 필요하다면 생성자 인자를 전달해 다른 이름이나 움직임을 가진 로고도 만들 수 있습니다.로고는 둥근 사각형 배경과 텍스트를 하나의
Scene에 추가해 구성했습니다.텍스트를 로고 중앙에 배치하기 위해
bounds()로 실제 텍스트 영역을 구한 뒤 위치를 계산합니다.배경과 텍스트를 각각 Canvas에 추가하지 않고 하나의
Scene으로 묶었기 때문에, 로고가 이동할 때는 Scene 전체의 위치만 변경하면 됩니다.4. 충돌할 때 색상 변경하기
벽과의 충돌을 시각적으로 쉽게 확인할 수 있도록 여러 색상을 배열로 준비했습니다.
충돌할 때마다 다음 색상을 선택하고, 마지막 색상 이후에는 다시 처음으로 돌아갑니다.
5. Canvas에 콘텐츠 추가하기
기존 예제를 참고하여
tvgexam::Example을 상속한UserExample을 만들고content()와update()를 구현했습니다.content()에서는 폰트를 로드하고, Canvas 크기를 저장한 뒤 배경과 로고를 추가합니다.6. 프레임마다 애니메이션 갱신하기
update()가 전달받는elapsed는 예제가 시작된 후 흐른 누적 시간입니다. 이전 프레임의 시간을 저장해 두었다가 현재 값에서 빼면 두 프레임 사이의 시간 차이를 얻을 수 있습니다.밀리초 단위의 값을 초로 변환해
Rect::update()에 전달합니다. 창을 이동하거나 디버거에서 일시 정지했을 때 로고가 한 번에 크게 이동하는 것을 막기 위해 최대 시간 차이는0.05초로 제한했습니다.예제 설명과 구현 의도
이번 예제에서 가장 중요하게 생각한 부분은 프레임 수가 아닌 시간을 기준으로 이동하는 것입니다.
프레임마다 고정된 거리만큼 로고를 이동하면 컴퓨터 성능이나 렌더링 엔진에 따라 이동 속도가 달라질 수 있습니다. 반면 속도에 실제로 지난 시간을 곱하면 FPS가 달라져도 로고가 비슷한 속도로 움직입니다.
충돌 처리에서는 속도의 방향만 변경하지 않고 로고의 위치도 경계 안으로 함께 보정했습니다. 이를 통해 순간적으로 프레임 간격이 커져도 로고가 화면 밖에 남거나 벽을 뚫고 지나가는 문제를 방지했습니다.
또한 속도에 단순히
-1을 곱해 방향을 토글하지 않았습니다. 왼쪽 벽에서는std::abs()로 속도를 항상 오른쪽 방향으로, 오른쪽 벽에서는-std::abs()로 항상 왼쪽 방향으로 고정했습니다. 위쪽과 아래쪽 벽도 같은 방식으로 화면 안쪽을 향하도록 처리했습니다. 따라서 접촉 상태가 연속된 프레임에서 두 번이나 세 번 판정되더라도 속도가 매번 반대로 뒤집히지 않고, 로고는 계속 화면 안쪽으로 이동합니다.또한 이동 상태, 사각형 충돌, 로고 렌더링, Canvas 갱신의 책임을 각각
Object,Rect,Logo,UserExample로 나눴습니다. 작은 예제지만 각 구조체가 담당하는 역할을 구분해 애니메이션의 흐름을 쉽게 확인할 수 있도록 했습니다.참고사항
이번 예제에서 사용한 주요 ThorVG API는 다음과 같습니다.
tvg::Shape::gen()tvg::Shape::appendRect()tvg::Text::gen()tvg::Text::bounds()tvg::Scene::add()tvg::Paint::translate()tvg::Canvas::update()전체 코드는 GitHub의 Bounce.cpp에서 확인할 수 있습니다.
All reactions