프로그램 개요는 part 1.을 참조하세요.
XML 코드는 뭐 볼 것 없이 넘기고 우선 스크립트의 풀 소스를 리스팅합니다.
XML을 포함한 모든 코드 다운은 여기.

more..

코드 컬러링해서 HTML로 export 하는 툴이나 공개 소스가 어딘가 있을 것 같은데... 그냥 MS Word에 넣었다가 붙여넣었습니다. 로딩이 좀 느리더라도 이해해 주세요. :(

   // user private member variables
   var m_divBG = null;             // <div>    : 백그라운드
   m_imgGhost = new Array(2),      // <img>    : 메인 캐릭터
   m_sBaseUrl = "http://www.3m4you.co.kr/gongdo/gadgets/Test04/";  // 개짓이 위치하는 URL

   m_nGhostSpeed = 3;              // 캐릭터의 속도
   m_nPosX = 0,                    // 메인 캐릭터의 X,Y 위치
   m_nPosY = 0,
   m_nPrevPosX = 0,                // 메인 캐릭터의 이전 X,Y 위치
   m_nPrevPosY = 0,

   m_nInterval = 30,               // 메인 프로시져의 처리 주기
   m_nTimeouts = 0,                // MouseMove 이후 타이머 회수 체크
   m_nMaxTimeouts = 40,            // 캐릭터의 생명 주기
   m_tmrMain = null;               // 메인 타이머

개짓 클래스의 내부에서 사용할 멤버 변수들을 선언하고 초기화 합니다.
가장 중요한 객체는 백그라운드 DIV와 IMAGE를 저장할 배열이고, 캐릭터의 이동 속도 및 현재 커서 위치, 메인 프로시저 구동 인터벌 등이 보이네요. 주석을 참고하시길.

이 멤버 변수들은 개짓 클래스 내에서 전역적으로 작동하며 모든 프로시저(함수)에서 공통으로 사용될 수 있는 요소입니다.

개짓 클래스의 컨스터럭터, this.initialize에서는 CreateObject()를 호출하여 필요한 초기화를 수행하고 디스트럭터, this.dispose에서는 DestroyObject()를 호출하여 자원 해제를 수행합니다.

/*--------------------------------------
|   CreateObjects
|   필요한 모든 객체를 생성하고 이벤트를 바인딩
---------------------------------------*/
function CreateObjects()
{
    // 메인 백그라운드 <div>
    var objTmp = null;
    objTmp = document.createElement("div");
    objTmp.id = "divBG";
    objTmp.style.pixelWidth = 300; // 최소 사이즈 결정
    objTmp.style.pixelHeight = 200;
    objTmp.style.backgroundColor = "#FF6633";
    m_divBG = m_el.appendChild(objTmp);
   
    // 메인 캐릭터 이미지 <img>
    for (i=0;i<2;i++)
    {
        objTmp = document.createElement("img");
        objTmp.id = "imgGhost";
        objTmp.src = m_sBaseUrl + "images/ghost_ani0" + (i+1) + ".gif";
        objTmp.style.position = "absolute";
        objTmp.style.left = 50;
        objTmp.style.top = 50;
        objTmp.style.visibility = "hidden";
        m_imgGhost[i] = m_el.appendChild(objTmp);
       }

       // 이벤트 매핑
       AttachEvent(m_divBG, "mousemove", MouseMoveBG);
      
       // 타이머 시작
       m_tmrMain = setTimeout(MainProcedure, m_nInterval);

       objTmp = null;
}   // function CreateObjects()

CreateObjects()에서 DIV와 IMAGE엘리먼트를 생성하는데 특히 IMAGE는 개짓에서 앞으로 사용될 모든 이미지를 메모리로 미리 로드를 해야 합니다.
다음으로 백그라운드 DIV의 MouseEvent를 매핑하는데요, AttachEvent()와 DetachEvent()라는 일종의 매크로를 만들어뒀습니다. 코드는 단순히 주어진 엘리먼트의 onXXXX라는 이벤트를 마지막 인자로 주어진 핸들러(함수)에 매핑한다는 거죠.

즉, AttachEvent(m_divBG, "mousemove", MouseMoveBG); 라고 하면
m_divBG 엘리먼트의 onmousemove 이벤트를 MouseMoveBG 핸들러에 매핑한다. 가 되겠습니다. 이후 m_divBG에서 mousemove 이벤트가 발생한 경우 MouseMoveBG 함수가 호출되겠죠?

다음으로 setTimer() 함수를 이용하여 메인 프로시저 구동을 위한 타이머를 활성화 합니다.
m_tmrMain = setTimeout(MainProcedure, m_nInterval);
이 타이머 객체는 클래스 지역 변수로 보관을 합니다.

마지막으로 함수 내부에서 사용한 임시 객체를 null로 해제해줍니다.
objTmp = null;
중요한건 어떤 객체건 더 이상 사용되지 않는 시점에서는 명시적으로 null로 설정하여 메모리를 해제해주어야 합니다. 물론 자바스크립트는 개비지컬렉션을 자동으로 수행하지만 프로그래머의 실수를 방지하는 차원에서라도 명시적인 메모리 해제는 중요합니다!
제 경우는 어떤 객체를 new나 createXXX등으로 생성하는 코드를 작성하면 바로 아랫줄에 null로 세팅하는 코드를 넣고 그 사이에 필요한 코드를 삽입하는 습관을 들였습니다.
이게 메모리 릭 관련 실수를 줄이는데 의외로 꽤 도움이 되더군요.

DestroyObjects()에서는 반대로 매핑된 이벤트를 제거하고 타이머를 중지시키며 사용된 객체들의 메모리를 해제합니다.

/*--------------------------------------
|   DestroyObjects
|   모든 이벤트를 해제하고 생성한 객체를 파괴
---------------------------------------*/
function DestroyObjects()
{
    DetachEvent(m_divBG, "mousemove", MouseMoveBG);
   
    clearTimeout(m_tmrMain); // 타이머 제거
    m_tmrMain = null;

    m_divBG = null;
    m_imgGhost = null;
}   // function DestroyObjects()

DestroyObjects()와 같이 정리하는 코드에서 주의할 점은 객체의 라이프 사이클에 따라 해제하는 순서에 영향을 받을 수 있다는 점입니다.

이 예제의 경우에 이벤트 매핑을 먼저 해제하고 타이머를 중지시킨 후 비로소 다른 객체들을 해제했습니다.
만약 객체들을 해제하고 이벤트 매핑이나 타이머 중지 코드를 사용한다면 당연하게도 '객체를 찾을 수 없습니다.'라는 스크립트 오류 메시지를 만나게 되겠죠?
또한 타이머를 사용하는 코드라면 타이머를 해제하지 않고 다른 객체들을 해제한다면 타이머가 미처 해제되지 않은 상태에서 이미 해제된 객체를 사용하려고 하는 상태를 만날 수도 있습니다. 뭐, 자바스크립트에서 그런 상황이 쉽게 나올 것 같진 않지만요.
어쨌든 기본에 충실해야겠죠.

위의 예제에서도 잘못된 부분이 눈에 띄는게 가급적이면 m_divBG보다 m_imgGhost를 먼저 해제했어야 합니다.
왜냐면 m_imgGhost는 논리적으로 m_divBG의 자식 엘리먼트이기 때문인데요, 객체의 해제 순서는 항상 최하위 자식에서 최상위 부모의 순으로 해주는 것이 맞겠습니다.


휴우, 별 내용도 없는 설명은 2회로 끝낼려고 했는데 코드까지 붙이다 보니 너무 길어진 것 같습니다. 나머지 핵심 처리는 part 3.으로...

신고
Posted by gongdo


티스토리 툴바