[패스트캠퍼스] 챌린지 9일차 2.28

2023. 2. 28. 22:58개발 일지/패스트캠퍼스\챌린지

Part2. Canvas 챕터 02 - 5 꼬리(Tail class) 만들기 강의 시작! 
 

강의 시작!

지난 강의에는 폭죽이 터졌을 때, 불꽃이 퍼져나는 파티클을 만드는 방법을 알아봤다. 이번 시간에는 파티클이 시작하자마자 터지는 것이 아니라 꼬리가 발사되어 화면 어느지점에서 꼬리가 사라지면 파티클이 터지는 효과를 만들는 방법을 알아본다.
 
우선 js폴터에 Tail.js 파일을 만들고 CanvasOption을 상속받는 Tail class를 export default로 선언한다. 그리고 x, vy, color를 인자로 받는 construct를 선언하고 멤버 편수들을 할당하는 로직을 구현한다.
그리고 update 함수에서 y의 값이 vy값을 더해주도록 구현하고 draw함수에서 꼬리를 그려주는 로직을 구현한다.
아래는 Tail.js의 코드이다.

import CanvasOption from "./CanvasOption.js";

export default class Tail extends CanvasOption  {
    constructor(x, vy, color){
        super();
        this.x = x;
        this.y = this.canvasHeight;
        this.vy = vy;
        this.color = color;
    }

    update() {
        this.y += this.vy;
    }

    draw() {
        this.ctx.fillStyle = this.color;
        this.ctx.beginPath();
        this.ctx.arc(this.x, this.y, 1, 0, Math.PI * 2);
        this.ctx.fill();
        this.ctx.closePath();
    }
}

그리고 Tail들을 관리하기 위해서 particles 와 같이 tails 배열을 선언해주고 createTail 함수를 선언하여 Tail을 생성하는 로직을 구현해준다. 이 crateTail 함수는 render함수 안의 frame 함수 안에서 실행을 해주는데, 그냥 실행하게 되면 매 프레임 마다 Tail을 생성하기 때문에 Math.random 함수를 사용해서 0.03(강의에서는 0.03이지만 조절해도 된다.)보다 작은 수가 나오면 실행하도록 하게 되면 Tail이 적당한 수로 생성이 된다.
그리고 Tail이 멈춘 곳에서 Tail이 사라지면서 폭죽이 터지도록 만들기 위해서 Tail의 vy의 값을 확인해서 -1보다 작을 경우에 tails에서 제거하고 createParticles를 실행하게 하면 Tail이 사라지면서 폭죽이 터지는 것을 확인할 수 있다. 다만 기존의 createParticles는 x,y의 값이 랜덤하게 생성되기 때문에 Tail의 x와 y의 값을 전달해줘서 사라진 Tail의 위치에서 폭죽이 터지도록 수정을 해주면 폭죽이 올라가 터지는 효과를 확인할 수 있다. 그리고 Particle class의 constructor가 color를 인자로 받을 수 있도록 추가해 주고 draw 함수 안에 있는  ctx fillStyle의 값을 rgba(${this.color), ${this.opacity) 로 수정해준다.
아래는 index.js를 수정한 코드의 일부분이다.

...
import Tail from "./js/Tail.js";
...

class Canvas extends CanvasOption {
    constructor() {
    	...
        this.tails = []
        ...
    }
    ...
    createTail() {
        const x = randomNumBetween(this.canvasWidth * 0.2, this.canvasWidth * 0.8);
        const vy = this.canvasHeight * randomNumBetween(0.01, 0.015) * -1;
        const color = '255, 255, 255';
        this.tails.push(new Tail(x, vy, color));
    }
	
    createParticles(x, y, color) {
        const PARTICLE_NUM = 400;
        for (let i = 0; i < PARTICLE_NUM; i++){
            const r = randomNumBetween(2, 100) * hypotenuse(innerWidth, innerHeight) * 0.0001;
            const angle = Math.PI / 180 * randomNumBetween(0, 360);
            const vx = r * Math.cos(angle);
            const vy = r * Math.sin(angle);
            const opacity = randomNumBetween(0.6, 0.9)
            this.particles.push(new Particle(x, y, vx, vy, opacity, color));
        }
    }

    render() {
        let now, delta;
        let then = Date.now();

        const frame = () => {
        	...
            if (Math.random() < 0.03) this.createTail();

            this.tails.forEach((tail, index) => {
                tail.update();
                tail.draw();

                if(tail.vy > -1){
                    this.tails.splice(index, 1);
                    this.createParticles(tail.x, tail.y, tail.color);
                }
            })
            ...
        }
    }

}
...

마지막으로 일직선으로 올라가는 Tail이 밋밋하기 때문에 우리가 상상하는 불꽃놀이의 꼬리가 올라가는 흔들거리는 꼬리를 만들기 위해서 Tail class를 수정해준다.
Tail이 좌우로 흔들거리며 올라가려면 좌우로 -1 ~ 1 사이로 움직이면 된다. 이렇게 일정하게 움직이게 하기 위해서 삼각함수를 이용하면 되는데 -1 ~ 1 사이로 값이 일정하게 변화하는 함수는 sin or cos 함수이다. 이를 이용하여 x의 값에 변화를 주면 Tail이 흔들거리며 올라가는 모습을 확인할 수 있다.
아래는 수정된 Tail class 코드이다.

...
import { randomNumBetween } from "./utils.js";

export default class Tail extends CanvasOption  {
    constructor(x, vy, color){
        ...
        this.angle = randomNumBetween(0, 2);
        ...
    }

    update() {
    	...
        this.angle += 0.3;
        this.x += Math.cos(this.angle) * this.vy * 0.2;
        this.opacity = -this.vy * 0.1;
    }

    draw() {
        this.ctx.fillStyle = `rgba(${this.color}, ${this.opacity})`;
        ...
    }
}

결과를 보면 흔들거리며 올라가다 점점 사라지다가 끝에 폭죽이 터지는 효과를 확인 할 수 있다.
 

강의 결과물

http://bit.ly/3Y34pE0

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.