If you're seeing this message, it means we're having trouble loading external resources on our website.

웹 필터가 올바르게 작동하지 않으면 도메인 *. kastatic.org*.kasandbox.org이 차단되어 있는지 확인하세요.

주요 내용

인터랙티브 장면

이제 에니매이션 장면을 만드는 방법을 알게 되었으니, 정적이지 않은 다른 종류의 장면, 즉 사용자가 인터랙션 할 수 있는 장면 만드는 법을 확실하게 이해하고 넘어갑시다. 예를 들어 (물론 윈스턴의 록 스타 시절 이후에) 윈스턴이 아기를 가진 장면을 그릴 수 있습니다. 또한, 사용자가 클릭하면 아기가 생성되도록 프로그래밍할 수 있습니다. 세상에 윈스턴 주니어가 많이 있다고 해서 나쁠 건 없잖아요.
위에서 말한 예시를 아래에 독립형 프로그램으로 만들어 보았습니다. 프로그램은 이 장면을 정적으로 묘사합니다. mouseClicked는 이미 출력된 화면 위에 커서를 두고 클릭하면 해당 위치에 윈스턴의 아기 이미지를 그립니다.
이 장면을 다중 장면 프로그램에 어떻게 통합시킬 수 있을 까요? 먼저 모든 정적 그리기 코드를 장면 그리기 함수 drawScene5()에 넣고 장면 변환 함수를 mouseClicked에 추가하는 것으로 시작합니다.
var drawScene5 = function() {
    currentScene = 5;
    background(173, 239, 255);
    fill(7, 14, 145);
    textSize(39);
    text("Winston has babies!", 10, 47);
    ...
};

mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        drawScene1();
    }
};
이 코드는 다음과 화면을 출력합니다:
그러나 mouseClicked 기능을 어떻게 통합할까요? 이미 코드에 mouseClicked를 정의하였으므로 두 번 정의할 수 없습니다. JavaScript에서는 마지막 함수의 정의만 유효하므로 이전 정의를 치환하게 됩니다. 즉, 기존 mouseClicked 내부에 아기를 그릴 코드를 넣을 좋은 위치를 찾아야 합니다. 몇 가지 선택 사항에 대해 논의해 봅시다.
1. 함수의 맨 윗줄에 놓습니다.
mouseClicked = function() {
    image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    ...
};
이렇게 하면 아이가 생성되는 화면이 아니어도 사용자가 마우스를 클릭할 때마다 호출될 것입니다. (다른 장면에서 윈스턴에게 아기가 생기는 그림은 이상해 보입니다.) 좋지 않아요.
2. currentScene === 4 if 블록 내부에 놓습니다.
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    } else if (currentScene === 5) {
        drawScene1();
    }
};
해당 위치가 drawScene5()를 호출하는 곳이고 아기는 장면 5에서 추가되어야 합니다. 그러나 한번 생각해 보기 바랍니다. 위 코드의 의미는 장면을 그릴 때마다 항상 추가적인 아기를 그리라는 의미입니다. 다시 말하면 아기를 한 명 이상 그리지 못하게 됩니다. 왜냐하면 currentScene은 장면 5로 설정되었기 때문에 if 블록 내의 코드는 더 이상 실행되지 않습니다.
3. currentScene === 5 if 블록 내부에 놓습니다.
mouseClicked = function() {
    if (currentScene === 1) {
        drawScene2();
    } else if (currentScene === 2) {
        drawScene3();
    } else if (currentScene === 3) {
        drawScene4();
    }  else if (currentScene === 4) {
        drawScene5();
    } else if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
        drawScene1();
    }
};
이것은 처음 장면을 출력한 후 첫 번째 클릭을 하기 전 까지 아기들을 그리지 말라는 의미입니다. 그러나 이후 코드 줄에서 보는 것처럼 아기들은 즉시 장면 1로 대체됩니다.
이번 예시에서는 아기 장면을 다른 장면과 통합하는 과정에서 치명적인 결함이 발견되었습니다. 마우스 클릭 인터랙션은 장면을 전환할 때도 쓰고 장면에서 인터랙션을 불러올 때도 쓰고 있습니다. 이제 처리해야 할 어려운 문제가 생겼습니다. 장면을 통합하기 위해 좀 더 근본적으로 접근해야 합니다.
4. 장면 1이 다시 출력되지 않게 하고 사용자가 다시 시작할 수 있도록 알려줍니다. 물론 이 방법으로 동작시킬 수 있습니다. 하지만 클릭해야 하는 장면이 제일 마지막에 있을 때만 이 방법이 통합니다. 만약 클릭해야 하는 장면이 마지막 장면보다 앞에 있으면 방법이 없습니다. 따라서 이 해결책은 도움이 되지 않습니다.
5.  mouseDragged 처럼 다른 종류의 인터랙션을 사용합니다. 이 방법으로 해결할 수 있습니다. 왜냐하면 마우스 드래그는 클릭으로 취급하지 않습니다. 꼭 currentScene === 5 를 써서 해당 장면 외에 다른 장면에서 마우스 드래그로 아기가 생성되지 않도록 하세요.
mouseDragged = function() {
    if (currentScene === 5) {
        image(getImage("creatures/BabyWinston"), mouseX-20, mouseY-20);
    }
};
밑에서 한번 해보세요. 마지막 장면에서 드래그 해보세요.
결과적으로 작동하긴 하지만 윈스턴이 얼마나 많은 아기를 갖게 될 것인지는 약간 걱정이 되네요. 일반적으로 이것은 최적의 해결책은 아닙니다. 다른 장면을 마우스 클릭에 반응하지 않도록 설계해야 하기 때문입니다. 이런 제약은 그렇게 달갑지는 않습니다.분명 더 나은 방법이 있을 거예요.
대신 마우스 클릭을 위치에 따라 다르게 반응하도록 지정해서 어떤 위치에서 클릭하면 장면을 바꾸고 다른 위치에서 하면 장면 내 인터랙션을 할 수 있도록 만들면 어떨까요? 마치 버튼처럼 말이에요! 실제로 이것은 대부분의 다중-장면 프로그램이 사용하는 방법입니다. 다음 단원에서 이런 방법에 대해 자세히 살펴봅시다.