2010년 4월 15일 목요일

MovieClip클래스 - play(),stop(),nextFrame(),prevFrame(),gotoAndStop()

 

- MovieClip 객체에는 이렇게 상속된다.

 

 

- MovieClip객체는 위와 같이 여러 클래스들을 상속받게되어 무겁다. 그래서 Sprite클래스를 Linkage에서

  Base클래스로 써도 무방하다. 그러나 프레임 제어를 할때에는 반드시 MovieClip을 상속받아야 한다.

  만약 프레임 제어를 하는데도 그대로 Sprite를 Base Class로 사용하게 된다면 함수를 사용할 수 없다고

  에러 메세지가 나타나게 된다. 위에서의 그림처럼 MovieClip에서 정의되어 있는 메소드들이 있는데 더적은

  범위에 있는 Sprite를 받은 상태에서 MovieClip에 메소드를 사용하려니 당연히 그 함수는 사용할 수 없다는

  에러 메세지가 나올 수 밖에 없는 것이다.

 

- 예를 들어 50프레임쯤에서 stop()을 하고 싶은데 stop()이라는 메소드가 MovieClip에 있다.

에러 메세지

 

레퍼런스에서의 정의

 

- 이런 것들을 고려하여 무비클립에 정의된 메소드들을 이용한 간단한 예제를 만들어 보았다.

 

 

 

MC_Animation.as

[code as3]
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;

public class MC_Animation extends Sprite
{
    public function MC_Animation()
    {
        super();

        config();
    }

    //-------------------------------------------------------------
    //
    //     Variables
    //
    //-------------------------------------------------------------
    private var isPlaying:Boolean = false; //재생버튼을 제어할 Boolean형의 객체 변수

    private var baseFps:int = stage.frameRate; //2배속재생버튼의 속도를 제어할 int형의 객체 변수

    //-------------------------------------------------------------
    //
    //     Properties
    //
    //-------------------------------------------------------------
    /**
     *    @private
     *    초기값 설정. 이벤트 등록과 버튼모양 변경
     */
    private function config() : void
    {
        pic.stop(); //모션이 들어간 무비클립 pic을 stop()으로 멈춤.

        //각종 버튼들에 버튼모드를 손모양으로 변경
        next_mc.buttonMode = true;
        prev_mc.buttonMode = true;
        play_mc.buttonMode = true;
        pause_mc.buttonMode = true;
        stop_mc.buttonMode = true;
        play_2_mc.buttonMode = true;

        //각종 버튼마다 움직임 정의할 이벤트 등록
        next_mc.addEventListener( MouseEvent.CLICK, nextClickHandler );
        prev_mc.addEventListener( MouseEvent.CLICK, prevClickHandler );
       
        play_mc.addEventListener( MouseEvent.CLICK, ppsClickHandler );
        pause_mc.addEventListener( MouseEvent.CLICK, ppsClickHandler );
        stop_mc.addEventListener( MouseEvent.CLICK, ppsClickHandler );

        play_2_mc.addEventListener( MouseEvent.CLICK, play2ClickHandler );
    }

    /**
     *    @private
     *    next_mc를 click하였을 때 움직임
     */
    private function nextClickHandler( e:MouseEvent ) : void
    {
        if( pic.currentFrame == pic.totalFrames ) //현재 프레임과 총 프레임수를 비교하여 같다면,
        {
            pic.gotoAndStop(1); //다시 처음 프레임으로 이동

            return; //if문을 빠져나온다
        }

        pic.nextFrame(); //처음 프레임으로 이동 후 계속 한 프레임씩 이동
    }

    /**
     *    @private
     *    prev_mc를 click하였을 때 움직임
     */
    private function prevClickHandler( e:MouseEvent ) : void
    {
        if( pic.currentFrame == 1 ) //현재 프레임이 1이라면,
        {
            pic.gotoAndStop( pic.totalFrames ); //다시 맨 끝 프레임으로 이동

            return; //if문을 빠져 나온 뒤,
        }

        pic.prevFrame(); //nextFrame()과 반대로 이전 프레임으로 한 프레임씩 이동
    }

    /**
     *    @private
     *
     *    @param e.target : play_mc, pause_mc, stop_mc 무비클립
     *    play_mc, pause_mc, stop_mc를 click하였을 때의 움직임
     */
    private function ppsClickHandler( e:MouseEvent ) : void
    {
        switch( e.target ) //이벤트로 넘겨받은 인스턴스가
        {
            case play_mc : //play_mc라면,

                if( isPlaying ) //isPlaying이 true라면, 즉 재생되고 있다면
                {
                    pic.stop(); //재생을 멈추고
                }
                else //isPlaying이 false라면, 즉 멈춰있다면
                {
                    stage.frameRate = baseFps; //초당 프레임 속도를 확인해주고

                    pic.play(); //다시 재생해줌
                }

                isPlaying = !isPlaying; //바뀐 Boolean값을 바꾸어 줌

                break; //빠져나옴

            case pause_mc : //e.target이 pause_mc 일시정지 버튼을 클릭했다면

                pic.stop(); //프레임 재생을 그대로 멈추어주고

                break; //빠져나옴

            case stop_mc : //e.target이 stop_mc 정지 버튼을 클릭했다면

                pic.gotoAndStop(1); //재생하고 있던 프레임을 맨 처음 프레임으로 가서 멈추게하고,

                break; //빠져나옴
        }
    }

    /**
     *    @private
     *    play_2_mc를 click하였을 때 움직임
     */
    private function nextClickHandler( e:MouseEvent ) : void
    {
        stgae.frameRate = 24; //현재 stgae에 정의되어 있는 초당 프레임 속도보다 2배 빠르게.

        pic.play(); //프레임 재생
    }
}
}
[/code]

- 106번째 줄에서 왜 다시 초당 프레임 속도를 다시 확인해주는가에 대한 것을 보면, 2배속으로 빠르게 재생

   하는 함수에서 24로 초당 프레임을 바꾸어 주었기 때문이다. 예를 들어, 재생 버튼을 눌러서 재생하다가

   중간에 2배속 재생 버튼을 누른 후 다시 재생 버튼을 눌러주게 되면 컴퓨터상에서는 stage의 frameRate를

   그전에 바꾸어 놓았던 24의 속도로 기억하고 있기 때문에 다시 한번 fla파일에서 원래 지정해 주었던 24의

   반의 속도인 baseFps 12의 속도로 넣어줘야 한다. 그래야 정상적인 재생 속도를 확인할 수 있다.

 

   또 2배속 재생 버튼을 누르다가 재생버튼을 누르면 멈추는 이유는 100번째 줄을 보면 알 수 있다. 재생할

   때에 편리성을 위해 재생버튼에 일시정지 기능도 함께 넣은 것이나 마찬가지 이다.

 

   isPlaying이라는 Boolean형의 객체변수를 20번째줄에서 false로 정의 내린 것을 if문을 활용하여 참, 거짓

   에 따라 재생해라, 멈춰라의 기능을 넣어준 것이다. 만약 20번째 줄에서 false를 true로 바꾸어 준 후, 재생

   버튼을 누르게 되면 두번을 클릭해야 원하는 재생을 할 수 있다.

 

* 참고로, pic을 그냥 막그린 저런 배경 틀에 맞게 나오게 하기 위해서는 Mask효과를 사용하였다.

  약간의 노가다 적인 배경에 맞춘 mask를 씌울 shape을 펜툴로 그린 다음 모션이 들어간 그림위에 레이어

  를 위치시킨 후, 마우스 오른쪽 클릭하여 Mask를 하면 펜툴로 그린 모양만큼만 효과가 적용되어 마치 배경

  그림을 따라 그림이 나오는 것 같은 효과를 볼 수 있다.

 

 

- 레퍼런스에서 Mask에 대한 정의를 잠깐 살펴보면, DisplayObject클래스에서 정의되어진 메소드이다.

 

이 메소드를 클래스로 만들어서 코드에 적용시켜보면 이렇다.

[code as3]
package
{
import flash.text.TextField;
import flash.display.Sprite;
import flash.events.MouseEvent;

public class maskSample extends Sprite
{
    public function maskSample()
    {
        super();

        config();
    }
 
    private var tf:TextField = new TextField();

    private var square:Sprite = new Sprite();

    /**
     *    @private
     *    화면에 나오는 요소들 초기값 설정
     */
    private function config() : void
    {
        //TextField로 생성한 객체 tf에 text를 넣음
        tf.text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
                + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
                + "Lorem ipsum dolor sit amet, consectetur adipisicing elit, "
                + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "

        tf.selectable = false; //텍스트필드 선택가능여부 false

        tf.wordWrap = true; //줄바꿈

        tf.width = 150; //텍스트 필드의 넓이

        addChild(tf); //화면에 붙임

        square.graphics.beginFill(0xFF0000); //Sprite로 생성한 객체에 빨간색 채움
 
        square.graphics.drawRect(0, 0, 40, 40); //가로 40 세로 40 크기의 사각형을 그림

        addChild(square); //화면에 붙임

        tf.mask = square; //텍스트 필드위에 Sprite형의 객체를 mask처리함

        tf.addEventListener(MouseEvent.MOUSE_DOWN, drag); //Drag를 위한 MouseDown 이벤트 등록
        tf.addEventListener(MouseEvent.MOUSE_UP, noDrag); //Drag를 위한 MouseUp 이벤트 등록
    }

    private function drag(event:MouseEvent):void
    {
        square.startDrag(); //사각형을 눌렀을 때 드래그 시작
    }

    private function noDrag(event:MouseEvent):void
    {
        square.stopDrag(); //사각형을 눌렀다 떼면 드래그 멈춤
    }
}
}
[/code]

예제 출처

 

 

- 코드에서는 Sprite형의 객체에 사각형을 그린후 빨간색으로 색을 채웠음에도 불구하고 안나오는 이유는

   mask처리를 해주었기 때문에 영역만 잡히고 색은 적용은 되었지만 화면상에서는 보이지 않는다.

   MC_Animation.as 예제에서 fla파일에 직접 빨간색의 Shape를 mask해준 것과 같은 것이다.

 

댓글 없음:

댓글 쓰기