Silverback9

#야생으로

Creative Coding 독학 제200일 2024년10월13일(일)

오늘은 동네 놀이터 모래사장에서 마른 모래로 재미있는 놀이를 하는 날이예요~^^*

어제 마우스 클릭클릭해서 모래성을 쌓느라 수고 많으셨어요~^^*

이번엔 마우스를 드래그해서 모래성을 빠르고 쉽게 쌓아 볼까요~~^^*

function mouseDragged() {
  let col = floor(mouseX / resolution);
  let row = floor(mouseY / resolution);
  grid[col][row] = 1; 
  
  //마우스로 쭈욱~ 드래그하면 자동적으로 작동되는 함수입니다~~^^*
  //메인 함수에서 따로 호출할 필요가 없어요~~^^*
  //mouseX, mouseY가 위치하는 화면 위치 좌표를 resoultion으로 나눈 후 그 몫의 정수 부분만 취하면, 해당 위치에 자리한 grid배열의 구성요소를 알 수 있을 것 같아요~^^*
  //그리고, 그 구성요소에 1의 값을 저장하면~~
  //메인 함수의 색칠하는 for 구문 안에서 흰 색으로 표현되겠지요~^^* 
} 

화면 위에서 드래그 해 보셔요~~~~^^* 샤랄랄라 라랄라~~~~^^*

물에 젖은 모래 알갱이는 아래 알갱이 위에 쌓일 수 있지만~^^*

마른 모래 알갱이는 아래 알갱이 위에 쌓이지 않고, 왼쪽이나 오른쪽으로 미끄러져서 아래 알갱이 옆에 안착될 것 같아요~~^^*

오늘 우리 이 장면을 코드로 표현해 볼까요~~^^* YEAH~~^^*

음…먼저~~^^* <우리의 알갱이>의 바로 아래 알갱이 뿐만 아니라 그 왼쪽/오른쪽의 알갱이도 살펴 봐야 겠네요~^^*

 let below = grid[i][j+1]; //바로 아래 칸을 찾아서~
 let belowR = grid[i+1][j+1];  //바로 아래 칸의 오른쪽 칸도 찾아서~ 
 let belowL = grid[i-1][j+1];  //바로 아래 칸의 왼쪽 칸도 찾아서~

그러면, 절차를 세워보도록 할까요~^^*


(if) below가 아직 검은 색인가? 
    (yes)-> 흰 색으로 칠하라
    (no)-> (else if) belowR이 아직 검은 색인가?
              (yes)-> 흰 색으로 칠하라
              (no)-> (else if) belowL은 아직 검은 색인가?
                        (yes)-> 흰 색으로 칠하라
                        (no) -> 지금 있는 자리를 흰색으로 칠하라    
    

코드로 표현해 보겠습니다~^^*

  for (let i = 0; i < cols; i++){
    for (let j = 0; j < rows; j++) {
      let state = grid[i][j]; //지금 단계 상태 저장~
      if (state === 1) { //이 칸이 하얗다면~~^^*
        let below = grid[i][j+1]; //바로 아래 칸을 찾아서~
        if (below === 0) { //바로 아래 칸이 까맣다면~~^^*
          nextGrid[i][j + 1] = 1; //바로 아래 칸을 하얗게~^^*
        }
        else if (belowR === 0) {
        //바로 아래 칸은 희지만 그 오른쪽 칸이 까맣다면~~^^*
          nextGrid[i+1][j+1] = 1; //알갱이의 바로 아래 오른쪽 칸을 하얗게~^^*
        }
        else if (belowL === 0) {
        //바로 아래 칸도 희고, 그 오른쪽 칸도 희지만, 그 왼쪽 칸은 까맣다면~~^^*
         nextGrid[i-1][j+1] = 1; //알갱이의 바로 아래 왼쪽 칸을 하얗게~^^*   
        } 
        else {
        //그렇지 않을 때, 즉, 
        //바로 아래 칸도 그 오른쪽 칸도 그 왼쪽 칸도 희거나 
        //바래 아래 칸이 존재하지 않을 때 
         nextGrid[i][j] = 1; //알갱이의 현재 자리를 하얗게~^^*
        }
      }
    }
  }
grid = nextGrid; //다음 단계 모눈 종이 상태를 지금 단계 모눈 종이에 저장~

그럼 우리 전체 코드를 같이 살펴 볼까요~^^*

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 col = floor(mouseX / resolution);
  let row = floor(mouseY / resolution);
  grid[col][row] = 1; 
  
  //마우스가 클릭되면 자동적으로 작동되는 함수입니다~~^^*
  //메인 함수에서 따로 호출할 필요가 없어요~~^^*
  //mouseX, mouseY가 위치하는 화면 위치 좌표를 resoultion으로 나눈 후 그 몫의 정수 부분만 취하면, 해당 위치에 자리한 grid배열의 구성요소를 알 수 있을 것 같아요~^^*
  //그리고, 그 구성요소에 1의 값을 저장하면~~
  //메인 함수의 색칠하는 for 구문 안에서 흰 색으로 표현되겠지요~^^* 
} 


let grid;
let cols;
let rows;
let resolution = 10;

function setup() {
  createCanvas(400, 400);
  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 === 1) { //이 칸이 하얗다면~~^^*
        let below = grid[i][j+1]; //바로 아래 칸을 찾아서~
        let belowR = grid[i+1][j+1];  //바로 아래 칸의 오른쪽 칸도 찾아서~ 
        let belowL = grid[i-1][j+1];  //바로 아래 칸의 왼쪽 칸도 찾아서~ 
         if (below === 0) { //바로 아래 칸이 까맣다면~~^^*
          nextGrid[i][j + 1] = 1; //바로 아래 칸을 하얗게~^^*
           let below = grid[i][j+1]; //바로 아래 칸을 찾아서~

        }
        else if (belowR === 0) {
        //바로 아래 칸은 희지만 그 오른쪽 칸이 까맣다면~~^^*
          nextGrid[i+1][j+1] = 1; //알갱이의 바로 아래 오른쪽 칸을 하얗게~^^*
        }
        else if (belowL === 0) {
        //바로 아래 칸도 희고, 그 오른쪽 칸도 희지만, 그 왼쪽 칸은 까맣다면~~^^*
         nextGrid[i-1][j+1] = 1; //알갱이의 바로 아래 왼쪽 칸을 하얗게~^^*   
        } 
        else {
        //그렇지 않을 때, 즉, 
        //바로 아래 칸도 그 오른쪽 칸도 그 왼쪽 칸도 희거나 
        //바래 아래 칸이 존재하지 않을 때 
         nextGrid[i][j] = 1; //알갱이의 현재 자리를 하얗게~^^*
        }
      }
    }
  }
grid = nextGrid; //다음 단계 모눈 종이 상태를 지금 단계 모눈 종이에 저장~

  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      
      let x = i * resolution;
      let y = j * resolution;
      
      fill(grid[i][j] * 255); 
      //grid[i][j]값이 1이면 1*255 = 255 즉, 흰색으로 채웁니다.
      //grid[i][j]값이 0이면 0*255 = 0 즉, 검은색으로 채웁니다.
      stroke(255);
      square(x, y, resolution); 
       
    }
  }
  //마우스 클릭 한 곳의 알갱이가 하얗게 변하나요? ^^*
  //그리고 그 아래칸들이 차례로 하얗게 까맣게 변화되나요?^^*
  //하얀 알갱이가 까만 하늘에서 내려오는 것처럼 보이나요?^^*
  //하얀 알갱이가 바닥에 가만히 머무르나요?^^*
  //하얀 알갱이가 마른 모래 언덕처럼 부드럽게 쌓이나요? 
}

마른 모래 언덕 쌓기 놀이를 하러 가 볼까요~~^^* 어머 근데, 어느 시점에서 프로그램이 멈춰 버리는 것 같은데요? 어떤 순간에 프로그램 멈춤이 발생하는가요??

네….마우스가 화면 밖으로 벗어나게 되면 프로그램이 멈추는 것 같아요.

grid배열이 화면 안의 위치좌표 기반의 구성요소들을 가지고 있어서 그런 것 같아요.

마우스가 화면 밖으로 벗어나면, 화면 안 위치좌표 기반의 grid배열의 구성요소를 배정하고, 그 바로 아래 및 왼쪽 아래와 오른쪽 아래 구성요소를 찾아 계산하는 것에 많은 어려움이 있는 것 같아요.

우리 내일은 음악 들으며 머리를 식히고~~^^*

화요일 신선한 마음으로 이 문제를 해결해 볼까요~~^^*

네~~^^* 고난은 우리가 더욱 섬세한 기능을 갖출 수 있도록 노력하게 만드는 계기가 되어 주어서 감사한 마음이 드네요~~^^*

오늘 저와 함께 마른 모래로 모래 언덕을 부드럽게 쌓는 코드를 완성해 주셔서 감사합니다~^^* 또한, 프로그램 멈춤의 문제를 발견해 주셔서 감사합니다~~^^*

우리 이 문제를 해결할 때까지 모래 사장에 함께 머물기로 해요~^^*

문제를 충분히 사랑하면 해결의 실마리를 함께 찾을 수 있을 거예요~~^^*

내일 우리 또 만나서 부드러운 모래에 발가락을 꼼지락거리며 함께 음악 들어요~~^^*

네~~^^* 꿈은 이루어 집니다~~^^*

댓글 남기기