2010년 4월 17일 토요일

BitmapData클래스

 

- BitmapData는 Object클래스에서 상속받는다. 이 BitmapData클래스는 bitmapData속성을 사용하여 Display

  패키지(DisplayObject) 안에 정의 되어 있는 Bitmap객체를 픽셀 데이터로 처리 할 수 있다. 또 Loader를 통

  해 로드한 비트맵 이미지에서도 액세스가 가능하다.

  Bitmap클래스는 구조가 InteractiveObject와 Shape와 같은 레벨에 있기 때문에 InteractiveObject에서

  정의되어 있는 마우스 이벤트 전달을 할 수 없다. 그러나 Bitmap를 포함하는 DisplayObjectContainer의

  addEventListener()로는 가능하다.

 

*BitmapData는 비트맵 이미지를 로드할 때 픽셀 제한이 있으므로 미리 크기를 고려하여 로드한다.

     Flash Player 10에서는 BitmapData 객체의 최대 높이 또는 폭의 크기가 8,192픽셀이며 총 픽셀 수는

     16,777,216픽셀을 초과할 수 없다. 따라서 객체의 폭이 8,192이고 높이가 2,048픽셀 이하인 이미지를 로드

     해야한다. Flash Player 9 이전 버전은 제한 픽셀이 2,880 * 2,880픽셀이다.

 

- BitmapData에서 이미지를 로드하는 과정을 보면 이렇다.

   플레시에서 이미지를 Load하는 순간 flash에서 비트맵 데이터로 분석하고 DisplayObect가 화면에 표시를

   해준다. 화면에 표시를 해준걸 Edit possible을 해줘. 편집이 가능 하도록 변경해준다.

   여기서 편집가능하다는 말이 비트맵 데이터로 분석한 과정에서 그 이미지를 Capture해서 우리가 포토샵

   같은 곳에서 핸들링 할수 있도록 해주는 기능과 같다는 것이다.

 

   예를 들어, 사진의 실제 크기가 2000 * 3000이라 치면 Load클래스에서 정의된 loader라는 객체는 실제로

   가벼운데 이 큰 사진을불러 오는 순간 무거워지게 된다. 그래서 불러오기 전에 크기를 stage의 크기로 줄

   여서 캡쳐를 뜨고 그 다음에 축소된 사진을 불러오는 것이다. 그럼 원래 크기인 2000 * 3000인 stage를 넘

   어서는 커다란 사진이 불러와서는 딱 stage크기만해지니 훨씬 가벼워질 수 있는 것이다.

 

   그러데 여기서 이렇게 크기를 scaelX속성을 사용하여 축소시키면 addChild()가 되지 않는다. 따라서 이럴

   떄에는 Graphics를 사용하여 그리면 되는데 Graphics에는 beginFill을 bitmap으로 대신 넣어서 그려넣는

   beginBitmapFill()메소드를 사용하면 된다.

 

   여기서 이미지를 불러오는 과정에 BitmapData에서 draw()라는 메소드가 있는데 여기에 파라미터값으로

   넘기는 값중에 soure라는 파라미터가 있다.

  

  

   그 값은 IBitmapDrawable이라는 인터페이스에서 구현되어져 있는데 이 인터페이스는 이미 DisplayObject

   에서 정의 되어져 있어서 그릴 수 있다. 눈에 보이는 모든 것들은 Sprite를 통해 DisplayObject를 상속 받아

   져 있기 때문에 source 매개변수에 loader를 써도 된다는 것이다.

 

* 여기서 인터페이스는 회사의 계약서라고 생각하면 된다. 명시만 해주는 것으로 아래와 같이 써준다.
[code as3]
public class Main extends Sprite implements IMain
[/code]

또 실제 인터페이스 인 IMain.as속 소스는..

[code as3]
public function a() : void{}

[/code]

이런식으로 메소드만 정의된 형태로 들어가있다.
여기서 접근자는 무조건 public이어야 한다.

아무내용이 없더라고 IMain에서 명시되어져 있는 함수를 무조건 Main에서 사용해야 한다. 형태 그대로..

파마미터가 있으면 있는대로...!!

 

인터페이스는 프로그래밍하는 개발자에게 길잡이 역할을 하는 것이나 다름 없다. 아직 완전히 와닿지는

않으나 여기까지만 알아두면 좋겠다.

 

 

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해준 것과 같은 것이다.

 

2010년 4월 10일 토요일

ScrollBar - 스크롤바2(슬라이더)

 

- 이번 예제는 스크롤바의 바닥 부분(?)도 클릭하였을때 bar가 클릭한 부분으로 이동되며 그 위치도

  TextField부분에 나오도록 바꾸어 보았다.

  그러기 위해서 stick부분이 원래 단순shape였는데 무비클립으로 바꾸어주고 Sprite로 Linkage해준다.

 

 

- 그리고 인스턴스 네임을 stick으로 준다.

 

 

- 우선 결과물을 보면 이렇다.

 

 

ScrollBarExample.as

[code as3]
package classes.SliderBotton
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Rectangle;

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

        config();
    }

    //--------------------------------------------------------------
    //
    //     Variables
    //
    //--------------------------------------------------------------
    private var min:Number = 0; //stick의 최소값을 0으로 초기화

    private var max:Number = 200; //stick의 최대값을 200으로 초기화

    private var length:Number = 300; //stick의 길이를 300으로 초기화

    private var pos:Number;

    //--------------------------------------------------------------
    //
    //     Properties
    //
    //--------------------------------------------------------------
    /**
     *    @private
     *    초기값 설정
     */
    private function config() : void
    {
         bar.buttonMode = true; //bar의 마우스모양을 손모양으로 변경
 
         stick.buttonMode = true; //stick의 마우스모양을 손모양으로 변경

         bar.addEventListener( MouseEvent.MOUSE_DOWN, barDownHandler ); //마우스를 눌렀을 때 bar에 이벤트 등록

         stick.addEventListener( MouseEvent.CLICK, stickClickHandler ); //마우스를 클릭했을 때 stick에 이벤트 등록
    }

    /**
     *    @private
     *    bar를 눌렀을 때 움직이는 동작
     */
    private function barDownHandler( e:MouseEvent ) : void
    {
        bar.addEventListener( Event.ENTER_FRAME, showTxt ); //bar를 클릭했을 때 textField에 나올동작을 enterFrame으로 이벤트 등록

        var bounds:Rectangle = new Rectangle( 0, 0, 300, 0 ); //

        bar.startDrag( bounds );

        stage.addEventListener( MouseEvent.MOUSE_UP, stageUpHandler );
    }

    /**
     *    @private
     *    stage에서 MouseUp 이벤트 감지후 제거
     */
    private function stageUpHandler( e:MouseEvent ) : void
    {
         bar.removeEventListener( Event.ENTER_FRAME, showTxt ); //enterFrame이벤트 제거
         
         bar.stopDrag(); //Drag동작을 정지시킴

        stage.removeEventListener( MouseEvent.MOUSE_UP, stageUpHandler ); //stage에서 MouseUp이벤트 제거
    }

    /**
     *    @private
     *    TextField에 위치 출력
     */
    private function showTxt( e:Event ) : void
    {
        pos = Math.round( ( bar.x * ( max - min ) ) / length - min ); //pos변수에 stick과 bar의 위치를 구한 공식을 대입. 변수들이 다 Number로 선언되었기 때문에 round()로 정수로 변환후 대입

        txt.text = String( pos ); //textField에 pos를 String형으로 변환하여 대입
    }

    /**
     *    @private
     *    stick을 클릭했을 때 동작
     *
     *    @param e : EnterFrame동작의 Event
     */
    private function stickClickHandler( e:MouseEvent ) : void
    {
         bar.x = mouseX; //mouse의 x좌표를 bar의 x좌표로 변경

         showTxt(e); //showTxt() 함수를 호출. stick의 위치를 textField로 출력하기 위함
    }
}
}
[/code]

- 저번 예제와 또 다른점은 stick의 길이를 300으로 넓혀주었다. 저번 예제에서는 stick의 길이도 200으로

  하여 그냥 단순히 bar의 x좌표를 String으로 변환하여 textField로 넣어주었는데 이번에는 stick의 길이에

  상관없이 최소값과 최대값을 정하여 그 값으로 나오게 하는 것이다.

 

  이번에는 저번 예제에서 구한 pos라는 비율을 적용해 보았다. 그럼 stick의 길이가 300인데도 불구하고

  min값과 max값을 정하여 원래 값으로 나눠주는 과정에서 200의 비율로 textField값이 나오게 된다.

  또 84번째줄에서 이렇게 해주면 pos와 min, max 등이 Number값이기 때문에 소수점이 나오기 때문에

  Math함수에서 round()메소드를 사용하여 pos값을 0.5값이 나오면 가까운 정수로 올림하여 적용시켜 준다.

  *잠깐, Math.round()에 관한 내용을 보면 이렇다.

 

  93번째 줄에서는 stick 부분을 클릭하였을 때의 동작 부분으로 마우스로 stick부분을 클릭하였을 때 bar를

  이동시키는 방법은 단순히 stick부분을 클릭하는 동작을 마우스가 하게 되므로 마우스의 x좌표를 bar의

  x좌표로 대입시켜주면 bar의 위치가 이동되게 되는 것이다. 그리고 그 값을 bar의 값과 동일하기 때문에

  showTxt()함수를 호출하여 주었다. showTxt()는 위에 이벤트 등록시 매개변수 값으로 이벤트값을 가지고

  오게 되므로 매개변수 값도 함께 넣어서 호출해주었다.

 

 

 

2010년 4월 6일 화요일

scrollbar - 스크롤바(슬라이더)

 

- 스크롤바를 만들어 봄으로써 볼륨바, 컨텐스 스크롤, 다양한 조절기능을 할 수 있다.

 

 

 

sliderButton.as
[code as3]
package classes.SliderButton
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.geom.Rectangle;

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

        bar.buttonMode = true; //버튼 모드 변경

        bar.addEventListener( MouseEvent.MOUSE_DOWN, downHandler ); //bar에 마우스이벤트 등록
    }

    /**
     *    @private
     *    bar를 mouseDown했을 때의 효과적용
     */
    private function downHandler( e:MouseEvent ) : void
    {
        bar.addEventListener( Event.ENTER_FRAME, showTxt ); //bar에 enterFrame이벤트 등록

        var bounds:Rectangle = new Rectangle( 0, 0, 200, 0 ); //Rectangle클래스 객체 생성 및 초기화

        bar.startDrag( true, bounds ); //lockCenter를 가운데로 true, bounds값 적용, drag 시작

        stage.addEventListener( MouseEvent.MOUSE_UP, upHandler ); //stage에 마우스이벤트 등록
    }

    /**
     *    @private
     *    마우스를 뗐을때 효과적용
     */
    private function upHandler( e:MouseEvent ) : void
    {
        bar.removeEventListener( Event.ENTER_FRAME, showTxt ); //bar에 등록되었던 이벤트 제거

        bar.stopDrag(); //drag 멈춤

        stage.removeEventListener( MouseEvent.MOUSE_UP, upHandler ); //stage에 등록된 이벤트 제거
    }

    /**
     *    @private
     *    텍스트 필드에 값 적용
     */
    private function showTxt () : void
    {
        txt.text = String( bar.x ); //화면에 Text가 bar의 x좌표 값으로 적용
    }
}
}
[/code]


- 이 예제는 네모난 무비클립 bar를 움직일 때 마다 그 위치가 텍스트 필드에 찍히게 하는 예제이다.

  화면에 미리 무비클립을 생성하고 Linkage를 SliderButton으로 해주고, 텍스트 필드는 Dynamic Text로

  설정해준다. Dynamic TexFeild로 해주어야 다른 값들을 받아 올 수 있다.

 

  startDrag에서 bounds를 지정해준 것은 width가 200인 영영안에서만 동작할 수 있도록 보이진 않지만

  드래그의 위치를 bar의 무비클립 시작지점에서 200만큼만 지정해준 것이다.
  그리고 밑에 stage에 이벤트를 등록해준 이유는 3.0에서는 onReleaseOutside라는 이벤트가 없어졌기

  때문에 마우스가 bar의 영역을 벗어나더라도 어디서나 감지 할 수 있도록 더 넓은 범위인 stage로 감지하

  여 remove하도록 이벤트를 걸어주었다.
 

  showTxt함수에서 TextField값을 bar의 x좌표로 적용해줄때 bar.x의 값은 소스에서 정의되어 있지 않아도

  자동 Number값이기 때문에 텍스트로 들어가기 위해서 String으로 변환하여 적용해주는 것이다.

 

  여기서 만약 드래그를 하는데 있어서 0~200의 값이 아닌 0~200범위 안에서 0~100의 범위를 갖게 하려면

  [code as3]
   txt.text = String( bar.x / 2 );
  [/code]
  이런식으로.. 그렇다면 -100~100의 범위를 갖게 하고 싶다면?

  [code as3]
   txt.text = String( ( bar.x / 2 ) * 2 - 100 );
  [/code]
  조금씩 난해해진다.. 그래서 이것을 공식으로 완성시켜보면!

  비례식으로 풀어보면,

  200 : bar.x = ( max - min ) : ( pos - min ) 이 되는데

 

 pos = ( bar.x * ( max - min ) ) / 200 - min

 

  이라는 식이 나온다.

 

  이렇게 나온 결과값으로 showTxt에 bar.x가 아닌 pos를 대입해보면 0~200이 아닌 min과 max의 값에 따라

  원하는 값을 얻을 수 있게 된다.

 

 

2010년 4월 5일 월요일

FileReference클래스

 

- FileReference클래스는 사용자 컴퓨터와 서버 사이에서 파일을 업로드, 다운로드 할 수 있는 방법을 제공

  한다. 우리가 흔히 파일을 받아서 저장하는 기능을 플래시에서도 구현할 수 있다는 것이다.

  FileReference도 일종의 PC와 서버사이의 통신을 하는 것에 속하므로 flash.net 패키지에 포함된다.

  FileReference에도 여러가지 메소드들이 있는데 그중 browser()라는 메소드를 보면,

 

 

  업로드할 파일을 선택할 수 있는 운영체제 대화 상자를 뜨게하는 메소드이다. 이 메소드는 한번에 하나만

  수행할 수 있다. 만약 FileReference.browser(); 하게되면 이런 창이 뜨는 것이다.

 

 

여기에서 매개변수로 browse(typeFilter:Array = null)typeFilter라는 배열객체로 들어가는데

파일을 필터링하는데 사용되는 인스턴스 배열이라고 한다. 파일을 필터링하는 것은 사용자가 선택할

수 없고 지정되지 않은 확장명이라던지 파일형에 관한 필터링을 하는 것을 말한다.

예를 들어 FileFilter는 이런식이다.

[code as3]
var imageFilter:FileFilter = new FileFilter( "Image", "*.jpg, *.gif, *.png" );
var myfr:FileReference = new FileRefence();
myfr.browser( [imageFilter] );
[/code]

* 업로드와 다운로드는 Flash Player에서 파일의 크기를 제한하지 않지만, 공식적으로 100MB이하

업로드 또는 다운로드를 지원한다고 한다. upload()와 download()메소드는 비차단 방식으로 만일

FileReference 객체의 범위를 벗어나는 경우 즉 업로드와 다운로드 파일전송이 완료되지 않은 상태에서

범위를 벗어나면 취소가 된다.

 

업로드는 upload(request:URLRequest, uploadDataFieldName:String = "Filedata", testUpload:Boolean = false)이렇다.

- request는 통신객체로 HTTP post 형식의 호출을 통한 url이 포함되어 있어야 한다.

- uploadDataFieldName은 파일 데이터 앞에오는 필드이름이다. null이면 안된다.

- testUpload는 Boolean값으로 true인 경우, 파일크기가 10KB보다 크면 FlashPlayer는 내용의 길이가 0인

  테스트 파일 업로드 POST를 한다.

 

다운로드는 download(request:URLRequest, defaultFileName:String = null)이렇다.

- request는 로컬 컴퓨터로부터 다운로드할 파일의 URL이 포함되어야 한다. 이 매개변수가 null일 경우 예외

  가 발생하므로 반드시 써줘야한다. 또 일반 브라우저에서 URL문자열의 길이가 제한이 있으므로 256보다 긴

  경우는 다운로드를 실패할 수도 있다.

- default는 다운로드할 파일의 기본 파일 이름으로 / | : * ? " < > 등 특수문자는 포함될 수 없다.

 

download()메서드는 운영체제 대화상자를 열어서 파일을 선택하고 저장할 위치를 선택하고 다운로드를 하겠다는 버튼을 누르면 서버에서 바로 다운로드를 실시하게 된다. 이 과정에서 다운로드를 하면서 파일을 선

택하여 저장하는 과정이 있는데 이 과정에서 save()메소드가 그 중요한 역할을 한다.

 

저장 메서드는 save(data:*, defaultFileName:String = null) 이런값이 있다.

- data는 저장할 데이터로 이 값도 null이 되면 ArgumentError 예외를 발생시킨다. 이 매개변수는 다양한 형

  태에 따라 다르게 처리 되는데 그 다양한 형식을 보면,

  값이 String인 경우 UTF-8 텍스트 파일로 저장되어지고 XML인 경우는 텍스트 파일에 XML형식으로 유지해

  주고, ByteArray객체인 경우라도 그대로 기록해주고 그외의 값인 경우는 save()메서드가 toStrng()메서드를

  호출하여 데이터를 문자열로 변환하여 텍스트 파일에 저장한다. 이작업이 실패가 되면 예외가 발생한다.

 

 

 

 

2010년 4월 3일 토요일

callBack - 콜백함수를 이용한 paricle예제

 

기존에 쓰던 parent속성은 종속관계가 있어 강한 결합을 만들기 때문에 대신 약한 결합인 콜백함수를 써보자

 

 

Particle.as

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

import classes.display.Seed;

public class Particle extends Sprite
{
    public function Particle()
    {
        super();
   
        config();
    }

    /**
     *    @private
     *    stage에 MouseMove이벤트 등록
     */
    private function config() : void
    {
        stage.addEventListener( MouseEvent.MOUSE_MOVE, mouseMoveHandler );
    }

    /**
     *    @private
     *    seed객체 생성과 초기화
     */
    private function mouseMoveHandler( e:MouseEvent ) : void
    {
        var seed:Seed = new Seed(); //seed객체 Sprite로 생성

        seed.onTransParent = seedTransParent; //Seed.as에 함수에 seedTransParent 대입

        seed.x = mouseX; //seed의 x좌표값을 현재 마우스의 x좌표로 대입
        seed.y = mouseY; //seed의 y좌표값을 현재 마우스의 y좌표로 대입

        var ratio:Number = Math.random(); //ratio라는 변수에 랜덤값 생성

        seed.scaleX = ratio; //seed의 scaleX를 ratio로 대입
        seed.scaleY = ratio; //seed의 scaleY를 ratio로 대입

        seed.alpha = Math.random(); //seed의 alpha값을 랜덤하게 만듦

        addChild( seed ); //화면에 seed를 붙임
    }

    /**
     *    @private
     *    display라는 매개변수로 표시객체를 제거
     */
    private function seedTransParent( display:DisplayObject ) : void
    {
        removeChild( display );
    }
}
}
[/code]


Seed.as
[code as3]
package classes.display
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;

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

        vx = Math.random() * 10 - 5; //x좌표의 속도를 -5~5사이
        vy = Math.random() * 10; //y좌표의 속도를 0~10사이

        gravity = 1; //중력가속도의 값은 1

        addEventListener( Event.ENTER_FRAME, alphaEnterFrameHandler );
    }

    //-----------------------------------------------------
    //    variables
    //-----------------------------------------------------
    private var vx:Number; //x 속도
    private var vy:Number; //y 속도
  
    private var gravity:Number; //중력가속도 변수

    private var _onTransParent:Function; //function객체 생성. _onTransParent = null

    //-----------------------------------------------------
    //     properties
    //-----------------------------------------------------
    public function set onTransParent( value:Function ) : void
    {
        _onTransParent = value;
    }

    public function get onTransParent() : Function
    {
        return _onTransParent;
    }

    /**
     *    @private
     *    중력가속도와 속도, alpha와 scaleX scaleY, color 등 효과 적용
     */
    private function alphaEnterFrameHandler( e:Event ) : void
    {
        vy = vy + gravity; //속도y좌표에 중력가속도를 더함

        this.x += vx; //seed의 x좌표에 속도x씩 더함
        this.y += vy; //seed의 y좌표에 속도y씩 더함

        this.alpha -= 0.05; //seed의 alpha를 0.05씩 감소시킴

        this.scaleX += 0.05; //seed의 scaleX에 0.05씩 더함
        this.scaleY += 0.05; //seed의 scaleY에 0.05씩 더함

        var ct:ColorTransform = this.transform.colorTransform; //colorTransform객체 생성

        ct.color = Math.random() * 0xFFFFFF; //위에서 생성한 ct에 랜덤 색상을 넣어줌

        this.transform.colorTransform = ct; //seed의 색상을 ct의 랜덤컬러로 변경

        if( alpha < 0 ) //seed의 알파가 0.05씩 줄어서 0보다 작으면 true, 아니면 false
        {
            removeEventListener( Event.ENTER_FRAME, alphaEnterFrameHandler ); //alpha가 0이면 enterFrameEvent제거

            if( _onTransParent != null )
            {
                _onTransParent( this );
            }
        }
    }
}
}
[/code]


- Particle클래스에서 Seed클래스에 있는 Function으로 생성된 함수를 참조하는 것이다.

  마치 매개변수를 넘겨주듯이 하면 된다. 데이터를 넘겨줄 때 이벤트를 써서 하는 방법도 있는데

  그 방법은 이벤트 클래스를 만들고 dispatch해주는 작업에서 딜레이가 되기 때문에 보다 빠르고

  다이렉트한 방법으로 콜백함수를 쓴다
 

  Particle클래스에서 26번째줄에 stage에 MouseMove이벤트를 등록해준 것은 마우스를 stage어느 곳에서

  이리저리 움직일 때마다 원이 나왔다 사라지게 하기 위해 MouseMove이벤트를 등록해준 것이다.

  mouseMoveHandler함수는 앞에 예제에서 해보았던 것들 처럼 seed의 객체를 생성해서 그 seed에 여러

  가지 color, alpha, x와 y좌표 등의 효과를 적용시키는 부분이다.


  객체는 여는 중괄호와 닫는 중괄호로만 존재한다면 객체라 할 수 있다. 따라서 function도 객체에 속하기

  때문에 변수로 선언하여 값을 넘겨주는게 자연스럽게 이루어진다.

 

2010년 4월 2일 금요일

Duplicate - 다양한 객체 만들기(복제-패턴2)

 

- 한 무비클립을 복제하여 패턴을 만드는 예제를 하였었는데, 스터디 선생님의 권유로 약간 변형을 해보았다

 

 

  랜덤으로 색이 바뀌게 하는 네번째 버튼을 없애고 애초에 페이지에 진입하면 Timer 이벤트로 저절로 색이

  바뀌도록 바꿔보았다.

 

 

[code as3]
package
{
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.MouseEvent;
import flash.events.IEventDispathcer;
import flash.geom.ColorTransform;

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

        seedBox = new Sprite();

        seedBox.x = 80;
        seedBox.y = 20;

        addChild( seedBox );

        createButton();

        colorTimerConfig(); //타이머 이벤트 함수 호출
    }

    private var seedBox:Sprite;

    private var normalBtn:Sprite;

    private var alphaBtn:Sprite;

    private var scaleBtn:Sprite;

    private var colorBtn:Sprite;

    private var row:int = 8;

    private var col:int = 10;

    private var tot:int = row * col;

    private var gap:Numer = 30;

    /**
     *   @private
     *   랜덤컬러로 나오는 함수에 타이머 이벤트 등록
     */
    private function colorTimerConfig() : void
    {
        var timer:Timer = new Timer( 400, 10 ); //400/1000초, 10번 Timer객체 생성

        timer.start(); //타이머 시작

        timer.addEventListener( TimerEvent.TIMER, createColor ); //timer객체에 이벤트 등록
    }

    private function createButton() : void
    {
        var g:Graphics;

        if( !normalBtn )
        {
            normalBtn = new Sprite();

            g = normalBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            normalBtn.x = 20;
            normalBtn.y = 20;

            normal.buttonMode = true;

           addChild( normalBtn );

           configListener( normalBtn );
        }

        if( !alphaBtn )
        {
            alphaBtn = new Sprite();

            g = alphaBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            alphaBtn.x = 20;
            alphaBtn.y = normalBtn.y + gap;

            alphaBtn.buttonMode = true;

           addChild( alphaBtn );

           configListener( alphaBtn );
        }

        if( !scaleBtn )
        {
            scaleBtn = new Sprite();

            g = scaleBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            scaleBtn.x = 20;
            scaleBtn.y = alphaBtn.y + gap;

            scaleBtn.buttonMode = true;

           addChild( scaleBtn );

           configListener( scaleBtn );
        }

        if( !colorBtn )
        {
            colorBtn = new Sprite();

            g = colorBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            colorBtn.x = 20;
            colorBtn.y = scaleBtn.y + gap;

            colorBtn.buttonMode = true;

           addChild( colorBtn );

           configListener( colorBtn );
        }
    }

    private function configListener( dispatcher:IEventDispatcher ) : void
    {
        dispatcher.addEventListener( MouseEvent.CLICK, btnClickHandler );
    }

    private function btnClickHandler( e:MouseEvent ) : void
    {
        switch( e.target )
        {
            case normalBtn :
                createNormal();
                break;

            case alphaBtn :
                createAlpha();
                break;

            case scaleBtn :
                createScale();
                break;

            case colorBtn :
                createColor(e); //TimerEvent매개변수를 createColor함수에 넘김
                break;
        }
    }

    private function removeAllChild() : void
    {
        while( seedBox.numChildren )
        {
            seedBox.removeChildAt( 0 );
        }
        removeEventListener( TimerEvent.TIMER, createColor ); //버튼을 클릭할때마다 TimerEvent 제거
    }

    private function createNormal() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            seedBox.addChild( temp );
        }
    }

    private function createAlpha() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            temp.alpha = i / tot;

            seedBox.addChild( temp );
        }
    }

    private function createScale() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            temp.scaleX = temp.scaleY = i / tot;
         
            seedBox.addChild( temp );
        }
    }

    private function createColor() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            var ct:ColorTransform = new ColorTransform();
           
            ct.color = Math.random() * 0xFFFFFFFF;

            temp.transform.colorTransform = ct;

            seedBox.addChild( temp );
        }
    }
}
}
[/code]

- TimerEvent를 걸어준 부분은 앞 예제와 동일하고, TimerEvent를 추가하여 생성자에서 타이머 객체가 있는

  함수를 호출한다. 그래서 바로 0.4초마다 createColor함수를 10번 호출한다.

 

2010년 4월 1일 목요일

Duplicate - particle

 

- particle은 아주 작은 조각을 의미하는 것으로 seed를 마치 조각처럼 사용하여 또다른 복제를 표현.

 

 

 

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

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

        config();
    }

    /**
     *   @private
     *   fps 변경 및 이벤트 등록
     */
    private function config() : void
    {
        stage.frameRate = 48; //1초당 프레임 속도를 48로 변경

        stage.addEventListener( MouseEvent.MOUSE_DOWN, downHandler );
        stage.addEventListener( MouseEvent.MOUSE_UP, upHandler );
    }

    /**
     *   @private
     *   마우스 DOWN시, EnterFrame 이벤트 등록
     */
    private function downHandler( e:MouseEvent ) : void
    {
        stage.addEventListener( Event.ENTER_FRAME, particle );
    }

    /**
     *   @private
     *   마우스 UP시, EnterFrame 이벤트 제거
     */
    private function upHandler( e:MouseEvent ) : void
    {
        stage.removeEventListener( Event.ENTER_FRAME, particle );
    }

    /**
     *   @particle
     *   마우스 x, y좌표를 객체에 대입
     */
    private function particle( e:Event ) : void
    {
        var temp:Sprite = new Seed(); //Sprite 객체 생성

        temp.x = mouseX; //현재 마우스의 x좌표를 생성한 객체의 x좌표에 대입.
        temp.y = mouseY; //현재 마우스의 y좌표를 생성한 객체의 y좌표에 대입.

        temp.alpha = Math.random(); //alpha값은 0~1사이 랜덤값
       
        temp.scaleX = temp.scaleY = Math.random() * 3; //temp의 크기는 0~3사이 랜덤값

        addChild( temp ); //화면에 표시객체를 붙여줌
    }
}
}
[/code]

 

- 앞에서 했던 예제중에 버튼을 누르면 크기와 알파값이 랜덤으로 조정되어져 찍히는 것과 같은 결과이지만,

  사용자가 마우스를 클릭하는 순간 그 위치에서만 생기는게 다른점이다.

  따라서 복제하는 방식은 같고 단지 Sprite객체로 생성해준 temp의 x와 y좌표에 현재 클릭상태로 움직여지고

  있는 stage상에서의 x와 y 좌표를 EnterFrame이벤트가 발생할 때마다 넣어주는 것이다.

  여기서 스치고 지나갈뻔한 소스는 43번째줄에 upHandler함수에서의 removeEventListener() 이다.

  통상 addEventListener만 해보았지 등록한 이벤트를 제거한적은 없었던 것 같다.

  이 메서드 역시 addEventListener()메서드 처럼 EventDispatcher클래스에 의해서 정의 되어져 있다.

  등록되어있던 것을 제거해주는 것이므로 매개변수도 등록했던 것을 지우려는 것과 동일한 조건으로 써준다

 

 만약 일치하지 않는다면 이 메서드를 호출해도 아무 영향도 없기 때문이다.

2010년 3월 31일 수요일

Duplicate - 겹치지 않게 복제하기(충돌감지)

 

- 충돌을 감지하면서 복제하기.

 

 

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

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

        config();
    }

    private var holder:Array = new Array();

    private function config() : void
    {
        stage.frameRate = 40;

        stage.addEventListener( Event.ENTER_FRAME, enterFrameHandler );
    }

    private function enterFrameHandler( e:Event ) : void
    {
        var box:Sprite = new Seed();

        box.x = Math.random() * stage.stageWidth;
        box.y = Math.random() * stage.stageHeight;

        box.scaleX = Math.random() * 2;

        holder.push( box );

        if( isOK( box ) )
        {
            addChild( box );

            var glow:GlowFilter = new GlowFilter();

           glow.color = Math.random() * 0xFFFFFF;

           box.filters = [ glow ];
        }
        else
        {
            holder.pop();
        }
    }

    private function isOK( mc:Sprite ) : Boolean
    {
        var i:int = 0;

        var count:Number = holder.length - 1;

        for( i = 0; i < count; i++ )
        {
            var flag:Boolean = holder[i].hitTestObject( mc );

            if( flag )
            {
                return false;
                break;
            }
        }
        return true;
    }
}
}
[/code]



-> 이 예제는 객체를 만들때 이전에 만들었던 표시 객체와 같은 위치에 나타내지 않도록 하는 것이다.

     앞에서 했던 충돌감지 메소드 hitTestObject()를 사용하여 먼저 만들어진 객체와 새로 만들어진 객체가

     충돌되지 않는 위치에 배치하는 것이다.

 

     15번째 줄에서 holder는 밑에서 만들 별모양의 표시객체를 참조할 Array이다. 앞전에 만들어진 객체와

     현재 만들어진 객체의 충돌을 감지하기 위해서 Array의 인덱스를 사용해 비교하면 편하고 참조를 통해

     빠르게 비교할 수 있기 때문이다. 객체를 단지 한 두개를 비교할 때가 아닌 지금처럼 많은 객체들이 있어

     비교할 때는 Array를 사용하면 보다 편하다.

     33번째 줄에서 Array로 만든 holder에 push()메서드를 이용하여 배열에 끝에 넣는다.

     19번째 줄에서 frameRate는 흔히 fla파일에서 보는 fps(Frame Per Second)를 액션스크립트에서 설

     정해주는 것이다. 초당 프레임으로 1초당 40프레임으로 속도를 변경해주었다.

     그 다음 stage에 이벤트를 추가해주었다. EnterFrame 이벤트를 추가해주어 enterFrameHandler를 보면,

     box를 앞에서와 마찬가지로 Sprite를 확장한 클래스인 Seed클래스로 생성하여 주었고, 랜덤하게 위치를

     stage안에서만 생성되도록 해주었다. 가끔 밖으로 별이 튀어 나가는 것은 별 객체의 중심점이 가운데로

     설정되어 있어서 이다.

 

     35번째줄에서 if문 조건에서 isOK() 함수값이 true이면 즉, isOK()함수의 반환값이 Boolean값인데 그

     box가 (매개변수로는 mc가 되겠다) 이전에 만들어진 array에 들어있는 객체들과 모두 hitTestObject로 겹

     침여부를 비교 하였을 때 겹쳐졌으면 즉 flag = true면 isOK()함수 반환값이 false이므로 pop()해주고,

     만약 반대로 겹치지 않았다면 리턴값이 true이므로 box를 addChild()를 해준다.

    

     addChild를 해준 후 화면에서 보이는 바와 같이 앞전 예제에서 했던 GlowFilter클래스와 random함수를

     이용하여 테두리색이 랜덤으로 나오게 해준다. 랜덤으로 나오게 하기 위해서 GlowFilter에서 glow라는

     객체를 생성하고 그 객체에 color 속성으로 랜덤한 색상을 넣어준다음 box에 filters 속성으로 이용해

     glow객체에서 나온 랜덤한 색상을 적용시켜 주는것이 43번째까지의 내용이다.

 

     만약 if문에서의 조건이 false라면은 pop()을 해주는데, pop() 메소드는 push()메소드와 반대로 꺼내는

     메소드이다. 여기서 꺼내주는 이유는 위 예제에서 box를 Sprite로 생성시키자마자 holder array에 곧바로

     push를 시켜주는데 if문 조건이 false라는 의미가 겹쳐졌다라는 말이므로 addChild를 시켜줄 필요도 없고

     glow를 적용시킬 필요도 없으므로 곧바로 넣어주었던 box를 다시 꺼내는 것이다(pop).

     pop() 메소드는 이렇게 이해하면 되겟다.

   

2010년 3월 30일 화요일

Duplicate - 다양한 객체 만들기(복제-패턴)

 

- 복제를 이용해 Grid(격자)모양을 만들어 보는 예제.

 

 

[code as3]
package
{
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.MouseEvent;
import flash.events.IEventDispathcer;
import flash.geom.ColorTransform;

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

        seedBox = new Sprite();

        seedBox.x = 80;
        seedBox.y = 20;

        addChild( seedBox );

        createButton();
    }

    private var seedBox:Sprite;

    private var normalBtn:Sprite;

    private var alphaBtn:Sprite;

    private var scaleBtn:Sprite;

    private var colorBtn:Sprite;

    private var row:int = 8;

    private var col:int = 10;

    private var tot:int = row * col;

    private var gap:Numer = 30;

    private function createButton() : void
    {
        var g:Graphics;

        if( !normalBtn )
        {
            normalBtn = new Sprite();

            g = normalBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            normalBtn.x = 20;
            normalBtn.y = 20;

            normal.buttonMode = true;

           addChild( normalBtn );

           configListener( normalBtn );
        }

        if( !alphaBtn )
        {
            alphaBtn = new Sprite();

            g = alphaBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            alphaBtn.x = 20;
            alphaBtn.y = normalBtn.y + gap;

            alphaBtn.buttonMode = true;

           addChild( alphaBtn );

           configListener( alphaBtn );
        }

        if( !scaleBtn )
        {
            scaleBtn = new Sprite();

            g = scaleBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            scaleBtn.x = 20;
            scaleBtn.y = alphaBtn.y + gap;

            scaleBtn.buttonMode = true;

           addChild( scaleBtn );

           configListener( scaleBtn );
        }

        if( !colorBtn )
        {
            colorBtn = new Sprite();

            g = colorBtn.graphics;

            g.clear();
            g.beginFill( 0xFFFFFF, 1 );
            g.drawRect( 0, 0, 50, 20 );
            g.endFill();

            colorBtn.x = 20;
            colorBtn.y = scaleBtn.y + gap;

            colorBtn.buttonMode = true;

           addChild( colorBtn );

           configListener( colorBtn );
        }
    }

    private function configListener( dispatcher:IEventDispatcher ) : void
    {
        dispatcher.addEventListener( MouseEvent.CLICK, btnClickHandler );
    }

    private function btnClickHandler( e:MouseEvent ) : void
    {
        switch( e.target )
        {
            case normalBtn :
                createNormal();
                break;

            case alphaBtn :
                createAlpha();
                break;

            case scaleBtn :
                createScale();
                break;

            case colorBtn :
                createColor();
                break;
        }
    }

    private function removeAllChild() : void
    {
        while( seedBox.numChildren )
        {
            seedBox.removeChildAt( 0 );
        }
    }

    private function createNormal() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            seedBox.addChild( temp );
        }
    }

    private function createAlpha() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            temp.alpha = i / tot;

            seedBox.addChild( temp );
        }
    }

    private function createScale() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            temp.scaleX = temp.scaleY = i / tot;
         
            seedBox.addChild( temp );
        }
    }

    private function createColor() : void
    {
        removeAllChild();

        var i:int = 0;

        for( i = 0; i < tot; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = ( i % col ) * 40 + gap;
            temp.y = Math.floor( i / col ) * 40 + gap;

            var ct:ColorTransform = new ColorTransform();
           
            ct.color = Math.random() * 0xFFFFFFFF;

            temp.transform.colorTransform = ct;

            seedBox.addChild( temp );
        }
    }
}
}
[/code]

 

 

- 복제하는 형태는 앞서 한 예제에서 같은 형태이고 복제한것을 Grid 형태로 찍는 것이다. 그리고 또 다른점

  은 버튼을 fla파일에서 직접 만들어 넣었다면 이번 예제에서는 Graphics클래스를 이용하여 만든다.

 

  처음 맨 밑바닥의 도화지 역할을 하는 seedBox를 Sprite로 객체를 생성하여 addChild해주고, 버튼들도

  그 위에 좌표를 설정해주어 각각 만들어 준다.

 

 

  161번째 줄은 버튼을 클릭할 때마다 생성되는 seedBox를 지우고 다시 그려주는 부분이다.

  버튼을 누를때마다 각각의 seed 무비들이 마구 나오면 알아볼 수 없기 때문에 numChild라는 속성을 이용

  하여 numChild가 있다면( numchild = 1 ) removeChildAt이라는 속성으로 지워준다. numChild가 한개라서

  1이지만 지울때의 메소드에서는 인덱스로 인식하기때문에 0이라고 해준다.

 

  격자로 찍기 위해서 공식을 이용하여 x와 y좌표에 적용시키면 되는데 위에서는 가로 10줄, 세로 8줄로 미리

  정의를 하고 나머지공식을 이용하여 공식을 만들었다.

  for문에서 tot까지 계속해서 1씩 증가하는 i 변수와 고정값인 col변수를 나누어 나오는 나머지와 seed클래스

  에서 생성되는 무비클립이 적정한 크기로 떨어져서 생성되도록 40을 곱하고 30을 더해준다. y좌표도 마찬가

  지로 공식을 구하여 적용시킨다. i 인덱스가 0부터 시작하므로 Math클래스에서 내림메소드 floor를 이용하

  여 적용시킨다.

  이렇게 x좌표와 y좌표의 결과를 찍어보면,

  30 / 30
  70 / 30
  110 / 30
  150 / 30
  190 / 30
  230 / 30
  270 / 30
  310 / 30
  350 / 30
  390 / 30

  30 / 70
  70 / 70
  110 / 70
  150 / 70
  190 / 70
  230 / 70
  270 / 70
  310 / 70
  350 / 70
  390 / 70
  30 / 110
  70 / 110
  110 / 110
  150 / 110
  190 / 110
  230 / 110
  270 / 110
  310 / 110
  350 / 110
  390 / 110

  ....

  이런 값이 적용되어 80개의 seed가 위와 같은 모양으로 찍히게 된다. 열의 간격은 나머지가 똑같은 수로

  나누기 때문에 패턴이 같은 식으로 나오게 되고, 행의 간격은 40씩 증가하게 되는 결과가 나온다.

2010년 3월 27일 토요일

Duplicate - 다양한 객체 만들기(복제-random,alpha,glow)

2.0에서 무비클립을 만들어 복제하고자 했을 때 이런식으로

[code as3]
_root.attachMovie( "Box", "mc", 0 );
_root.createEmptyMovieClip( "mc", 0 );
Box.duplicateMovieClip( "mc", 0 );
[/code]
빈 무비클립을 만들어 복제하는 형태였다면,

 

3.0에서의 복제는 new를 사용해 만들기만 하면 된다.

[code as3]
var mc:Box = new Box();
var mc:MovieClip = new MovieClip();
[/code]

예제를 보면 이렇다.

 

 

for문을 이용해 Seed클래스를 100번 실행하여 만든다.

 

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

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

        seedBox = new Sprite();

        addChild( seedBox );

        buttonMode = true;

        config();
    }

    private var seedBox:Sprite;

    private var seedNum:Number = 100;

    private function config() : void
    {
        normalBtn.addEventListener( MouseEvent.CLICK, btnClickHandler );
        alphaBtn.addEventListener( MouseEvent.CLICK, btnClickHandler );
        glowBtn.addEventListener( MouseEvent.CLICK, btnClickHandler );

        setChildIndex( seedBox, 0 );
    }

    private function btnClickHandler( e:MouseEvent ) : void
    {
        switch( e.target )
        {
            case normalBtn :
                createNormal();
                break;

            case alphaBtn :
                createAlpha();
                break;

            case glowBtn :
                createGlow();
                break;
        }
    }

    private function removeAllChild() : void
    {
        while( seedBox.numChildren )
        {
            seedBox.removeChildAt(0);
        }
    }

    private function createNormal() : void
    {
        removeAllChild();

        var i:int  = 0;

        for( i = 0; i < seedNum; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = Math.random() * stage.stageWidth;
            temp.y = Math.random() * stage.stageHeight;

            seedBox.addChild( temp );
        }
    }

    private function createAlpha() : void
    {
        removeAllChild();

        var i:int  = 0;

        for( i = 0; i < seedNum; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = Math.random() * stage.stageWidth;
            temp.y = Math.random() * stage.stageHeight;

            temp.scaleX = temp.scaleY = Math.random() * 2;

            temp.alpha = Math.random();

            seedBox.addChild( temp );
        }
    }

    private function createGlow() : void
    {
        removeAllChild();

        var i:int  = 0;

        for( i = 0; i < seedNum; i++ )
        {
            var temp:Sprite = new Seed();

            temp.x = Math.random() * stage.stageWidth;
            temp.y = Math.random() * stage.stageHeight;

            temp.scaleX = temp.scaleY = Math.random() * 2;

            temp.alpha = Math.random();

            temp.filters = [ new GlowFilter() ];

            seedBox.addChild( temp );
        }
    }
}
}
[/code]

-> 버튼 세개는 stage에 무비클립으로 미리 만들어 주었고, 동그라미 모양의 무비클립은 Seed라는 클래스를

    Sprite클래스를 확장한 형태로 Linkage를 주었다. 모션이 없으므로 가볍게 하기 위해 역시 Sprite로 하였

    다. 버튼을 누를 때마다 100개의 seed가 만들어 지면서 상황에 따라 알파값이 들어가거나 크기가 랜덤하

    게 찍히거나 혹은 glow 값을 넣어주었다.

    여기서 glow값을 쓰기 위해서 GlowFilter를 import 해주었다. glow는 우리가 흔히 포토샵에서 사용하게

    되는 테두리를 변형해주는 ↓

    Blendong툴인데 이것을 액션스크립트로도 적용할 수가 있다는 것이다.

   

    액션스크립트에서 GlowFilter() 생성자를 보면 이렇다.

   
    소스에서 처럼 아무것도 지정해주지 않았을 때 기본값으로 빨간색이 나오게 되는 것이다. 나머지 값들도

    지정해주는 것에 따른 효과를 볼 수 있게 된다.

   

     32번째줄에 보면 setChildIndex(child:DisplayObject, index:int)메소드를 써준 이유

    는 seedBox에서 생성되는 100개의 seed들이 stage에 올려놓은 버튼을 가려서 생성되기 때문에 간혹 버

    튼을 가려 버튼의 역할을 못하게 막는 경우가 있어서 쉽게말해 seedBox의 depth를 0으로 준 것이다. 그럼

    맨 밑으로 가게 되어 버튼 세개가 위로 올라오게 된다.

    표시 객체가 여러 개일 경우 지정해준 인덱스에 대해서만 바뀌게 되고 나머지는 그대로이다.

   

    예를 들어,

    [code as3]
    setChildIndex( getChildAt(1), 0 );
    [/code]
    이렇게 해주면 밑에 그림처럼 인덱스가 바뀌게 된다.

   

 

- 출처 : http://help.adobe.com/ko_KR/AS3LCR/Flash_10.0/index.html?flash/display/Graphics.html&flash/display/class-list.html

   

2010년 3월 26일 금요일

Sprite 클래쓰 - Drag & Drop( 영역 대 포인트 : hitTestPoint )

 

- hitTestPoint( x:Number, y:Number, shapeFlag:Boolean = false ) 메소드는 영영 대 영역과

   다르게 매개변수인 x와 y의 위치로 겹침 여부를 따진다. 여기서 shapeFlag는 표시 객체의 실제 픽셀과의

   겹침을 판단할 것인지 아니면 경계 상자로 판단할 것인지의 여부이다. 기본값은 false를 갖는다. 밑에서의

   예제처럼 true를 하면 별모양 무비클립의 x와 y좌표가 stage에 있는 글자와 직접적으로 겹쳐야 메소드의

   반환값을 true로 준다.

 

 

[code as3]
package classes.view
{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flahs.utils.Timer;

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

        config();
    }

    private function config() : void
    {
        var timer:Timer = new Timer( 300, 50 );

        timer.addEventListener( TimerEvent.TIMER, timerHandler );

        timer.start();
    }

    private function timerHandler() : void
    {
        var star:Star = new Star();

        star.tx = Math.random() * 3 + 1;
        star.ty = Math.random() * 3 + 1;

        addChild( star );

        start.addEventListener( Event.ENTER_FRAME, enterFrameHandler );
    }

    private function enterFrameHandler( e:Event ) : void
    {
        var mc:MovieClip = MovieClip( e.target );

        if( mc.x < 0 || mc.x > stage.stageWidth )
        {
            mc.tx = -mc.tx;
        }

        if( mc.y < 0 || mc.y > stage.stageHeight )
        {
            mc.ty = -mc.ty;
        }

        if( kjh.hitTestPoint( mc.x, mc.y, true ) )
        {
            mc.gotoAndStop(2);
            mc.rot = -5;
        }
        else
        {
            mc.gotoAndStop(1);
            mc.rot = 5;
        }

        mc.x = mc.tx;
        mc.y = mc.ty;
        mc.rotation = mc.rot;
    }
}
}
[/code]

Timer클래스를 이용해서 300/10000초에 tiemrHandler함수를 50번 호출한다.

random()함수를 이용해서 tx라는 변수에 1~3사이의 난수를 넣어놓고, 그 난수를 star.tx에 넣어 둔다.

star에 이벤트 등록을 하고 enterFrameHandler 함수에서 이벤트를 통해 e.target(star)를 MovieClip으로

형변환 시킨다.

여기서 형변환을 하는 이유는 http://help.adobe.com/ko_KR/AS3LCR/Flash_10.0/index.html?flash/display/Graphics.html&flash/display/class-list.html 여기에서 보는 바와 같이 target 이라는 속성

자체가 Object로 인식되기 때문에 MovieClip클래스를 확장한 Star 클래스로 star라는 객체를 생성해도

MovieClip이 아닌 단지 Object라 반드시 "형 변환" 을 시켜준다.

그리고 mc의 x, y좌표가 양 쪽 끝이나 stage에 위, 아래에 닿으면 반대방향으로 튕겨 움직이도록 좌표값을

-로 바꿔 넣어준다.

hitTestPoint의 메소드로 겹침여부를 확인한 후, true이면 mc를 2번째 프레임으로 가게해서 노랑색으로

바꾸어 주고, 5도만큼 반대방향으로 각도를 바꿔주면서 tx만큼 간다.

 

 

* hitTestPoint 메소드를 위 예제처럼 TextField를 이용하여 적용시키려면 비트맵 형태로 바꾸어 주어야

      한다. TextField에서 글자를 모두 선택 후, Ctrl + "B" 를 두번 해주어야 비트맵의 형태로 바뀐다.

     

 

2010년 3월 25일 목요일

Sprite 클래쓰 - Drag & Drop( 영역대영역 : hitTestObject )

 

- hitTestObject( obj : DisplayObject ) 메소드는 표시 객체의 경계 상자를 평가하여 obj 표시객체의

   경계 상자와 겹치거나 교차하는지 확인한다. obj는 테스트할 표시 객체이다. 반환값은 true, false로..

 

 

예제를 보면,

 

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

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

        alpha_a.buttonMode = true;
        alpha_b.buttonMode = true;

        alpha_a.addEventListener( MouseEvent.MOUSE_DOWN, AstartDragHandler );
        alpha_a.addEventListener( MouseEvent.MOUSE_UP, AstopDragHandler );
        alpha_b.addEventListener( MouseEvent.MOUSE_DOWN, BstartDragHandler );
        alpha_b.addEventListener( MouseEvent.MOUSE_UP, BstopDragHandler );
    }

    private function AstartDragHandler( e:MouseEvent ) : void
    {
        alpha_a.startDrag();
        alpha_a.alpha = 0.5;
    }

    private function AstopDragHandler( e:MouseEvent ) : void
    {
        if( alpha_a.hitTestObject( alphaFrame_a ) )
        {
            alpha_a.x = alphaFrame_a.x;
            alpha_a.y = alphaFrame_a.y;
        }

        alpha_a.alpha = 1;
    }

    private function BstartDragHandler( e:MouseEvent ) : void
    {
        alpha_b.startDrag();
        alpha_b.alpha = 0.5;
    }

    private function BstopDragHandler( e:MouseEvent ) : void
    {
        if( alpha_b.hitTestObject( alphaFrame_b ) )
        {
            alpha_b.x = alphaFrame_b.x;
            alpha_b.y = alphaFrame_b.y;
        }

        alpha_b.alpha = 1;
    }
}
}
[/code]

-> buttonMode가 true이면, 마우스 포인터를 Sprite객체위에 놓으면 모양을 손가락 모양으로 바꾼다.

* 그런데 만약 Sprite 객체로 버튼을 만들어 꾸며서 사용할 경우에는 buttonMode = true 속성 뿐 아니라,

useHandCursor = true 속성과 mouseChildren = false 를 함께 적용해주면 예기치 않은 동작에서 벗어 날

수 있다.

useHandCursor는 기본값이 true인데 이 속성은 buttonMode = true인 상태에서 손 모양 커서를 표시하겠다는 뜻이고, mouseChildren 해당 객체의 자식에서 마우스의 기능을 사용할 것인지의 여부이다. 결론적으로 false인데 그 이유는 예를 들어

 

[code as3]
var spriteArea Sprite = new Sprite();
addChild( spriteArea );

var circle Sprite = new Sprite();
circle.graphics.beginFill( 0xFFFF00 );
circle.graphice.drawCircle( 0, 0, 100, 100 );
addChild( circle );

spriteArea.mouseChildren = false;
[/code]

이런식으로 자식 인스턴스에서만 마우스가 표시되어야지 부모까지 적용이 되게하면 마우스 포인터를 궂이

손 모양으로 지정해주는 의미가 없어지기 때문이다. 더 정확히 http://67740420.textcube.com/?page=9

여기 예제에서 Search 버튼인 자식 인스턴스에서는 손 모양이 적용되고 버튼 바깥부분인 부모 인스턴스에서

는 평범한 화살표 모양으로 바뀌게 되는 것이다.

 

if문 조건에서인 alpha_a인 지한 A무비클립(Sprite 객체)과 alphaFrame_a인 연한 색의 stage에 있는 A무비클립(DisplayObject 표시 객체) 영역의 겹침 부분을 감지하여 Boolean값으로 반환한다. 그런데 여기서 영역 대 영역으로 감지란 눈에 보이는 무비클립의 모양이 아닌, 네모 영역으로 겹침을 판단한다.

이렇게 되면 if조건을 true로 인식하고 alpha_a의 x와 y좌표 위치를 alphaFrame_a의 x와 y좌표 위치로 이동

시키는 것이다.

 

 

2010년 3월 22일 월요일

Sprite 클래쓰 - Drag & Drop

 

- startDrag() 메소드

   매개변수로는 lockCenter : Booleanboudns : Rectangle 이 있다.

   lockCenter 가 true일 경우, 드래그하는 무비클립의 (+)점에 마우스 포인터가 일치하게 되고, false일 경우

   에는 드래그를 하는 최초 클릭 시작점에 마우스 포인터가 일치하게 된다.

   bounds는 Rectangle클래스의 속성을 쓰는 것과 마찬가지로 x좌표, y좌표, width, height 를 직접 지정해

   주면 된다.

 

 

 

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

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

        buttonMode = true;

        this.addEventListener( MouseEvent.MOUSE_DOWN, startDragHandler );
        this.addEventListener( MouseEvent.MOUSE_UP, stopDragHandler );
    }

    private function startDragHandler( e:MouseEvent ) : void
    {
        this.alpha = 0.5;
        this.startDrag();
    }

    private function stopDragHandler( e:MouseEvent ) : void
    {
        this.alpha = 1;
        this.stopDrag();
    }
}
}
[/code]

 

This is part of Korea.

 

 

 

 

 

 

 

  참신해.

2010년 3월 13일 토요일

ColorTransform

ColorTransform 클래스를 사용하여 DisplayObject의 색상값을 조절할 수 있다. 다시 말해서

Advanced Effect 효과를 액션스크립트로 표현할 수 있다.

 

http://help.adobe.com/ko_KR/AS3LCR/Flash_10.0/index.html?flash/display/Graphics.html&flash/display/class-list.html

*모든 눈에 보이는 객체는 ColorTransform을 갖고 있다. " 1pixel = 0xAARRGGBB "

   여기서 AA(Alpha)값은 BitmapData에서만 쓰인다. 보통은 0xRRGGBB로 쓴다. -255~255까지.

   redMultiplier, greenMultiplier, blueMultiplier는 0~1 사이 값에서 유효하다.

 

 

-

 

 

 

 

-

-> 스테이지를 클릭했을때, changeHandler 함수를 호출하여 ColorTransform에서 ct라는 객체를 생성하고,

     ct의 색을 노랑색으로 지정한다. 스테이지에 있는 무비클립 nemo와 pic을 ct의 색상를 변경한다.

 

 

예제2>

 

 

-->