2023. 2. 27. 15:34ㆍ개발 일지/패스트캠퍼스\챌린지
Part2. Canvas 챕터 02 - 4 불꽃놀이 원 모양으로 랜덤 파티클 만들어보기 강의 시작!
이전 강의에서 만든 폭죽 파티클은 네모난 모양으로 퍼져나갔다. 이번 강의에서는 우리가 알고 있는 원모양으로 퍼져나가는 폭죽 파티클을 만드는 방법을 알아본다.
우선 네모난 방향으로 폭죽 파티클이 퍼져나는 이유를 알아보면, 파티클이 프레임마다 퍼져나가는 방향에 대해서 vx와 vy가 -5~5 사이의 값을 갖도록 구현을 했다. 이를 좌표평면에 그려보면 사각형 모양으로 그려지고 우리는 그 모양대로 폭죽 파티클이 퍼져나가는 것을 알 수 있다.
우리는 동그란 모양으로 퍼져나가길 원하기 때문에 좌표평면에서 원을 그렸을 때, 우리가 vx와 vy에 넣어줄 값을 어떻게 구할지 확인 할 수 있다. 여기서 필요한 것은 삼각함수이다. 특정한 값을 구하게 되면 우리는 삼각함수의 cosθ, sinθ 를 활용해서 구할 수 있게 된다.
아래는 삼각함수를 활용하여 수정한 코드이다.
...
createParticles() {
const PARTICLE_NUM = 2000;
const x = randomNumBetween(0, this.canvasWidth);
const y = randomNumBetween(0, this.canvasHeight);
for (let i = 0; i < PARTICLE_NUM; i++){
const r = randomNumBetween(0, 3);
const angle = Math.PI / 180 * randomNumBetween(0, 360);
const vx = r * Math.cos(angle);
const vy = r * Math.sin(angle);
this.particles.push(new Particle(x, y, vx, vy));
}
}
...
그리고 확인을 하면 원모양으로 파티클이 퍼져나가는 것을 확인 할 수 있다. 여기서 파티클의 갯수를 2000개에서 적당히 줄인 후에 파티클의 반지름 크기를 10에서 2정도로 줄이면 좀더 작고 얘쁘게 퍼지는 폭죽 파티클을 확인할 수 있다. 하지만 이렇게 하더라도 폭죽 파티클이 어색하기 때문에 폭죽이 터지면서 내려오도록 Particle class에서 중력과 점점 느려지는 계산을 구현해줘야 한다.
우선 constructor에 gravity와 friction을 선언해주고 update에서 vy 에 gravity를 더해주고 vx와 vy에 friction을 곱해줘 점점 느려지는 효과를 구현해준다. 그리고 동시에 파티클들이 사라지는 것을 opacity의 랜덤값을 줘서 서로 다른 타이밍에 사라지도록 Particle의 constructor가 opacity를 받도록 수정해주고 createParticles에서 opacity를 랜덤값으로 할당해주고 Particle을 생성할 때, 마지막 인자로 opacity를 넣어주면 생성된 파티클들이 각각 다른 타이밍에 사라지는 모습을 확인 할 수 있다.
...
export default class Particle extends CanvasOption{
constructor(x, y, vx, vy, opacity){
...
this.opacity = opacity;
this.gravity = 0.12;
this.friction = 0.93;
}
update() {
this.vy += this.gravity;
this.vx *= this.friction;
this.vy *= this.friction;
...
}
...
createParticles() {
...
for (let i = 0; i < PARTICLE_NUM; i++){
const r = randomNumBetween(2, 100) * 0.2;
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));
}
}
...
그리고 render함수에서 배경색을 검은색으로 칠해주는 fillStyle의 값 this.bgColor에 + '10' 같이 알파값을 추가해주면 알파값과 함께 배경색이 칠해지기 때문에 파티클들이 바로 지워지지 않고 잔상이 남는 것처럼 보여진다. 그리고 마지막으로 작업할 것은 화면의 크기에 따라서 퍼지는 크기가 화면 크기에 따라서 조절이 되도록 구현을 해본다.
파티클의 퍼지는 범위는 파티클들을 생성할때 r값에 따라서 정해지는 r의 값을 화면 크기에 따라서 조절을 하려면 피타고라스의 정리를 활용하여 화면의 가로, 세로의 길이에 따라 빗변의 길이를 구해 r의 값을 할당해주면 된다.
아래는 r의 값과 배경색을 칠해주도록 수정한 코드이다.
export const hypotenuse = (x, y) => {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
...
import { randomNumBetween, hypotenuse } from "./js/utils.js";
...
createParticles() {
...
for (let i = 0; i < PARTICLE_NUM; i++){
const r = randomNumBetween(2, 100) * hypotenuse(innerWidth, innerHeight) * 0.0001;
...
}
}
render() {
...
const frame = () => {
...
this.ctx.fillStyle = this.bgColor + '40';
...
}
...
}
...
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
'개발 일지 > 패스트캠퍼스\챌린지' 카테고리의 다른 글
[패스트캠퍼스] 챌린 10일차 3. 1 (0) | 2023.03.01 |
---|---|
[패스트캠퍼스] 챌린지 9일차 2.28 (0) | 2023.02.28 |
[패스트캠퍼스] 챌린지 7일차 2. 26 (0) | 2023.02.26 |
[패스트캠퍼스] 챌린지 6일차 2.25 (0) | 2023.02.25 |
[패스트캠퍼스] 챌린지 5일차 2.24 (0) | 2023.02.24 |