본문 바로가기
♣ 강좌/플래시

메뉴 만들기 (6) hitTest()의 이해...왜 hitTest()가 필요한가?

by 칠칠너래 2006. 3. 25.

정말 간만에 강좌를 올릴 시간이 났네요..

오전만..잠깐 났어요.

오후 부터는 또 웹프로그래머랑 서로 연동 부분 맞쳐 봐야 하거든요.

아직 웹 프로그래머님이 저랑 연동 할 부분이 준비가 안 되어 있어서..ㅎㅎ

 

오늘은 hitTest에 대해 알아 Boa 요..

 

그럼 왜 메뉴를 만들때 hitTest 가 필요한지 부터 아셔야 겠죠?

 

플래시의 매력 중에 하나가 인터렉션이라고 할 수 있습니다.

사용자의 반응에 의해 플래시가 반응을 하는 거지요.

 

그럼 플래시는 사용자의 반응을 어떻게 알 수 있을까요?

 

마우스 이벤트 관련

 

1. 마우스의 움직임

2. 마우스의 왼쪽 클릭

3. 마우스의 오른쪽 클릭

4. 마우스 휠의 움직임

 

 

키보드 이벤트 관련

 

1. 키보드의 입력(esc키 제외 ㅡ.ㅡ)

 

버튼 이벤트 관련

 

1. 버튼에 롤오버

2. 버튼에 롤아웃

3. 버튼 릴리즈

4. 버튼 릴리즈 아웃

5. 버튼 프레스

6. 버튼 드래그 오버

7. 버튼 드래그 아웃

 

 

요렇게 될 수 있겠네요..

 

이런걸 통해서 사용자와 플래시가 대화를 할 수 있는거네요..

 

우리가 메뉴를 만들 때 많이 쓰는 이벤트가

버튼 이벤트 중 롤오버, 롤아웃, 릴리즈 이벤트가 되겠네요..

 

우선 이3가지를 이해를 정확하게 해야겠죠..

 

1. 버튼 롤오버

마우스 커서가 버튼의 힛 영역 밖에서 버튼의 힛 영역 안으로 들어갈 때 발생합니다.

 

버튼 인스턴스에 직접 입력 (이벤트 핸들러 형식)

on(rollOver) {

 실행할 액션

}

 

프레임에 입력 (콜백 함수 형식)

btn.onRollOver = function () {

 실행할 액션

}

 

 

2. 버튼 롤아웃

버튼의 롤오버 상태에서 마우스 커서가 버튼의 힛 영역 밖으로 나갈 때 발생합니다.

 

버튼 인스턴스에 직접 입력 (이벤트 핸들러 형식)

on(rollOut) {

 실행할 액션

}

 

프레임에 입력 (콜백 함수 형식)

btn.onRollOut= function () {

 실행할 액션

}

 

3. 버튼 릴리즈

마수스로 버튼을 눌렀다가 뗐을 때 발생합니다.

 

버튼 인스턴스에 직접 입력 (이벤트 핸들러 형식)

on(release) {

 실행할 액션

}

 

프레임에 입력 (콜백 함수 형식)

btn.onRelease= function () {

 실행할 액션

}

 

다 아시는 거겠지만..다시한번 적어 보았습니다.

 

대부분의 메뉴가 하나로 구성 된 것이 아니라

하나의 메뉴안에 또 다른 서브메뉴를 가지고 있는 구조입니다.

 

메뉴 1        메뉴 2     메뉴 3

 

서브 1       서브 1      서브 1

서브 2       서브 2      서브 2

서브 3       서브 3      서브 3

 

이런 형태를 가지게 되는 거죠..

그리고 우리가 메뉴 1에 마우스가 롤 오버 했을 때

메뉴가 쭉 펼처 지면서

서브 1, 2, 3의 메뉴가 보이게 됩니다.

 

아래의 SWF 를 보시길 바래요..

 


 

마우스를 올려 보았나요?

 

어떤 현상이 일어 나나요?

노랑 원에다 마우스를 올려 놓으면 버튼 이벤트 중 롤 오버 이벤트가 잘 작동 됩니다.

빨강원도 마차가지구요..

 

이제 문제가 발생하기 시작합니다.

노랑원과 빨강원이 겹치는 부분에 마우스를 살포시 가져 갑니다.

 

우리의 예상은

노랑원과 빨간원의 롤 오버 이벤트가 다 작동 되길 원합니다.

하지만 플래시는 2개의 버튼 영역이 겹칠 때에는 상위의 스팩*1에 있는 버튼의 이벤트만 발생하게 됩니다.

따라서 빨강원(제가 2번째로 만든 원입니다..따라서 빨강원의 스팩이 더 높습니다.)의 이벤트만 발생하게 되는 겁니다.

노랑원 depth(-16383)보다 빨간원 depth(-16381) 가 높기 때문입니다.

플래시에서 수동으로 인스턴스를 만들면 -16383 부터 2씩 올라가는 뎁쓰를 가지게 됩니다.

 

다시위에 꺼를 가져와서 보면


 

메뉴 1        메뉴 2     메뉴 3

 

서브 1       서브 1      서브 1

서브 2       서브 2      서브 2

서브 3       서브 3      서브 3

 

메뉴 1번을 롤 오버 했을 때

서브 1,2,3이 보여줘야 하는데..

그 서브1, 2, 3 을 릴리즈 했을 때도

이벤트가 발생 되어야 합니다.

 

근데 서브 1,2,3 도 버튼이고 메뉴 1번도 버튼입니다.

보통의 서브 1, 2, 3은 메뉴 1번의 안에 있게 됩니다.

따라서 버튼안에 버튼이 있게 되는 형태 이므로..

안에 있는 버튼은 버튼 이벤트가 발생하지 않게 됩니다.

 

이를 해결 할 수 있게 하는 것이 hitTest() 입니다.

 

몰론 hitTest() 안 쓰고도 마스크를 잘 활용하면 똑같은 결과의 메뉴들을 만들 수 있습니다.

하지만 hitTest() 를 써야지만 만들 수 있는 멋진 메뉴들도 있답니다.

 

또 길어 졌습니다.

2번째 시간으로 hitTest() 를 넘겨야 겠네요^^

 

 

 

참고 *1

 

플래시의 스택 구조...

우리가 흔히 플래시에 있는 타임라인을 보면 레이어 들이 있습니다.

2개의 오브젝트(심볼)이 있을 때

높은 레이어에 있는 것이 위에 놓이게 됩니다.

이럴때 높은 레이어에 있는 오브젝트가 밑에 있는 레이어의 오브젝트 보다

스팩이 높다고 말할 수 있습니다.

 

플래시에서의 가장 하위의 스택은 내부 레이어 스팩입니다.

타임라인 상에서 같은 레이어에 있을 때 Modify>Arrange 명령을 통해서

서로 겹치는 것의 스택을 바꾸 수 있습니다.

 

그 다음이 실제 레이어에 의해서 결정 되는 스택이고

 

액션을 통해 생성된 클립은 수동으로 만든 클립보다 높은 스택을 가지게 됩니다.

attachMovie(), duplicateMovieClip() createEmptyMovieClip() 등을 통해서

생성되는 클립이 액션으로 만들어진 클립입니다.

 

이보다 더 상위에 있는 것은 level 개념입니다.

위의 것들이 플래시 내부간의 스택이었다면

level은 swf간의 개념입니다.

 

다시 정리하자면

 

level>depth>layer>arrange

 

의 개념을 생각하면 됩니다..

하위의 스택 구조가 아무리 높아도

상위의 스택 구조가 낮으면 화면상에 보일 때 아래에 위치 하게 됩니다.

 

즉, b라는 무비클립의 뎁쓰가 1000 이고

a의 무비클립의 뎁쓰가 1이라고 할지라도

a의 level 이 2이고

b의 level 이 1이면

a가 위에 보이게 되는 겁니다.

 

또한 b클립이 화면상의 가장 상위의 레이어에 있으면서 depth가 100 이라도

a 클립의 depth가 101 이면

a가 위에 보이게 됩니다.