플래시 플레이어에는 AVM이라는 액션스크립트 판독/실행기와 렌더링을 담당하는 렌더러가 있다. enterFrame이벤트인 경우에는 frameRate에 의존하여 실행속도(실행횟수)를 결정하게 되는데 마우스 이벤트인 경우에는 재생속도와 관계없이 독립적으로 실행을 한다. 따라서 frameRate가 낮을 경우에 버튼등을 클릭하여 화면에 표현하려면 다음 렌더링엔진이 실행할 때 까지 기다려야한다. 즉 frameRate를 초당1씩 실행하고 실행시 바로 클릭하여 어떤 액션을 화면을 통해 보여진다면 1초뒤에 클릭한 액션이 가시적으로 표현이 된다.
그러한 경우 AS1에서도 제공되었던 updateAfterEvent()를 호출하여 강제로 렌더러를 실행시킨다. updateAfterEvent가 호출되는 즉시 화면이 갱신되므로 frameRate에 영향을 받지않는 마우스 이벤트를 구현할 수 있게 된다.
Posted by 버터백통
마우스를 이용하여 많은 작업을 하다보면 현재 이벤트를 반환하는 객체상에 마우스 좌표를 전역 값으로 사용해야 하는 경우가 종종 발생한다. AS1에서는 _root._xmouse와 _root._ymouse라는 속성을 사용하여 전역(절대)좌표를 알아 낼 수 가있었는데 AS3으로 오면서 localToGlobal라는 메소드를 통해 전역좌표 값을 알아내야한다.
localToGlobal를 사용하기 위해서는 마우스이벤트에서 받은 지역 좌표 값을 저장한 Point와 함께 사용한다.

이벤트를 발생하는 객체.localToGlobal( 객체의 지역좌표값 )

가령 e로 넘어오는 객체의 지역 좌표를 localPoint라는 포인트에 저장하고 전역좌표로 변환하는 변수를globalPoint 라고 한다면 아래와 같이 변수를 선언하면 된다.
var localPoint:Point = new Point( e.localX , e.localY );
var globalPoint:Point = e.target.localToGlobal( localPoint );

경로에 해당하는 객체의 지역좌표 값을 localToGlobal()를 통하여 전역 좌표값으로 변환한다.
Posted by 버터백통
외부에서 이미지 파일을 불러오는 것은 컴파일시 [Embed]를 사용하여 swf파일안에 포함시킬 수 있다. 하지만 실행중에 이미지를 불러오려면 Load라는 클래스를 사용하여야한다. Load클래스는 이미지파일이나 비디오등의 visual관련된 파일을 불러오는 역할을 담당하고 URLLoader는 데이터를 주고 받는데 사용한다.

Loader를 통해 불러올 수 있는 파일은 jpg , gif , png , swf가 있고 load라는 메서드를 통해 파일을 불러온다.
외부의 파일로 접근하기 위해서는 Loader클래스 단독적으로 사용할 수 없다. 서버나 로컬에 접근할 수 있는 통로를 담당하는 URLRequest라는 클래스와 함께 사용한다.
 var ldr:Loader = new Loader();
ldr.load( new URLRequest( "링크" ));

위의 코드는  로더 클래스를 통해 외부 이미지를 불러오는 명령이다. 그리고 호출이후 어떠한 상태인지를 알수 있는 여러가지 이벤트를 사용할 수 있다.

* 이벤트
Event.OPEN : 로드가 시작될 때 전달됩니다.

ProgressEvent.PROGRESS : 파일이 로드되는 동안 계속해서 발생.

Event.COMPLETE : 파일 다운로드가 완료된 후, 로드된 무비 클립의 메서드와 속성이 사용 가능한 상태가 되기 전에 전달.

Event.INIT : 로드된 SWF 파일을 조작할 수 있도록, 로드된 SWF 파일의 속성과 메서드가 액세스 가능한 상태가 된 후에 전달됩니다. 이 이벤트는 complete 핸들러에 앞서 전달됩니다. 스트리밍 SWF 파일의 경우 init 이벤트는 complete 이벤트보다 훨씬 더 이전에 발생할 수 있습니다. 대부분의 경우에는 init 핸들러를 사용합니다.

HTTPStatusEvent.HTTP_STATUS : 로드 중 실패한 HTTP요청이 감지될 때 발생

IOErrorEvent.IO_ERROR : 파일을 로드할 수 없는 경우 또는 로드 프로세스 중 오류가 발생.

SecurityErrorEvent.SECURITY_ERROR :  보안샌드박스 때문에 로드할 수 없을 때 발생한다.

이러한 이벤트는 Loader클래스에 직접 사용하는 것이 아니고 contentLoaderInfo라는 속성에 리스너를 추가한다. contentLoaderInfo는 어떠한 대상이 로드될 때의 정보를 파악하여 제공하기 위해 설계된 것이다.

Loader클래스는 DisplayObjectContainer를 상속받은 클래스이다. 따라서 불러들인 컨텐츠는 Loader안에 존재하며 content속성을 통해서 컨텐츠에 접근할 수 있다.
가령 A.swf에 run라는 메서드가 있다. 이 A.swf파일을 ldr이라는 delegate로 불러들였을 때  run를 호출하기 위해서 다음과 같이 코딩한다.
var movie:* = ldr.content;
movie.run();

위에 movie의 데이터타입을 *로 설정한것은 현재 이 프로젝트에는 run이라는 메서드가 없으므로 에러를 발생한다. 이를 방지하기 위한 처리이다.

* 외부에서 이미지파일의 데이터 자체를 받아오는 경우 인코더가 필요하며 ByteArray로 변환된 데이터를 loadBytes라는 명령문으로 이미지처리 할 수있다.
Posted by 버터백통

플래시에서 버튼심벌로 등록을 하면 4개의 상태 프레임이 나온다.
up과 over , down , hit이라는 프레임으로 심플버튼에서 역시 4개의 상태를 구분하는 upState,overState,downState, hitTestState 속성이 있다. 이 속성들은 대입식으로 디스플레이 오브젝트를 값을 설정하여야 하고 반드시 hitTestState를 설정하여야 버튼으로 작동하게 된다.

upState : 평상시의 디스플레이 상태
overState : 마우스 커서가 ht영역에 닿을 때의 디스플레이 상태
downState : 마우스로 클릭하였을 때의 디스플레이 상태
hitTestState : 버튼의 영역을 결정하는 곳으로 통상 버튼의 up영역을 사용한다.


var sbtn:SimpleButton = new SimpleButton();
sbtn.upState = createRect( 0xFF0000 , 100 , 100 );
sbtn.overState = createRect( 0x00FF00 , 100 , 100 );
sbtn.downState = createRect( 0x0000FF , 100 , 100 );
sbtn.hitTestState = sbtn.upState;
sbtn.addEventListener( MouseEvent.ROLL_OVER , onOver );
sbtn.addEventListener( MouseEvent.CLICK , onConfirm );
addChild( sbtn );
 
function createRect( color:int , width:int , height:int ):Shape
  {
   var rect:Shape = new Shape();
   rect.graphics.beginFill( color );
   rect.graphics.drawRect( 0,0, width , height );
   rect.graphics.endFill();
   return rect;
  }
 
function onOver( e:MouseEvent ):void
  {
   trace("SimpleButton Over.")
  }
 
function onConfirm( e:MouseEvent ):void
  {
   trace("확인을 눌렀습니다.")
  }


이 처럼 작성된 버튼에 마우스를 가져다 대면 "SimpleButton Over."라고 출력하게 된다. 또 버튼을 클릭하게 되면 "확인을 눌렀습니다."라는 메세지를 볼 것이다.

Posted by 버터백통
화면에 보여질 수 있는 객체는 디스플레이 오브젝트를 상속받은 것들이다. 예전에는 이러한 객체는 플래시툴을 이용하여 드로잉하고 그 객체를 불러 들여와 스크립트로 제어 하였지만 AS3에서는 액션스크립트만으로 드로잉을 할 수 있다. 물론 이쁘고 복잡한 효과는 어느 정도 버려야 한다.

앞서 디스플레이 리스트를 통해 계층구조를 살펴 보았다. 그 중에 드로잉만 가능한 객체는 Shape정도가 있는데 사용 용도에 따라 부모클래스를 정해야 한다. 단순히 그래픽만 그릴 것이면 Shape정도로 사용하면 될 것이고 안에 자식을 추가 할 수 있는 컨테이너를 만들 것이면 Sprite, 모션을 만들어야 한다면 MovieClip을 exteds해야 한다.

SimpleButton : up , over , down , hit영역 등이 있는 플래시에서 제공하는 버튼 심볼과 같은 클래스이다.
Shape : 단순한 드로잉이 가능 한 객체이다.
Sprite : 자식을 추가할 수 있는 컨테이너이자 드로잉도 가능하다. 단 타임라인은 제공하지 않는다.
MovieClip : 자식을 추가 할 수 있는 컨테이너이자 드로잉도 가능하면 타임라인을 제공한다.

이처럼 적절한 클래스를 상속받아 graphics를 이용하거나 upState ,overState...등을 통해 클래스 특징에 맞는 메서드를 이용하여 visual object를 만든다.
Posted by 버터백통

컨테이너의 인덱스 번호가 큰것이 앞으로 나와 보다 작은 인덱스의 객체를 가린다고 설명하였다. 그렇다면 이미 화면에 붙어있는 객체의 인덱스 순서를 바꾸어 앞으로 혹은 뒤로 이동시키고자 할때는 setChildIndex()를 사용한다.

* setChildIndex( 이동할 객체 , 이동할 인덱스번호 )
어떠한 컨테이너에 10개의 객체가 붙어있다고 가정하면 그 컨테이너의 인덱스 범위는 0~9까지 이다. 이 컨텐이너에 제일 앞에서 두번째인 8번인덱스에 객체를 붙이고자 한다면 setChildIndex( 객체 , 8 )이라고 입력하면 된다. 또는 특정 객체 green의 위치에 앞에 붙이고자 할때 green의 인덱스 번호를 구하기 위해서는 getChildIndex라는 메서드르 사용한다. setChildIndex( 객체, getChildIndex(green) ) 이 처럼 green의 인덱스값을 구하여 그 위치에 객체를 이동 시키면 green의 인덱스는 1증가하여 해당 객체 앞에 놓이게 된다.

var red:Shape = new Shape();
red.graphics.beginFill(0xFF0000)
red.graphics.drawRect(0,0,100,100)
red.graphics.endFill();
red.x = 50
addChild( red )

var green:Shape = new Shape();
green.graphics.beginFill(0x00FF00)
green.graphics.drawRect(0,0,100,100)
green.graphics.endFill();
green.x = 100
addChild( green )

var blue:Shape = new Shape();
blue.graphics.beginFill(0x0000FF)
blue.graphics.drawRect(0,0,100,100)
blue.graphics.endFill();
blue.x = 150
addChild( blue )

var gray:Shape = new Shape();
gray.graphics.beginFill(0x666666)
gray.graphics.drawRect(0,0,100,100)
gray.graphics.endFill();
gray.x = 80
gray.y = -50
addChild( gray )

setChildIndex( gray , getChildIndex(green) )

* getChildIndex( 인덱스번호를 알려는 객체 )
getChildIndex은 어떠한 특정 객체의 인덱스값을 반환하는 메서드이다.


* getChildAt( 인덱스번호 )
delegate한 객체의 이름을 모르고 인덱스 번호를 알고있을 때 해당 객체로 접근하는 메서드이다.

Posted by 버터백통

addChild또는 addChildAt을 통하여 디스플레이 컨테이너에 추가된 객체를 지우고자 한다면 removeChild()또는 removeChildAt()을 통하여 제거해야 한다.

* removeChild( 제거할 객체 )
removeChild는 제거할 delegate를 통해 객체를 제거한다.


* removeChildAt( 인덱스번호 )
removeChildAt는 컨테이너의 인덱스번호를 참조하여 배치된 객체를 제거한다. 만얀 컨테이너의 모든 객체를 지우고자 한다면 순환문을 이용하여 배치된 객체를 제거한다.

참고 : 디스플레이 리스트에서 removeChild를 통하여 리스트에서 지우면 렌더링 엔진에서만 삭제되는 것일 뿐 객체가 완전히 삭제되는 것은 아니다. 만약 삭제하려면 객체를 참조하는 모든 것을 null로 설정해야 한다.

Posted by 버터백통
앞서 디스플레이 리스트라는 것을 공부하였다. 디스플레이 리스트는 화면에 보일수 있도록 렌더러가 그리는 대상 목록이 되는데 이 목록에 추가하기 위해서는 new생성자를 통해 AVM2에 추가하고 addChld()와 addChildAt() 메서드를 통하여 목록에 추가한다.

var red:Shape = new Shape();    //생성자를 통해 AVM에 등록한다.
red.graphics.beginFill(0xFF00FF)
red.graphics.drawRect(0,0,100,100)
red.graphics.endFill();
addChild( red )                       //addChild()를 통해 디스플레이 리스트에 등록시킨다.

* addChild( 화면에 붙일 객체)
컨테이너에 추가할 객체를 매개변수로 받아 렌더링 엔진의 디스플레이 리스트에 등록한다.
기본적으로 컨테이너에는 배열처럼 정수인덱스로 상,하를 구분하게 되는데 나중에 화면에 붙은addChild가 인덱스 값이 이전 객체보다 1이 더 크다.

* addChildAt( 화면에 붙일 객체 , 인덱스 번호 )
컨테이너에 붙일 객체를 2번 째 매개변수의 값으로 인덱싱하여 디스플레이 리스트에 등록한다.

* 컨테이너의 인덱스
컨테이너에는 배열처럼 정수색인 인덱스를 통해 객체의 깊이를 설정할거나 배치할 수 있다. 이 값은 0부터 화면에 붙은 자식수-1 만큼의 범위를 갖는다.
addChild( red1 )    
addChild( red2 )    
addChild( red3 )    
위처럼 3개의 객체가 어떤 컨테이너에 자식으로 추가 되었다면 red3이 화면 제일 앞쪽에 배치되며 red1,red2를 가리게 된다. 그리고 인덱스의 값은 2에 위치하게 된다.

이러한 인덱스는 자식이 추가되면 자동으로 1씩 증가하며 범위내에 빈공간이 없도록 배치한다. 예전 AS1에서는 swapDepth나 dupliacetMovieClip , attachMovie..등을 통하여 인덱스를 설정하였는데 인덱스 중간에 빈값이 존재하고 개발자가 입력하는 값에 의존하였다. 따라서 이로인한 객체간 인덱스 충돌을 개발자가 신경써서 코딩하여야 했지만 이제는 자동으로 관리하게 되었다. 그리고 인덱스 범위내에 객체가 지워지면 자동으로 뒤에 객체들이 앞으로 당겨져 빈공간을 채워주도록 설계가 되었다. 단 addChildAt()을 통하여 이미 채워진 인덱스에 객체를 넣거나 범위를 벗어난 값으로 배치하려 하면 에러를 발생하게 된다.

* 부모 컨테이너의 교체
A.addChild( red1 )    
A.addChild( red2 )    
A.addChild( red3 )  
B.addChild( red1 )    <- red1을 B로 이동
위처럼 red1이 A에서 B로 이동하게 되었다. 예전 같으면 A에 red1을 제거하고 새로운 red1을 만들어 B객체에 넣어 주어야 했다. 하지만 AS3에서는 위의 코드처럼 A에 addChild한 상태임에도 불구하고 B에 다시 red1을 addChild하면 자동으로 A에서는 객체가 제거되고 B의 자식으로 붙게 된다. 따라서 A의 자식수는 2개이고 B의 자식수는 1의 값으로 설정된다.









Posted by 버터백통
디스플레이 리스트라는 것은 플레시플레이어의 렌더러를 통해 화면에 그려질 객체의 리스트이다. AS3를 인식할 수 있는 플래시 플레이어는 9버전 이상부터 지원하는데 AVM2(actionscript virtual Machine)라는 액션스크립트 판독/실행기와 렌더링을 담당하는 렌더러를 포함하고있다. AS3이전 버전의 AS는 무비클립이 생성될 때 자동으로 화면에 그려지게 되고 자신이 속한 부모를 바꿀 수 없었다. 만약 부모를 옮겨야 한다면 삭제 후 새로 생성하는 과정을 거쳐야만 했다. 하지만 새로운 렌더러는 이러한 기능을 대폭 개선하여 유연한 구조와 렌더링 프로세스의 개선에 중점을 두었다.

* 디스플레이 리스트 3원소
스테이지 :
스테이지는 디스플레이 계층 구조의 최상위이다. 한 개의 무비당 유일한 한개의 스테이지를 가지고 있으며 한개의 디스플레이 컨테이너(main application class)를 갖는다. 그리고 모든 디스플레이 객체는 stage를 통하여 접근 할 수 있다.

디스플레이 컨테이너 : 객체 안에 다른 자식 객체를 가질 수 있는 객체이며 자식을 포함 할 수 있는 스테이지도 디스플레이 객체 컨테이너이고 Sprite,MovieClip, Shape도 디스플레이 객체 컨테이너이다. 디스플레이 객체 컨테이너가 디스플레이 리스트에서 지워지면 해당 컨테이너 안의 자식들도 디스플레이 리스트에서 지워진다.

디스플레이 객체 : 디스플레이 오브젝트는 눈에 보이는 원소이다. MovieClip, Sprite는 디스플레이 컨테이너인 동시에 디스플레이 오브젝트이고 TextField는 디스플레이 오브젝트이다. 이러한 디스플레이 오브젝트를 화면에 보이고자 한다면 디스플레이 리스트에 등록되어진 컨테이너에 붙여야 화면에 보여지게 된다.

[ 디스플레이 리스트 계층 구조 1]

사용자 삽입 이미지

[ 디스플레이 리스트 계층 구조 2]

사용자 삽입 이미지

DisplayObject :
DisplayObject 클래스는 표시 목록에 배치할 수 있는 모든 객체의 기본 클래스입니다.

Bitmap :

Bitmap 클래스는 비트맵 이미지를 표시하는 표시 객체를 나타냅니다.

InteractiveObject :

InteractiveObject 클래스는 사용자가 마우스와 키보드를 사용하여 상호 작용할 수 있는 모든 표시 객체의 추상 기본 클래스입니다

MorphShape :

MorphShape 클래스는 표시 목록에서 MorphShape 객체를 나타냅니다. MorphShape 객체는 ActionScript에서 직접 만들 수 없으며, Flash 제작 도구에서 모양 트윈을 만들 때 함께 만들어집니다.

Shape :

Shape 클래스는 ActionScript 드로잉 API를 사용하여 가벼운 모양을 만드는 데 사용됩니다. Shape 클래스에는 Graphics 클래스의 메서드에 액세스할 수 있게 해 주는 graphics 속성이 포함됩니다.

StaticText :

이 클래스는 표시 목록의 StaticText 객체를 나타냅니다. ActionScript로는 StaticText 객체를 만들 수 없습니다. StaticText 객체를 만들려면 제작 도구를 사용해야 합니다.

Video :

Video 클래스를 사용하면 SWF 파일에 포함하지 않고도 응용 프로그램에서 라이브 스트리밍 비디오를 표시할 수 있습니다.

DisplayObjectContainer :

DisplayObjectContainer 클래스는 표시 목록에서 표시 객체 컨테이너 역할을 할 수 있는 모든 객체에 대한 기본 클래스입니다.

SimpleButton :

SimpleButton 클래스를 사용하여 SWF 파일에 있는 버튼 심볼의 모든 인스턴스를 제어할 수 있습니다. 제작 도구에서 버튼 인스턴스를 만든 후 SimpleButton 클래스의 메서드와 속성을 사용하여 ActionScript에서 버튼을 조작할 수 있습니다.

TextField :

TextField 클래스를 사용하면 텍스트 표시 및 입력을 위한 표시 객체를 만들 수 있습니다.

Loader :

Loader 클래스는 SWF 파일이나 이미지(JPG, PNG 또는 GIF) 파일을 로드하는 데 사용됩니다.

Sprite :

Sprite 객체는 무비 클립과 유사하지만, 타임라인이 없기 때문에 타임라인이 필요 없는 객체에 적합한 기본 클래스입니다.

Stage :

전역적으로 액세스할 수 없으며 DisplayObject 인스턴스의 stage 속성을 통해 액세스해야 합니다.

MovieClip :

MovieClip 클래스는 Sprite, DisplayObjectContainer, InteractiveObject, DisplayObject 및 EventDispatcher 클래스로부터 상속됩니다. Sprite 객체와 달리 MovieClip 객체에는 타임라인이 있습니다.


Posted by 버터백통