Silverback9

#야생으로

Creative Coding 독학 제107일 2024년07월12일(금)

오늘은 이글거리는 화염을 만들기 위한 준비 공부를 하겠습니다~~^^*

네~~^^* 코딩으로 직접 만들었던 동그라미 이미지를 물방울 입자로 사용하여, 땅 위에 소중한 비를 공급해 보겠습니다.

오늘은 동그라미 그리기 함수를 사용하지 않고 동그라미 이미지를 바로 표현하는 작업을 하기 때문에, 이미지 표현에 관한 새로운 함수들을 사용해 보겠습니다~^^*

아래 동영상 강의를 클릭하시면 오늘 공부 내용을 바로 시작(5:12)하실 수 있어요~^^* 8:15까지 보시면 오늘 공부 끝~^^*

오늘의 핵심 코드 부분을 먼저 살펴 볼까요~^^*

 let img;
//직접 만들었던 입자 이미지 파일의 크기를 줄인 (32*32) 이미지 파일을 저장할 변수입니다~^^

 function preload(){  
    img = loadImage('smallone.png');  
//기존의 동그라미 입자 이미지 파일을 (32*32픽셀)로 크기를 줄인 이미지 파일을 로드하여 변수 img에 저장하겠습니다~^^* 
  }

 show() {
  
    tint(255, this.lifetime);
    //픽셀 이미지 데이터 Red, Green, Blue, Alpha를 관장하는 함수입니다. 처음엔 흰색(RGB 모두 255)의 불투명(this.lifetime 255)이지만, 시간이 지나면서, this.lifetime이 -5씩 줄어들면서, 점점 투명해 집니다. 
  
    imageMode(CENTER);
    //이미지의 위치좌표점을 가운데에 놓겠습니다.
    
    image(img, this.pos.x, this.pos.y, this.r);
    //이미지파일을, 빗방울 위치 좌표 (this.x, this.y)에 지정된 크기 this.r 사이즈로 보여줍니다.
  }

이제 프로그램 전체 코드들을 파일 별로 살펴 보겠습니다~^^*

<!DOCTYPE html>
<html lang="en">
  <head>
    https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.js
    https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/addons/p5.sound.min.js
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <main>
    </main>
      http://particle.js
      http://emitter.js
      http://sketch.js
  </body>
</html>

class Particle {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = p5.Vector.random2D();
    this.vel.mult(random(0.5, 2));
    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 -= 5;
  }

  show() {
  
    tint(255, this.lifetime);
    //픽셀 이미지 데이터 Red, Green, Blue, Alpha를 관장하는 함수 tint() 입니다. 처음엔 흰색(RGB 모두 255)의 불투명(this.lifetime 255)이지만, 시간이 지나면서, this.lifetime이 -5씩 변화되어, 점점 투명해 집니다. 
  
    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.1);
      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 = [];
//비를 뿌려주는 레인메이커들을 담을 배열입니다~^^*
//오늘은 단 한 명의 레인메이커 바로 You! 만이 활약하도록 하겠습니다~ 

let img;
//직접 만들었던 입자 이미지 파일의 크기를 줄인 (32*32) 이미지 파일을 저장할 변수입니다~^^

let colorDirt = 0;
//비가 오면 흙색이 점차 초록초록하게 변화하도록 배경색 조정에 사용할 변수입니다~^^*

function preload(){
  img = loadImage('smallone.png');
  //기존의 동그라미 입자 이미지 파일을 (32*32픽셀)로 크기를 줄인 이미지 파일을 로드하여 변수 img에 저장하겠습니다~^^* 
}

function setup() {
  createCanvas(400, 400);
  emitters.push(new Emitter(200, 2));
  //하늘 한가운데에서 비를 내려보내는 고마운 레인 메이커입니다~^^*
  //바로 You!
}

function draw() {
  background(150, 100 + colorDirt, 50);
  //처음엔...비가 오지 않고 풀이 나지 않아 붉은 땅이예요.
  //비가 오면서 씨앗이 싹을 틔우고 자라게 되면~~~^^* 두둥~~~^*
  //투명한 연두빛이 온 세상을 채우게 되겠죠~~^^*

  
  for (let emitter of emitters) {
    emitter.emit(1);
    //한 번에 소중한 빗방울 하나씩 만들어주는 감사한 rain maker입니다^^* 
    //바로 You!
    emitter.show();
    emitter.update();
  }
  colorDirt = colorDirt + 0.5;
  //점점 생명의 녹색 기운이 강해져가요~~!! YEAH~~!!
  //고마워요, 레인 메이커! 바로 You!
}

붉은 땅, 비를 기다리며 땅을 부드럽게 갈아 놓았습니다. 이제 레인 메이커 바로 You!의 활약을 기다리고 있습니다! 마우스/손가락으로 비의 방향을 자유롭게 조절하며, 소중한 빗방울을 뿌려 주셔요~~~~^^*

한 번에 한 개의 빗방울을 만들어 뿌렸는데요, 온세상이 초록초록해 지네요!

한 번에 하나씩! 의 힘이 참 큰 것 같아요!!

그리고~~소중한 비가 반갑게 내리면, 그 빗물을 소중하게 잘 활용하면 참 좋을 것 같아요!!

이글거리는 태양 아래, 이 소중한 빗방울을 잘 사용하여 초원과 숲을 가꾸겠노라고 굳은 결심을 하신 아프리카 마을 주민분들이 계십니다~~!!. 반달모양 둔덕을 가진 웅덩이를 하루하루 성실하게 일구어 나가고 계십니다~~!! 멋지고 존경스러운 분들이시네요~~!!

어느 섬에는, 사라져 버린 오아시스를 버리고 떠나지 않고, 그곳에 꿋꿋이 남아 하루 하루 나무를 꾸준히 심은 분이 계십니다~~!!. 하늘에서 내린 빗물을 나무가 소중하게 잘 사용해 주어서, 되살아난 오아시스 덕분에 동물들도 편안하게 지낼 수 있게 되었네요~^^* 멋지고 존경스러운 분!!

가만히 책상에 앉아 한 장 한 장 정성을 들여 수만 장의 그림을 그려서 아름다운 애니메이션 한 편을 만드는 모습도 참 멋지고 존경스러운 모습인 것 같아요~^^*

하루 하루를 정성으로 살아가면, 그것이 바로 성인의 삶인 것 같아요~^^*

한 번에 하나! 하루에 한 번! 하루 하루! 의 큰 힘을 믿고 사는 삶! 멋지고 존경스러운 삶!

한 번에 빗방울 하나씩 만들어 주신 멋진 레인 메이커, 바로 You! 오늘도 저와 함께 코딩 공부를 해주셔서 감사합니다~^^*

우리 내일도 만나서 함께 코딩 공부 해요~~~^^*

네!! 꿈은 이루어 집니다!!!

댓글 남기기