Silverback9

#야생으로

Creative Coding 독학 제206일 2024년10월19일(토)

오늘은 무지개색 모래 언덕쌓기 프로그램을 좀더 깔끔하게 정돈해 보겠습니다~^^*

우리가~~^^* 마우스 드래깅으로 <우리의 알갱이>를 생성할 때와 <우리의 알갱이>가 내려와 앉을 자리에 있는 <아래 알갱이들>을 찾는 과정에서, <<화면 안에 있을 때>>라는 조건이 굉장히 중요했었지요~~^^*

<<화면 안에 있을 때>>라는 조건을 코드 안 필요한 곳에 매번 새롭게 써서 넣었었는데요~^^*

이 부분을 함수로 만들어 보면 어떨까요?

화면 안에 있을 때 진리값 true를 return하는 함수를요~~^^*

그러면 if 조건문이 이 함수를 호출해서 그 return 값이 true일 때 지시문을 실행하도록 하면, 보기에도 깔끔하고~~^^* 필요할 때 언제든 어디서든 호출해서 쓰면 되어서 편리할 것 같아요~~^^*

function withinCols(i) {
return i >= 0 && i <= cols - 1;
}
//x축 위치가 화면 안에 있을 때 진리값 true를 return합니다. 
function withinRows(j) {
return j >= 0 && j <= rows - 1;
}
//y축 위치가 화면 안에 있을 때 진리값 true를 return 합니다. 

그럼 우리 이 함수들을 사용해서 화면 안 위치를 점검하도록 전체 코드를 개선해 볼게요~^^* 그리고~~^^* <우리의 알갱이>의 크기도 줄여서, 곱디고운 무지개색 모래 분말을 만들어 볼까요? 너무 고와서 소리가 나지 않을 수도 있어요~~^^*

function withinCols(i) {
return i >= 0 && i <= cols - 1;
}
//x축 위치가 화면 안에 있을 때 진리값 true를 return합니다. 

function withinRows(j) {
return j >= 0 && j <= rows - 1;
}
//y축 위치가 화면 안에 있을 때 진리값 true를 return 합니다. 



function make2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
    for (let j = 0; j < arr[i].length; j++) {
      arr[i][j] = 0;
    }
  }
  return arr;
  //새까맣게 채워진 모눈 종이를 return합니다. 
}

function mouseDragged() {

  let mouseCol = floor(mouseX / resolution);
  let mouseRow = floor(mouseY / resolution);   
 
  let matrix = 20;
//아주 고운 가루를 만들 것이라, 최대 생성 개수는 늘여서 20*20으로 해보겠습니다.
  
  let extent = floor( matrix / 2); 
  for (let i = -extent ; i <= extent ; i++) {
    for (let j = -extent ; j <= extent ; j++) {
      if(random(1) < 0.75) {
       let col = mouseCol + i;
       let row = mouseRow + j; 
       if(withinCols(col) && withinRows(row)) {
         grid[col][row] = hueValue;
       }
      }
    } 
  }

  hueValue += 1;

  if(hueValue > 360) {
    hueValue = 1;
  }
  
  //마우스가 클릭되면 자동적으로 작동되는 함수입니다~~^^*
  //메인 함수에서 따로 호출할 필요가 없어요~~^^*
  //mouseX, mouseY가 위치하는 화면 위치 좌표를 resoultion으로 나눈 후 그 몫의 정수 부분만 취하면, 해당 위치에 자리한 grid배열의 구성요소를 알 수 있을 것 같아요~^^*
  //마우스의 위치를 중심으로 하는 한스쿱 정사각형 범위 안의, 0.75 확률로 임의적으로 위치좌표들을 찾습니다. 이 x y 위치 좌표들이 화면안에 있는 경우에만, 해당 grid[][] 구성요소에 HSB hulValue를 저장합니다. 
  //메인 함수의 색칠하는 for 구문 안에서 HSB hulValue 색상으로 표현되겠지요~^^* 
  //한 스쿱의 알갱이 색은 동일하고, 다음 스쿱 알갱이 색은 살짝 달라지겠네요~^^*
  //hueValue값이 360보다 커지면 다시 1로 세팅하겠습니다~^^*
} 


let grid;
let cols;
let rows;

let resolution = 1;
// 아주 고운 가루 알갱이를 생성해 보겠습니다.

let hueValue = 0;

function setup() {
  createCanvas(400, 400);
  colorMode(HSB, 360, 255, 255);
  cols = width / resolution;
  rows = height / resolution;

  grid = make2DArray(cols, rows);
  //지금 단계 까만 모눈 종이 준비~~^^*
  
}

function draw() {
  background(0);
   
  let nextGrid = make2DArray(cols, rows);
  //다음 단계 까만 모눈 종이 준비~~^^*

  for (let i = 0; i < cols; i++){
    for (let j = 0; j < rows; j++) {
      let state = grid[i][j]; //지금 단계 상태 저장~
      if (state > 0) { //이 칸이 색칠해져 있다면~~^^*
        let below = grid[i][j+1]; //바로 아래 칸을 찾아서~
        
        let dir = 1;
        if(random(1) < 0.5) {
          dir *= -1;
        }
        
        let belowA;
        let belowB;
        if ( withinCols(i + dir)) {
          belowA = grid[ i + dir ][ j + 1 ];
        }
        if ( withinRows(i - dir)) {
          belowB = grid[ i - dir ][ j + 1 ];
        }
        //오른쪽 왼쪽 임의적으로, 위치좌표가 화면 안쪽에 있을 때만, 아래A와 아래B가 grid[][] 구성요소를 저장해요~^^*
        
        
        
        if (below === 0) { //바로 아래 칸이 까맣다면~~^^*
          nextGrid[i][j + 1] = state; //바로 아래 칸 색칠~^^*
        }
        else if (belowA === 0) {
        //바로 아래 칸은 색칠되어 있지만, 아래A 칸이 까맣다면~~^^*
          nextGrid[i + dir][j+1] = state; //알갱이의 바로 아래A 칸 색칠~^^*
        }
        else if (belowB === 0) {
        //바로 아래 칸도, 아래A 칸도 색칠되어 있지만, 아래B 칸은 까맣다면~~^^*
         nextGrid[i - dir][j+1] = state; //알갱이의 아래B 칸 색칠~^^*   
        } 
        else {
        //그렇지 않을 때, 즉, 
        //바로 아래 칸도 아래A 칸도 그 아래B 칸도 색칠되어 있거나
        //바래 아래 칸이 존재하지 않을 때 
         nextGrid[i][j] = state; //알갱이의 현재 자리 색칠~^^*
        }
      }
    }
  }
grid = nextGrid; //다음 단계 모눈 종이 상태를 지금 단계 모눈 종이에 저장~

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      
      let x = i * resolution;
      let y = j * resolution;
      
      noStroke();
      //테두리를 없애겠습니다.
      //컴퓨터의 업무량을 줄여 보겠습니다.
      //컴퓨터의 작업 속도가 빨라지면 좋겠습니다!
      
      if(grid[i][j] > 0) {
      
        fill(grid[i][j], 255, 255); 
        //grid[i][j]에 저장된 Hue 색상값, 채도 최대값, 명도 최대값
      
        square(x, y, resolution);
      }        
    }
  }
  //마우스 클릭 한 곳에 무지개색 알갱이가 생기나요?? ^^*
  //그리고 그 아래칸들이 차례로 무지개색 까맣게 변화되나요?^^*
  //무지개색 알갱이가 까만 하늘에서 내려오는 것처럼 보이나요?^^*
  //무지개색 알갱이가 바닥에 가만히 머무르나요?^^*
  //무지개색 알갱이가 마른 모래 언덕처럼 부드럽게 쌓이나요? 
  //마우스가 왼쪽 가장자리 오른쪽 가장자리 가더라도 프로그램이 계속 되나요?
  //마우스로 한 곳을 천천히 오래 드래그해도 프로그램이 계속 되나요? 
  //알갱이가 왼쪽 오른쪽 임의적으로 자연스럽게 쌓이나요?^^*
  //무지개색 빠르게 쌓이나요~^^*?
  //새까만 배경이 깔끔하게 보이나요~^^*?
  //마우스 위치를 중심으로 한 스쿱의 <우리의 알갱이>들이 임의적으로 생성되어 자연스럽고 시원하게 쏟아지나요~^^*
  //빨주노초파남보 예쁜 무지개색 모래 언덕이 쌓이나요~~^^*
  //곱디 고운 무지개색 모래 가루라서 소리도 하나도 나지 않고 쌓이고 있어서 깜짝 놀라고 계시나요~~^^*

}

소리가 나지 않는 컬러풀한 용각산을 만나러 저랑 함께 가보실까요~~^^*

지금 제가 공부하고 있는 까페의 창 밖의 교통 표지판 뒷면에 아침 햇살과 나뭇잎 그림자가 함께 춤추고 있는데요! 나뭇잎 그림자와 함께 춤추고 있는 아침 햇살가루는 너무 고와서 그런지 소리가 나지 않아요!

<우리의 알갱이>도 고운 무지개 모래 분말이 되어 소리없이 내려오고 있지만~~^^*

서로 일곱빛깔 무지개 언덕이 되어 주며 편안히 앉은 <우리의 알갱이>들에게 멋진 반주에 곁들여 노래를 부르자고 청하면, 함께 마음 맞추어 아주 아름다운 음악 소리를 내어 줄 것만 같아요~~^^*

모래성 프로그램의 완성을 향한 제법 길었던 여정을 오늘 저와 함께 마무리해 주셔서 감사합니다~^^*

오늘 우리는 The Code of Nature 트랙의 Cellular Automata 파트를 다 마쳤어요~~^^*

Congratulations! and Celebrations!

우리 내일은~~^^* 새로운 파트를 시작해 볼까요~~!! 새로운 도전!! 함께 할까요~!!

오늘도 멋진 아침! 멋진 하루! 보내시고요~~!!!

우리 내일 또 만나요~~^^*

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

댓글 남기기