오늘은 드디어~~네! 드디어~~와우!
화염을 만들어 보~겠~습~니~다~~~^^*
아래 동영상 강의를 클릭하시면 오늘 공부 내용을 바로 시작(8:15)하실 수 있어요~^^*
어제 우리는~~^^*,
일전에 코드로 만들어 놓았던 동그라미 입자 이미지를 (32*32) 크기로 줄여서, 빗방울 입자 이미지로 사용을 했었지요~^^*
let this.lifetime = 255;
tint(255, this.lifetime);
this.lifetime -= 5;
로 코드를 짜서, 흰색 255 +불투명도 255로 초기 설정을 하여, 시간이 지남에 따라, 불투명도 this.lifetime을 줄여 나갔어요~
오늘 우리는~~^^*,
let this.lifetime = 255;
tint(255, 5, 5, this.lifetime);
this.lifetime -= 5;
로 코드를 짜서, 붉은 느낌이 강한 색(255, 5, 5) + 불투명도 255로 초기 설정을 하여, 불투명도 this.lifetime을 줄여 나갈게요~
아 네 네!!!
음~~왜 그냥 붉은 색(255, 0, 0)을 사용하지 않고 붉은 느낌의 색 (255, 5, 5)사용하는 지 궁금하시다고요?
어머 그러네요…. 흠…왜 그럴까요….???
참! 그런데요~~!!!
불꽃은 안쪽 부분이 많이 밝아 보이잖아요~~^^*
그 느낌을 만들기 위해,
를 사용해 보겠습니다~^^*
ADD는 여러 가지 색상의 빛을 합치는 것을 의미해요~^^*
빛은 다양한 색상의 빛을 섞으면 섞을 수록 밝아져서 점점 희어지는데요~
그 원리를 사용해 보겠습니다~!!
아 네 네!!!
네…. 그렇죠….!!! 역시….예리하시군요!!!
순한 붉은 색이면 (150, 0, 0)을 하면 될텐데…왜 순하게 붉은 느낌의 색(150, 40, 80)를 사용하는지 궁금했었는데…blendMode(ADD); 보니 이제 이해가 되신다구요…!!!
그러네요!!!! 오오!!!
(150, 0, 0)은 빛 색상의 더하기 blendMode(ADD)의 효과가 없을 것 같아요. Red 빛 하나만 존재하니까요.
(150, 40, 80)는 Green 빛과 BLue 빛이 약하게나마 존재하고 있어서, 화염 입자들이 여러 개 겹칠 수록, blendMode(ADD)의 효과가 점점 커질 것 같아요~
신기하네요~~^^*
그리고요~~^^*
이전 프레임의 이미지 색상이 남아있어서 blendMode(ADD)에 중복합산되지 않도록~,
함수 clear()를 사용하여~, 이전 프레임 화면을 깨끗하게 지우겠습니다~~^^*
그래서, 오늘의 핵심 코드는~~~~
clear();
blendMode(ADD);
let this.lifetime = 255;
tint(150, 40, 80, this.lifetime);
this.lifetime -= 10;
입니다~~^^*
그럼 이제 화염을 표현한 프로그램의 파일별 코드 내용을 함께 살펴 볼까요~^^*
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="particle.js"></script>
<script src="emitter.js"></script>
<script src="sketch.js"></script>
</body>
</html>
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = p5.Vector.random2D();
this.vel.mult(random(0.5, 3));
this.acc = createVector(0, 0);
this.r = 32;
this.lifetime = 255;
}
finished() {
return this.lifetime < 0;
}
//화염 입자가 일생을 잘 마무리 하였다면 True 값을 반환합니다.
applyForce(force) {
this.acc.add(force);
}
edges() {
if (this.pos.y >= height - this.r) {
this.pos.y = height - this.r;
this.vel.y *= -1;
}
if (this.pos.x >= width - this.r) {
this.pos.x = width - this.r;
this.vel.x *= -1;
} else if (this.pos.x <= this.r) {
this.pos.x = this.r;
this.vel.x *= -1;
}
//붉은 화염이, 단단한 바닥이나 벽에 닿으면 움직임의 방향을 바꾸도록 하겠습니다.
}
update() {
this.vel.add(this.acc);
this.pos.add(this.vel);
this.acc.set(0, 0);
this.lifetime -= 10;
}
show() {
tint(150,40,80, this.lifetime);
//픽셀 이미지 데이터 Red, Green, Blue, Alpha를 관장하는 함수입니다. 처음엔 순한 붉은 느낌의 색(R 150 G 40 B 80)의 불투명(this.lifetime 255)이지만, 시간이 지나면서, this.lifetime이 -10씩 변화되면서, 점점 투명해 집니다.
imageMode(CENTER);
//이미지의 위치좌표점을 가운데에 놓겠습니다.
image(img, this.pos.x, this.pos.y, this.r);
//이미지파일을, 붉은 화염 위치 좌표 (this.x, this.y)에 지정된 크기 this.r 사이즈로 보여줍니다.
}
}
class Emitter {
constructor(x, y) {
this.position = createVector(x, y);
this.particles = [];
}
//화염 스팟은 각각 지정된 좌표에, 입자 배열을 생성하여꽃불꽃을 뿜습니다~
emit(num) {
for (let i = 0; i < num; i++) {
this.particles.push(new Particle(this.position.x, this.position.y));
}
}
//지정된 갯수의 화염 입자를 한 번에 만들어 입자 배열에 담습니다~.
update() {
for (let particle of this.particles) {
let gravity = createVector(0, 0.01);
particle.applyForce(gravity);
//중력의 작용을 받도록 하겠습니다~^^*
let dirX = map(mouseX, 0, width, -0.3, 0.3);
let dirY = map(mouseY, 0, height, -0.3, 0.3);
let yourControl = createVector(dirX, dirY);
particle.applyForce(yourControl);
//마우스 움직임에 따라 바람의 방향이 변화합니다~^^*
particle.update();
particle.edges();
}
for (let i = this.particles.length - 1; i >= 0; i--) {
if (this.particles[i].finished()) {
this.particles.splice(i, 1);
}
}
//화염 입자 배열의 맨뒤에서 앞으로 나아가며, 화염 입자 수명을 점검하여, 일생을 잘 마무리 하였다면, 화염 입자 배열에서 풀어주어 검은 밤 공기 속에 몸을 시원하게 담그고 쉬도록 배려합니다. 컴퓨터 복지도 배려합니다^^*
}
show() {
for (let particle of this.particles) {
particle.show();
}
}
//화염을 보여 줍니다~^^*
}
let emitters = [];
//깜깜한 밤을 밝혀줄 화톳불을 담을 배열입니다~^^*
//오늘은 화력 좋은 화톳불 하나만 지피도록 하겠습니다~^^*
let img;
//직접 만들었던 입자 이미지 파일의 크기를 줄인 (32*32) 이미지 파일을 저장할 변수입니다~^^
function preload(){
img = loadImage('smallone.png');
//기존의 동그라미 입자 이미지 파일을 (32*32픽셀)로 크기를 줄인 이미지 파일을 로드하여 변수 img에 저장하겠습니다~^^*
}
function setup() {
createCanvas(400, 400);
emitters.push(new Emitter(200, 350));
}
function draw() {
clear();
//이전 프레임에서 그려놓은 불꽃 이미지를 지웁니다~
//이전 프레임의 이미지 색상이 영구적으로 남겨져 BlendMode(ADD)에 중복합산되지 않도록 하기 위한 장치인 것 같아요~^^*
background(0);
//깜깜한 밤이예요..!
//하지만 걱정 마세요~!!
//우리에겐 붉은 화톳불이 있으니까요!!!
blendMode(ADD);
//가슴 속 밝고 하얀 순수한 마음을 가진 열정 불꽃을 그려 봅시다~~!!
for (let emitter of emitters) {
emitter.emit(3);
//화력 좋은 화톳불입니다!!
emitter.show();
emitter.update();
}
}
넵, 화력 좋은 화톳불로 캄캄한 밤 공기에 빛과 열기를 더해 볼까요~^^* 마우스/손가락을 움직여 바람의 방향을 변화시켜 보셔도 재미있겠지요~~~^^* 캠프파이어 고고~~~^^*
열심히 살아온 이번 한 주 끝, 토요일 저녁입니다~
불멍하셔요~~^^*
와우!!! 입자에 대한 모든 것을 마무리 한 오늘이네요~^^*
오늘도 저와 함께 코딩공부해 주셔서 감사합니다~^^*
하나의 챕터를 마무리 하였으니…^^*
새로운 챕터가 또 우리를 기다리고 있겠네요~~^^*
네~~!! 우리 내일 또 만나서 함께 코딩공부해요~~~^^*
꿈은 이루어 집니다~~!!!
댓글 남기기