[Canvas-불꽃놀이-10] 불꽃놀이 꼬리의 위치와 속도 구현

이전 글 : [Canvas-불꽃놀이-09] 파티클 관리와 객체 폴링

 

[Canvas-불꽃놀이-09] 파티클 관리와 객체 폴링

이전 글 : [Canvas-불꽃놀이-08] 애니메이션 기본 틀잡기 [Canvas-불꽃놀이-08] 애니메이션 기본 틀잡기이전 글 : 2024.11.18 - [개발/Canvas] - [Canvas-불꽃놀이-07] 불꽃놀이 Particle들의 부모 클래스 [Canvas-불

jinsk-joy.tistory.com

 

불꽃놀이 꼬리 구현하기 (x 좌표값들과 속도)

이제 기본적인 토대는 다 완성이 되었으므로 세부적인 구현에 들어가고자 한다.

먼저 불꽃의 꼬리 구현부터 시작하겠다.

  • 꼬리의 개수는 5개이며 중앙에 1개, 왼쪽 2개, 오른쪽 2개에서 미리 정의된 x좌표 배열과 y 속도 배열을 기반으로 생성된다.
  • 꼬리는 시각적인 안정화를 위해 프레임 카운트를 기준으로 일정한 간격을 두고 생성된다.
  • 꼬리가 소멸되면 텍스트 파티클과 원형 파티클이 이어서 생성된다.

1. x 좌표 위치 생성

  • 중앙의 x 좌표는 CanvasOption의 mainX 를 사용한다.
  • 중앙을 기준으로 일정 거리는 꼬리 생성에 제외한다.
    -. 반응형을 고려하여 모바일과 모바일 이외를 구분하여 제외 거리를 다르게 적용한다.
    -. 왼쪽 : width 시작 기준 ~ (중앙 - 제외거리) 안에서 동일한 간격으로 5개
    -. 오른쪽 : (중앙 + 제외거리) ~ width 종료 기준 안에서 동일한 간격으로 5개
  • 필요한 상수 추가
// constants.js
export const TAIL = {
    BASE_QTY: 5,		// 기본 수량
    SMALL_EXCLUSION: 75,	// 모바일 화면 제외 거리
    EXCLUSION: 150,		// 모바일 화면 외 제외 거리
    START_X_RATIO: 0.15,	// left x좌표 시작점
}

 

  • 꼬리의 x 좌표 관련 멤버 변수 초기화
// Canvas.js
initCanvasVars() {
    // 생략...
    
    this.tailQty = TAIL.BASE_QTY;
    this.tailsLeftPosX = [];
    this.tailsRightPosX = [];
}

 

  • 꼬리의 x좌표 값들 생성
// Canvas.js
createTailPosX() {
    // 좌표 배열의 길이
    const length = this.tailQty;
    
    // 중앙에서 제외할 거리
    const exclusionDist = this.isSmallScreen ? TAIL.SMALL_EXCLUSION : TAIL.EXCLUSION;
    
    // left x좌표 시작점
    const leftStart = this.canvasCssWidth * TAIL.START_X_RATIO;
    
    // left x좌표 종료점
    const leftEnd = this.mainX - exclusionDist;
    
    // right x좌표 시작점
    const rightStart = this.mainX + exclusionDist;
    
    // x좌표를 생성할 간격 (균등 분포를 위해 종료 위치와 시작위치의 차이를 나눔)
    // 간격을 계산할때 오른쪽 부분을 같이 계산하지 않는 이유는 xOffset이 왼쪽과 동일하게 적용되기 때문이다.
    const xOffset = (leftEnd - leftStart) / (length - 1);

    // 좌표 배열 생성하여 대입
    this.tailsLeftPosX = Array.from({ length }, (_, i) => Math.floor(leftStart + i * xOffset));
    this.tailsRightPosX = Array.from({ length }, (_, i) => Math.floor(rightStart + i * xOffset));
}

2. y 좌표의 속도값 생성

x좌표의 위치를 생성했으면 이제 y좌표의 속도값을 생성해야 한다.

  • 중앙의 꼬리의 속도는 항상 같은 속도를 가진다.
  • 나머지 꼬리의 속도는 배열로 만들어 동일한 간격으로 설정된다.
  • 필요한 상수를 추가하고 중앙을 제외한 나머지 속도 배열 생성 
    -. 캔버스 높이 위치에서 출발하므로 아래에서 위로 출발하는 모양이기 때문에 MIN이 MAX보다 더 커야 한다.
// constants.js
export const TAIL = {
    // 생략...
    
    MIN_Y_RATIO: 0.7,	// 꼬리가 올라갈 수 있는 가장 낮은 높이 (화면 높이의 70%)
    MAX_Y_RATIO: 0.3,	// 꼬리가 올라갈 수 있는 가장 높은 높이 (화면 높이의 30%)
};

 

  • y의 속도를 계산하는 공통 함수 구현 
    -. 속도는 거리 / 시간 공식으로 계산된다.
    -. 아래에서 위로 이동하기 때문에 음수값으로 설정한다.
// Canvas.js
// 캔버스 하단에서 출발하기 때문에 마이너스 속력을 가져야 하므로
// 설정한 높이에서 캔버스 height을 빼줘야 아래에서 위로 올라가는 속도를 가지게 된다.
calculateTailVY(yPos) {
    return (yPos - this.canvasCssHeight) / this.interval;
}

 

  • 중앙 속도와 나머지 속도를 계산하여 멤버 변수에 대입한다.
// Canvas.js
// CanvasOption에서 설정한 main이 되는 y의 좌표값을 전달해 속도를 산출한다.
this.mainTailVY = this.calculateTailVY(this.mainY);
// Canvas.js
createTailVY() {
    // y속도 배열의 길이
    const length = this.tailQty;
    
    // 최저 속도
    const minTailVY = this.calculateTailVY(this.canvasCssHeight * TAIL.MIN_Y_RATIO);
    
    // 최고 속도
    const maxTailVY = this.calculateTailVY(this.canvasCssHeight * TAIL.MAX_Y_RATIO);
    
    // 속도간의 간격을 계산 (균등 분포를 위해 최고 속도와 최저 속도의 차이를 나눔)
    const vyOffset = (maxTailVY - minTailVY) / (length - 1);

    // 속도 배열 생성
    this.tailsVY = Array.from({ length }, (_, i) => minTailVY + i * vyOffset);
}

3. Canvas를 초기화 시 tail의 x 좌표 값들과 속도값들을 생성

  • 불꽃놀이 화면으로 전환하거나 브라우저 크기가 변경되면 꼬리의 위치와 속도도 달라지므로 다시 계산해야 한다.
  • 그러므로 init 메서드에서 꼬리의 위치와 속도값을 저장하고 이와 관련된 메서드를 실행한다.
// Canvas.js
init() {
    super.init();

    // 생략...
    
    // tail 생성에 필요한 값들 초기화
    this.mainTailVY = this.calculateTailVY(this.mainY);
    this.createTailPosX();
    this.createTailVY();
}

 

Github 링크
 

GitHub - jinsk9268/text-fireworks

Contribute to jinsk9268/text-fireworks development by creating an account on GitHub.

github.com