오늘은 우리 마른 모래를 한 스쿱 한 스쿱 시~원~~하게 뿌리도록 프로그램을 개선해 보겠습니다~~^^* YEAH~^^*
그전에, 우리~~grid[][]을 표현하는 화면 속의 알갱이들의 테두리를 지워서. 컴퓨터가 계산해서 표현하는 일을 좀 가볍게 만들어 보면 어떨까요? 그러면 컴퓨터의 작업속도가 좀더 빨라 질 수 있을 것 같아요~^^*
원래는~ <까만내부+하양테두리>가 <하얀내부+하얀테두리>로 바뀌는 것이 알갱이가 움직이는 모습을 표현했지만~
이제는~ <까만내부+No테두리>가 <하얀내부+No테두리>로 바뀌는 것이 알갱이의 움직임을 표현하도록 코드를 개선해 보겠습니다~^^*
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * resolution;
let y = j * resolution;
noStroke();
//테두리를 없애겠습니다.
//컴퓨터의 업무량을 줄여 보겠습니다.
//컴퓨터의 작업 속도가 빨라지면 좋겠습니다!
fill(grid[i][j] * 255);
//grid[i][j]값이 1이면 1*255 = 255 즉, 흰색으로 채웁니다.
//grid[i][j]값이 0이면 0*255 = 0 즉, 검은색으로 채웁니다.
square(x, y, resolution);
}
}
새하얀 모래가 새까만 밤에 빠르게 쌓이는 시원한 광경을 우리 구경하러 함께 가요~~^^*
시원함 level 1에 도달하였으니,
이제 우리~~^^*
시원함 level 2로 나아가 볼까요~~^^*?
한 스쿱 한 스쿱 시~원~~하게~~^^*
화면 위의 <마우스 위치좌표에 해당하는 grid[][]의 구성요소>의 <주변 grid[][]구성요소들>을 모두 한꺼번에 <우리의 알갱이>들로 만들어 보면 어떨까요!
음…마우스 위치 좌표에 해당하는 grid[][]의 구성요소가 중심이 되는 일종의 새로운 행렬 한 스쿱[][] 행렬을 만든다고나 할까요~~?
정사각형 모양의 한 스쿱의 한 변의 길이를 3라고 가정하고,
마우스 위치 좌표헤 해당하는 구성요소가 한스쿱 [mX] [mY] 이라고 한다면
[mX-1][mY-1] [ mX ][mY-1] [mX+1][mY-1]
[mX-1][ mY ] [ mX ][ mY ] [mX+1][ mY ]
[mX-1][mY+1] [ mX ][mY+1] [mX+1][mY+1]
로 구성될 수 있을 것 같아요~^^*
어머 근데!!! 1은 3을 2로 나눈 몫의 정수 부분을 취한 것과 같은데요!!!
1 = floor( 3 / 2);
이 특성을 이용하면, 한 스쿱의 변의 길이를 자유롭게 지정해도 그에 따라 한 스쿱 행렬이 자연스럽게 만들어 질 수 있을 것 같아요!!
let matrix = 5;
let extent = floor( matrix / 2);
그러면 우리 이제~~^^* 마우스 위치좌표 주변에 가로세로 5 면적의 한스쿱 <우리의 알갱이>들을 생성하도록 함수 mouseDragged()를 개선해 볼까요~^^*
function mouseDragged() {
let mouseCol = floor(mouseX / resolution);
let mouseRow = floor(mouseY / resolution);
let matrix = 5;
let extent = floor( matrix / 2);
for (let i = -extent ; i <= extent ; i++) {
for (let j = -extent ; j <= extent ; j++) {
let col = mouseCol + i;
let row = mouseRow + j;
if(col >= 0 && col <= cols-1 && row >= 0 && row <= rows-1) {
grid[col][row] = 1;
}
}
}
}
음….이제 우리 한 스쿱 모래 알갱이들이 시원하게 쏟아져 쌓이는 모습을 표현하는 프로그램의 전체 코드를 살펴 볼까요~~^^*
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 = 5;
let extent = floor( matrix / 2);
for (let i = -extent ; i <= extent ; i++) {
for (let j = -extent ; j <= extent ; j++) {
let col = mouseCol + i;
let row = mouseRow + j;
if(col >= 0 && col <= cols-1 && row >= 0 && row <= rows-1) {
grid[col][row] = 1;
}
}
}
//마우스가 클릭되면 자동적으로 작동되는 함수입니다~~^^*
//메인 함수에서 따로 호출할 필요가 없어요~~^^*
//mouseX, mouseY가 위치하는 화면 위치 좌표를 resoultion으로 나눈 후 그 몫의 정수 부분만 취하면, 해당 위치에 자리한 grid배열의 구성요소를 알 수 있을 것 같아요~^^*
//마우스의 위치를 중심으로 하는 한스쿱 정사각형 범위를 위치좌표들을 찾습니다. 이 x y 위치 좌표들이 화면안에 있는 경우에만, 해당 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 dir = 1;
if(random(1) < 0.5) {
dir *= -1;
}
let belowA;
let belowB;
if ( i + dir >= 0 && i + dir <= cols - 1) {
belowA = grid[ i + dir ][ j + 1 ];
}
if ( i - dir >= 0 && i - dir <= cols - 1) {
belowB = grid[ i - dir ][ j + 1 ];
}
//오른쪽 왼쪽 임의적으로, 위치좌표가 화면 안쪽에 있을 때만, 아래A와 아래B가 grid[][] 구성요소를 저장해요~^^*
if (below === 0) { //바로 아래 칸이 까맣다면~~^^*
nextGrid[i][j + 1] = 1; //바로 아래 칸을 하얗게~^^*
}
else if (belowA === 0) {
//바로 아래 칸은 희지만 아래A 칸이 까맣다면~~^^*
nextGrid[i + dir][j+1] = 1; //알갱이의 바로 아래A 칸을 하얗게~^^*
}
else if (belowB === 0) {
//바로 아래 칸도 희고, 아래A 칸도 희지만, 아래B 칸은 까맣다면~~^^*
nextGrid[i - dir][j+1] = 1; //알갱이의 아래B 칸을 하얗게~^^*
}
else {
//그렇지 않을 때, 즉,
//바로 아래 칸도 아래A 칸도 그 아래B 칸도 희거나
//바래 아래 칸이 존재하지 않을 때
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;
noStroke();
//테두리를 없애겠습니다.
//컴퓨터의 업무량을 줄여 보겠습니다.
//컴퓨터의 작업 속도가 빨라지면 좋겠습니다!
fill(grid[i][j] * 255);
//grid[i][j]값이 1이면 1*255 = 255 즉, 흰색으로 채웁니다.
//grid[i][j]값이 0이면 0*255 = 0 즉, 검은색으로 채웁니다.
square(x, y, resolution);
}
}
//마우스 클릭 한 곳의 알갱이가 하얗게 변하나요? ^^*
//그리고 그 아래칸들이 차례로 하얗게 까맣게 변화되나요?^^*
//하얀 알갱이가 까만 하늘에서 내려오는 것처럼 보이나요?^^*
//하얀 알갱이가 바닥에 가만히 머무르나요?^^*
//하얀 알갱이가 마른 모래 언덕처럼 부드럽게 쌓이나요?
//마우스가 왼쪽 가장자리 오른쪽 가장자리 가더라도 프로그램이 계속 되나요?
//마우스로 한 곳을 천천히 오래 드래그해도 프로그램이 계속 되나요?
//알갱이가 왼쪽 오른쪽 임의적으로 자연스럽게 쌓이나요?^^*
//새하얀 알갱이가 빠르게 쌓이나요~^^*?
//새까만 배경이 깔끔하게 보이나요~^^*?
//마우스 위치를 중심으로 한 스쿱의 <우리의 알갱이>들이 생성되어 시원하게 쏟아지나요~^^*
}
한 스쿱 한 스쿱씩 시~원~~하게 모래 언덕을 만들어 봅시다~~^^* 아이 시원해~~^^*
한꺼번에 많이 쏟아지니 좀 무섭게 시원하시다구요~? 마치 범 내려오면서 쇠낫 같은 발톱으로 잔디 뿌리 왕모래를 엄동설한 백설격으로 자르르르르 흩치는 것 같아서 무서우시다구요?
그럼 우리 어린이 숟가락으로 편안하게 시원한 광경을 연출해 볼까요~~^^* matrix 2by2로 가봅시다~~^^*
물의 양을 조절하며 시원한 물내림을 자유롭게 만들어 내는 멋진 아이디어처럼~
<우리의 알갱이>의 양을 자유롭게 조절할 수 있도록,
함수 mouseDragged()를 오늘 저와 함께 개선해 주셔서 감사합니다~~^^*
내일은 또 어떤 예쁜! 도전이 우리를 기다리고 있을까요~~^^* 궁금하시죠~~^^*
오늘도 시원한 아침! 멋진 하루! 보내시구요~~^^*
내일 우리 또! 만나는 거예요~~~^^*
네~!!! 꿈은 이루어 집니다~~!!!!
댓글 남기기