본문 바로가기

동강의AS3.0 강좌

[Base] 3강 - MouseEvent, Event.ENTER_FRAME 활용


1, 2 강에서 Event 중 마우스 이벤트와 ENTERFRAME 이벤트에 대해 잠깐 훑어 보았습니다. 이 두가지 이벤트는 Flash 에서 가장 많이 쓰이는 이벤트에 불과 하고요( 하지만 굉장히 중요한 이벤트들 입니다 ) 상상하지 못할 별에 별 신기한 이벤트 들이 Actionscript 3.0 에 존재 하고 있고, 사용자는 단지 이벤트의 전달 구조만 이해 한다면 손 쉽게 사용할수 있습니다.  

시작에 앞서 사람들이 말하는 "F1 형님" 에 대해 알아 보겠습니다. F1 형님이란, Flash 에서 제공하는 도움말입니다. Actionscript 에서 제공하는 거의 모든 클래스를 포함하고 설명하고 예제로 사용법을 알려 주는 아주 편안한 도구 입니다.  

사용법은 그냥 F1 키를 누르면 도움말 기본이 뜨고 위에 있는 검색 창에 모르는 클래스나 함수를 써주게 되면 도움말에 들어 있는 파일중에서 그 단어가 포함된 링크들을 찾아 줍니다. ( 실제로 이 도움말은 html 파일로 되어 있습니다 )  



이건 단순한 사용법이고 좀더 효율적으로 해당 클래스를 찾으려면 아래 그림과 같이 문자열을 마우스로 드레그 하고 F1 을 누르면 해당 클래스나 메소드로 바로 이동하게 됩니다. ( 아래 그림에서는 MouseEvent ) 처음 시작할때 부터 F1 습관을 들여 놓는 것이, 실력이 쭉쭉쭉 향상 되는 지름길 입니다. 영어가 부담스러우신 분들은 CS3 한글판을 설치 하시던가,

  http://cafe.naver.com/flashactionscript/9310 

이글을 참고 하세요.

1. Event 이용하기

지금까지 배웠던 3 가지 이벤트로 간단한 크기 변환 버튼을 만들어 보겠습니다. 우선 Stage 에 자신이 원하는 버튼의 모양을 3개를 만들어 주세요. ( 이름을 : bu_mc1, bu_mc2, bu_mc3 이라 하겠습니다.


이름을 입력 하고 레이어를 추가한 후에 action 을 추가 하겠습니다. 

  1. bu_mc1.addEventListener(MouseEvent.MOUSE_OVER, Overhandler);
  2. bu_mc2.addEventListener(MouseEvent.MOUSE_OVER, Overhandler);
  3. bu_mc3.addEventListener(MouseEvent.MOUSE_OVER, Overhandler);
  4. bu_mc1.addEventListener(MouseEvent.MOUSE_OUT, Outhandler);
  5. bu_mc2.addEventListener(MouseEvent.MOUSE_OUT, Outhandler);
  6. bu_mc3.addEventListener(MouseEvent.MOUSE_OUT, Outhandler);
  7.  
  8. function Overhandler(event:MouseEvent):void
  9. {
  10.         trace("오버");
  11.  
  12. }
  13. function Outhandler(event:MouseEvent):void
  14. {
  15.         trace("아웃");
  16.  
  17. }

다 타이핑 하기 지겨우시지요? for문을 이용해서 간략화 하겠습니다.

  1. for(var i:int= 1; i < 4; i++)
  2. {
  3.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OVER, Overhandler);        
    // bu_mc1 를 [] 를 통해 표현하는방법
  4.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OUT, Outhandler);      
    // addEventListener 사이에 .() 이없다는것 주의
  5.  
  6.                                                                                                                    
  7. }
  8.  
  9. function Overhandler(event:MouseEvent):void
  10. {
  11.  
  12.  trace("오버");
  13. }
  14. function Outhandler(event:MouseEvent):void
  15. {
  16.  trace("아웃");
  17.  
  18. }

같은 기능을 수행 하지만 보기에 더 깔끔합니다. 그런데 6개의 Event 에 대해 작용하는 함수를 왜 두개 밖에 않만들었을까요? Actionscript 의 EventListener 는 함수를 이어 주는 역할만 하는게 아니라 이벤트가 발생한 객체와 이벤트를 전달할 객체 그리고 이벤트 자체에서 포함하고 있는 정보 들도 전달해 주는 기능을 합니다.

  1. event.target
  2.  
  3. function Overhandler(event:MouseEvent):void
  4. {
  5.    trace(event.target.name);
  6. }
  7. function Outhandler(event:MouseEvent):void
  8. {
  9.    traceevent.target.name);
  10.  
  11. }

어떤 결과가 나올까요???? 직접 해 보시기 바랍니다. 위와 같이 event 는 정보 덩어리 입니다. ( 위에서는 무비 클립의 name 속성을 이용했습니다 ) name 속성 뿐만 아니라 event.target.x , event.target.width, event.target.alpha 등등.. 전달되는 객체가 가지고 있는 ( 여기서 전달 되는 객체는 bu_mc 들이고, bu_mc 들은 MovieClip 으로 정의 했다는 거 기억 하시지요? ) 속성들을 알아 볼수 있습니다. ( 엄격하게 따지면 달라지는 경우도 있지만 여기에서는 그냥 넘어 가겠습니다.) 소스를 보다 보면 event.target 이 아니라 event.currentTarget 으로 전달 받는 경우가 있는데, 잠깐 언급하고 지나가겠습니다.

2. event.target , event.currentTarget 

 target <- 이벤트를 쏜놈 입니다. 보통은 EventDispatcher 이며 EventDispatcher를 상속받은 클래스. IEventDispatcher를 구현한 클래스만이 event.target 이 될 수 있습니다. currentTarget 은 보통은 화면에 출력되는 객체 입니다. DO와 DOC는 트리구조이죠. 간다한 예를 들어... 나무가 있습니다. 나무의 뿌리(target) 부분에 링겔(이벤트리스너)을 꼽습니다. 최초 뿌리 부분에서의 약물이 잎사귀 까지 가는 단계를 캡쳐 단계라 합니다. 약물이 잎사귀(타겟)에 도달한 후 다시 (약물을 전달한)수액은 뿌리로 돌아갑니다. 이것은 버블링 단계라 합니다. currentTarget 은 현재 (약물을 전달하는)수액이 어느지점에 있는가를 나타냅니다. - 퍼옴 

한마디로 target 은 이벤트를 발생 시킨 객체고 currentTarget 은 이벤트가 발생하는 객체 입니다. 따라서 target 과 currentTarget 이 같은 경우도 있고 달라지는 경우도 있습니다. 두가지를 잘 구분해서 써야 원하는 코딩이 이루어 질수 있습니다. ( 저도 확실하게 이해 하고 있지 않은 부분이라 더 깊게 들어 가는건 조금 공부를 더 한후에 하겠습니다.. ㅜㅡ;; 곧 수정하겠습니다. (2008-12-11)  

또 지겨운 이론을 이렇게 줄줄줄 늘어 놓았네요... 다시 돌아 와서 ..위와 같은 원리로 함수는 두개만 있어도 상관이 없다는 말을 하고 싶었습니다..   

변수를 추가 해서 제일 상단에 처음 width 값과 height 값을 저장합니다.
var ori_W = bu_mc1.width
var ori_H = bu_mc1.height           
// bu_mc 들은 모두 같은 크기 이기 때문에 임의로 bu_mc1 의 값을 저장 
 

그리고 변화 시키고 싶은 target 값을 지정하겠습니다.
var targetX = 120;
var targetY = 120; 
  1. var ori_W = bu_mc1.width
  2.  
  3. var ori_H = bu_mc1.height            // bu_mc 들은 모두 같은 크기 이기 때문에 임의로 bu_mc1 의 값을 저장
  4.  
  5.  
  6.  
  7. var targetW = 120;
  8.  
  9. var targetH = 120;
  10.  
  11.  
  12.  
  13. for(var i:int= 1; i < 4; i++)
  14. {
  15.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OVER, Overhandler);         // bu_mc1 를 [] 를 통해 표현하는방법
  16.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OUT, Outhandler);       // addEventListener 사이에
  17.  
  18.                                                                                                                     .() 이없다는것 주의
  19. }
  20.  
  21. function Overhandler(event:MouseEvent):void
  22. {
  23.  
  24.      event.target.width = targetW;
  25.      event.target.height = targetH;
  26.  }
  27. function Outhandler(event:MouseEvent):void
  28. {
  29.    event.target.width = ori_W;
  30.      event.target.height = ori_H;
  31.  
  32.  
  33. }
    실행! 생각한 대로의 결과 인가요?
  1. 그럼 여기에 부드러운 크기 변화를 위한 ENTER_FRAME 이벤트를 적용해 보겠습니다. fpt 는 36으로 조절
    var ori_W = bu_mc1.width
  2. var ori_H = bu_mc1.height            // bu_mc 들은 모두 같은 크기 이기 때문에 임의로 bu_mc1 의 값을 저장
  3. var targetW = 120;
  4. var targetH = 120;
  5. for(var i:int= 1; i < 4; i++)
  6. {
  7.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OVER, Overhandler);  
  8.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OUT, Outhandler);    
  9.                                                                                                      
  10. }
  11.  
  12. function Overhandler(event:MouseEvent):void
  13. {
  14.  
  15.    event.target.addEventListener(Event.ENTER_FRAME, enterframehandler);    
  16.    
  17. }
  18. function Outhandler(event:MouseEvent):void
  19. {
  20.    event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);    
  21.    
  22. }
  23. function enterframehandler(event:Event):void
  24. {
  25.  if(targetW > event.target.width){        // targetW 에서 정한 크기보다 작을때 까지 +3 씩 해 준다.
  26.   event.target.width += 3;                    
  27.   event.target.height += 3;
  28.  }
  29.  else                                              // 그 크기가 되면 이벤트 삭제
  30.   event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);
  31.  
  32.  
  33. }

아놔...  왜 크게만 되고 작게는 안되요?


  1. var ori_W = bu_mc1.width
  2. var ori_H = bu_mc1.height            // bu_mc 들은 모두 같은 크기 이기 때문에 임의로 bu_mc1 의 값을 저장
  3. var targetW = 120;
  4. var targetH = 120;
  5. for(var i:int= 1; i < 4; i++)
  6. {
  7.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OVER, Overhandler);  
  8.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OUT, Outhandler);    
  9.                                                                                                      
  10. }
  11.  
  12. function Overhandler(event:MouseEvent):void
  13. {
  14.  
  15.  event.target.addEventListener(Event.ENTER_FRAME, enterframehandler);    
  16.    
  17. }
  18. function Outhandler(event:MouseEvent):void
  19. {
  20.    event.target.addEventListener(Event.ENTER_FRAME, enterframehandler2);    
  21.    event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);    
  22.  
  23.    
  24. }
  25. function enterframehandler(event:Event):void
  26. {
  27.  if(targetW > event.target.width){
  28.   event.target.width += 3;
  29.   event.target.height += 3;
  30.  }
  31.  else
  32.   event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);
  33.  
  34.  
  35. }
  36. function enterframehandler2(event:Event):void
  37. {
  38.  if(ori_W < event.target.width){
  39.   event.target.width -= 3;
  40.   event.target.height -= 3;
  41.  }
  42.  else
  43.   event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler2);
  44.  
  45.  
  46. }


코드가 점점 길어 짐니다.. 으악!!! 어떻게 코드를 줄일수 있을까요? if 문을 사용해 봅시다.

  1. var ori_W = bu_mc1.width
  2. var ori_H = bu_mc1.height            // bu_mc 들은 모두 같은 크기 이기 때문에 임의로 bu_mc1 의 값을 저장
  3. var targetW = 120;
  4. var targetH = 120;
  5. var bo:Boolean = false;
  6. for(var i:int= 1; i < 4; i++)
  7. {
  8.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OVER, Overhandler);  
  9.  this["bu_mc"+i].addEventListener(MouseEvent.MOUSE_OUT, Outhandler);    
  10.                                                                                                      
  11. }
  12.  
  13. function Overhandler(event:MouseEvent):void
  14. {
  15.  bo = true;
  16.  event.target.addEventListener(Event.ENTER_FRAME, enterframehandler);    
  17.    
  18. }
  19. function Outhandler(event:MouseEvent):void
  20. {
  21.   bo = false;
  22.  event.target.addEventListener(Event.ENTER_FRAME, enterframehandler);    
  23.  
  24. }
  25. function enterframehandler(event:Event):void
  26. {
  27.  if(bo){
  28.   if(targetW > event.target.width){
  29.    event.target.width += 3;
  30.    event.target.height += 3;
  31.   }
  32.   else
  33.   {
  34.    event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);
  35.    bo = false;
  36.   }
  37.  }
  38.  else
  39.  {
  40.   if(ori_W < event.target.width){
  41.    event.target.width -= 3;
  42.    event.target.height -= 3;
  43.   }
  44.   else{
  45.    event.target.removeEventListener(Event.ENTER_FRAME, enterframehandler);
  46.    bo = true;
  47.   }
  48.  }
  49.  
  50. }


bo 값을 이용해 ture, false 를 조절해서 enterframehandler 를 하나로 줄였습니다. 어렵다고요?
제가 봐도 어렵습니다. 최종 코드를 하나하나 타이핑 해 보시고, 이 ENTERFRAME 과 MouseEvent 와의 이벤트 전달 관계를 잘 이해해야 뒤에 나오는 더 어려운 이벤트들의 관계를 이해 할수 있을꺼라 생각이 됩니다. 우리의 생각을 컴퓨에서 전달하기 위해서는 한글을 이해를 못하는 멍청한 컴퓨터를 배려 해서 10101111111001 로 전달해 줘야 되는데 그 10101111101의 중심에는 if 문이 있습니다. 잘 활용하면 명검이 될수도 있고 잘 활용못한다면 무수히 많은 에러로 인해 프로그램을 망가뜨릴수 있으니 잘 이해 하고 넘어 가세요. 

버튼 크기 바꾸는데 왜이리 복잡하냐!!!!!!!!! 라고 말하시는 분들을 위해

 위의 방법을 쓴 것은 ENTERFRAME 의 이해를 위해서 사용한 것이고, actionscript 에는 알아서 계산해 주는 Tween 이라는 클래스가 있습니다. 위의 방법은 강력한 Tween 클래스를 사용하기 전의 연습단계이고,, Tween클래스는 좀 후에 다루겠습니다. 궁금하신 분들은 Tween 클래스를 F1 에서 찾아 보는것도 좋을것 같습니다.  

ps : 위와 같이 enterframe 을 하나로 사용하면 문제가 발생합니다. 왜 발생하는 것일까요?  
       생각해 봅시다.

 

 문제 수정전 swf 파일