[AS3] DisplayObject란

Programming/ActionScript 3.0 2007. 7. 20. 11:10
1. DisplayObject란 무엇인가?
AS2까지는 MovieClip이 모든 것을 처리할 수 있었으나 AS3에서는 기존의 MovieClip의 기능을 여러 개의 클래스로 분산해 놓았다.

1.1. 표시 오브젝트란

표시 오브젝트란 화면에 표시되는 모든 오브젝트라고 할 수 있다. 예를 들면 AS2의 MovieClip도 화면에 표시되므로 표시 오브젝트라고 할 수 있다. String 이나 Sound와 같은 클래스의 오브젝트는 그 자체로 화면에 표시할 수 없는 것들이기 때문에 표시 오브젝트라고 할 수 없다.

AS3에서는 MovieClip을 복수의 클래스에 분산시켰는데 타임 라인 기능이 없는 Sprite과 같이 MovieClip보다 적은 기능을 갖고 있는 클래스도 있고 비트 맵을 표현하는 Bitmap 클래스, 텍스트를 표시하는 TextField 클래스 등이 있다. Sprite와 같은 클래스를 이용하면 MovieClip을 사용하는 것보다는 전체적으로 퍼포먼스를 향상 시킬 수 있다. 이유는 AS3이전에는 MovieClip 자체에서 거의 모든 기능을 포함하고 있었기 때문에 MovieClip 하나만을 보더라도 묵직했지만 그것을 기능별로 분류하여 오브젝트 자체가 가벼워 졌기 때문이다. 실제로 사용하게 되는 표시 오브젝트 클래스들은 아래와 같은 클래스들이 있다.

AVM1Movie, Bitmap, MorphShape, Shape, StaticText, Video, SimpleButton, TextField, Loader, Sprite, Stage, MovieClip

1.2. 표시 오브젝트 컨테이너란

표시 오브젝트는 “화면에 표시되는 모든 오브젝트” 라고 하였지만 정확하게는 “화면에 표시할 수 있는 모든 오브젝트” 라고 할 수 있다.

new로 만든 표시 오브젝트만으로 화면에 표시되지는 않는다. 표시 오브젝트는 표시 오브젝트 컨테이너에 넣어야만 화면에 표시된다. 아래에서 이야기 하겠지만 표시 오브젝트 컨테이너에 있는 addChild나 addChildAt 메소드 등을 이용해서 컨테이너에 표시 오브젝트를 추가하는 행위로서 화면에 표시된다. 표시 오브젝트 컨테이너가 될 수 있는 클래스는 아래와 같은 클래스들이다.

Loader, Sprite, Stage, MovieClip

여기서 표시 오브젝트 컨테이너는 그 자체가 표시 오브젝트라는 것을 알 수 있다.
AS3의 이전 버전에서 사용하던MovieClip이 상자 구조를 취할 수 있던 것처럼 이러한 클래스도 상자 구조를 취할 수 있다.

1.3. 표시 리스트란
이와 같이 컨테이너 화면에 표시되고 있는 오브젝트의 리스트를 표시 리스트라고 한다. swf 1개의 최상위에는 1개의 Stage 오브젝트가 있다. 이것이 스테이지의 최상위 컨테이너가 된다.

스테이지로부터 표시 오브젝트는 트리 구조를 갖게 되며 컨테이너가 될 수 없는 표시 오브젝트는 리프 노드(그 이상 분기하지 않는 것)이며
컨테이너는 리프 노드, 또는 브랜치 노드(그 이상 분기 가능한)가 된다.

1.4. 표시 오브젝트의 실체
표시 오브젝트는 보통 변수 같아서 하나의 표시 오브젝트의 실체는 오로지 하나다. 표시 오브젝트를 복수의 컨테이너에 addChild 할 수 없으며 동일 컨테이너에 addChild 했을 경우에도 컨테이너에서는 한 번 삭제되어(이동했다는 표현이 더 적절하겠다) 컨테이너의 맨 위(depth)에 추가된다. 표시 오브젝트 컨테이너에는 addChild와 반대의 기능을 하는removeChild라는 메소드를 가지고 있다. 이것은 이름대로 컨테이너로부터 표시 오브젝트를 삭제하는 메소드다. removeChild 메소드는 컨테이너(표시 리스트)로부터 지정한 표시 오브젝트를 제외할 뿐, 메모리에서 제거되는 것이 아니라는 것을 잊어서는 안 된다. 표시 오브젝트를 더 이상 사용하지 않을 경우에는 removeChild와 함께 별도로 delete 연산자로 표시 오브젝트를 삭제하여야만 가비지 컬렉터에 의해 메모리 회수 대상이 될 수 있다.

2. DisplayObject 클래스와 DisplayObjectContainer 클래스의 관계

표시 오브젝트의 개념을 토대로 표시 오브젝트의 기본이 되는 2개의 클래스를 보면서 좀 더 구체적으로 이야기하면 다음과 같다.

2.1. DisplayObject 클래스 개략
모든 표시 오브젝트는 DisplayObject 클래스를 상속하고 있다.(자세한 상속 관계는 레퍼런스를 참조) 간단하게 말하면 모든 표시 오브젝트에 공통의 성질(프롭퍼티나 메소드)은 DisplayObject 형을 갖고 있는 것이다. 예를 들면 x 나 y ,height ,alpha 등은 공통 항목으로서 DisplayObject 클래스가 가지고 있는 것이다.

MovieClip을 잘 다루기 위해서 레퍼런스를 보는 경우 AS2 까지는 MovieClip만을 보면 되었으나 AS3부터는 기본이 되는 DisplayObject의 프롭퍼티와 메소드를 알아 둘 필요가 있다. 반대로 말하면 DisplayObject의 취급을 알아 두면 모든 표시 오브젝트를 컨트롤 할 수 있다. (DisplayObject 속성에 한하여) 레퍼런스를 참조할 때는 DsplayObject의 항목을 우선적으로 확인해 볼 필요가 있다. DisplayObject 자체는 표시를 위한 기능을 가지고 있지 않으므로 사용자 클래스를 만드는 경우는 DisplayObject의 서브 클래스를 확장하여 사용하면 된다.

2.2. DisplayObjectContainer 클래스 개략
Sprite나 MovieClip은 컨테이너가 될 수 있다고 이야기 했는데 그것들은 DisplayObjectContainer 클래스를 상속하고 있기 때문이다. 컨테이너를 조작하는 메소드나 프롭퍼티(addChild등)는 DisplayObjectContainer 클래스가 공통으로 가지고 있는 기능이다. 물론 DisplayObjectContainer 클래스는 DisplayObject 클래스를 상속하고 있다.
「심도」의 취급에 대해서도 DisplayObjectContainer (프롭퍼티•메소드)로 관리하게 된다. Sprite나 MovieClip을 취급하는 경우는 이러한 클래스 레퍼런스를 참조할 필요가 있다.

2.3. AS3에서의 심도 관리는 어떻게 되나
AS3 이전의 액션스크립트에서는 depth나 getNextHighestDepth을 자주 사용하였지만AS3에서는 이러한 메소드는 사라졌다. 하지만「심도」와 같은 개념은 남아 있는데, AS3에서는 해당 컨테이너가 몇 번째에 위치해 있는가를 나타낼 때 “인덱스 위치” 라는 개념으로 설명할 수 있다.

인덱스 위치는 0에서 부터 시작해 증가하는데 0은 가장 안쪽(아래)이 되며 수치가 큰 만큼 앞(위)에 표시된다.

인덱스 위치는 기존에 사용하던 심도의 개념처럼 고정된 것이 아니다. 컨테이너 내에서 표시 오브젝트가 추가되거나 위치가 조정 되면 다른 자식 오브젝트도 자동적으로 인덱스 위치가 조정된다. 심도와는 달리 인덱스 위치는 불연속적인 성격을 가지지 않으며 절대적으로 연속적이다.
만약 0, 1,2라는 인덱스 위치를 가지고 있는 3개의 오브젝트가 하나의 컨테이너 안에 있을 경우 인덱스 1에 있는 오브젝트를 인덱스 0으로 이동할 경우 AS3 이전의 스크립트에서는 0 뎁스 위치에 있는 오브젝트가 삭제되고 1뎁스에 있는 오브젝트가 0뎁스로 이동하고 기존의 1뎁스는 소멸하면서 중간에 1뎁스에는 오브젝트를 갖고 있지 않은 불연속적인 성격을 갖고 있었으나 AS3부터는 인덱스 1위치를 0위치로 이동할 경우 자동적으로 0위치에 있던 오브젝트는 인덱스 1위치로 이동하게 되므로써 연속적인 위치를 유지하게 된다.

2.4. 컨테이너의 조작
좀 더 구체적으로 이야기 하기 위해서 DisplayObjectContainer의 메소드나 프롭퍼티를 몇 개 소개하면 다음과 같다. (자세한 것은 레퍼런스 참조)

•addChild / addChildAt 메소드
컨테이너에 표시 오브젝트를 추가한다. addChild는 항상 맨 위에 자식 오브젝트를 추가한다.(인덱스 위치의 마지막) addChildAt을 사용하면 특정 인덱스 위치를 지정할 수 있다.

•setChildIndex / swapChildren / swapChildrenAt 메소드
컨테이너의 자식 오브젝트의 인덱스 위치를 변경한다. swapChildren, swapChildrenAt은 2개의 자식 오브젝트를 지정하고 위치를 바꾼다. 전자는 인수로서 2개의 오브젝트를 지정하고 후자는 2개의 인덱스 위치를 지정해서 바꿀 수 있다.

•removeChild / removeChildAt 메소드
컨테이너로부터 표시 오브젝트를 삭제한다. removeChild는 직접 오브젝트를 삭제하고(표시 리스트에서 제거)  removeChildAt은 인덱스 위치를 통해 삭제한다. 표시 오브젝트의 실체는 삭제되지 않으며 어디까지나 컨테이너로부터 제거될 뿐이다.(메모리 영역은 유지된다.)

•getChildAt / getChildByName 메소드
지정한 오브젝트를 돌려준다. getChildAt은 인덱스 위치를 통해 돌려주고 getChildByName은 오브젝트명을 통해서 지정한 오브젝트를 돌려준다. getChildByName의 경우는 해시검색을 진행하기 때문에 getChildAt 쪽이 getChildByName보다 처리속도가 빠르다.

•getChildIndex 메소드
지정한 오브젝트의 인덱스 위치를 돌려준다.

•contains 메소드
컨테이너 내에 지정한 오브젝트가 있을지를 조사하여 Boolean 값(true/false)를 돌려준다.
import flash.display.Sprite;
var sprite1:Sprite = new Sprite();
var sprite2:Sprite = new Sprite();
var sprite3:Sprite = new Sprite();
var sprite4:Sprite = new Sprite();

sprite1.addChild(sprite2);
sprite2.addChild(sprite3);

trace(sprite1.contains(sprite1)); // true
trace(sprite1.contains(sprite2)); // true
trace(sprite1.contains(sprite3)); // true
trace(sprite1.contains(sprite4)); // false
•numChildren 프롭퍼티
컨테이너에 포함되는 자식 오브젝트의 수를 돌려준다. (컨테이너명.numChildren - 1)로 하면 컨테이너의 맨 위의 인덱스 위치를 지정할 수 있다.

    

설정

트랙백

댓글

한국에서 SW 개발자가 성공하지 못하는 세가지 이유

Programming/Etc 2007. 7. 14. 14:02
소프트웨어 개발자 직종에 대한 회의론적인 얘기가 여기저기에서 들린다. 한때 IT 붐이 일었을 때는 많은 사람들이 개발자를 지망하기도 했다. 하지만 최근 상황을 보면, 신규 유입되는 인력이 아주 적은 편이다. 요즘 젊은이들은 영악해서 이 직종에 비전이 없다는 것을 너무나 잘 알고 있다.

신참 인력뿐만 아니라 고급 인력도 많이 부족하다. 현재의 사회 풍토에서 고급 인력으로 성장하는 것은 결코 쉬운 일이 아니기 때문이다. 그저 사회가 제시하는 길을 따라가다가는 고급 인력이 되는 것이 아니라 퇴출된다.

필자의 경우를 보면, 필자는 정말 프로그래밍이 좋아서 시작한 8비트 키드이다. 중학교 1학년 때 처음으로 컴퓨터를 알게 된 이후로 한시도 컴퓨터와 떨어진 적이 없는 소위 컴퓨터광(geek)이다. 하지만 대학 졸업 후 사회에 나와 첫 직장인 SI 업체에서 일하면서 몇 번이나 눈물을 흘렸다. 이후 프리랜서, 개인회사 창업, 벤처기업, 중소기업, 대기업, 외국계 기업을 두루 걸치면서 현재까지 겨우 살아남을 수 있었다.

만일 그런 인생의 순간순간에서 이를 악물고 분발하지 못한 채 끈을 놓아버렸다면 어땠을까? 정말 아찔한 생각이 든다. 특유의 헝그리 정신으로 인해 겨우 버텼으며 성격도 많이 변했다. 그간 필자 자신 그리고 선배, 동료, 후배들을 보면서 느꼈던 생각을 정리해서 개발자가 성공할 수 없는 이유 세 가지를 꼽아 보았다.

SI 중심의 왜곡된 업계 구조

첫 째, 업계 구조가 SI 중심으로 왜곡되어 있다. 국내의 소프트웨어 산업은 패키지나 솔루션 비즈니스가 제대로 작동되지 않는 상태에서, 대기업 중심의 SI 업체들이 시장을 차지하고 있다. 그 과정에서 산업의 혈액 순환이 잘 되지 않아, 대기업만 돈을 벌뿐 중소기업들은 협력 업체라는 미명 하에 근근이 먹고 살고 있는 형편이다. 통계에 따르면 전체 매출의 80% 이상을, 그리고 영업 이익의 90% 이상을 대기업 계열 SI 업체 상위 3개사가 가져가고 있다.

SI는 소프트웨어 산업을 구성하는 한 가지 요소일 뿐이지만 국내에서는 거의 SI 밖에 없는 수준이다. 그런 상태에서 빅3업체가 모든 것을 가져가고 있으며, 산업 전반에 하청 및 재하청에 따른 죽음의 순환 고리를 형성하고 있다. 그런 생태 구조에서 개발자는 단지 머리 수에 불과할 따름이다. 또한 전문적인 지식에 대한 가치 판단이 제대로 이루어지지 않고 있기 때문에, 소프트웨어 아키텍처까지도 비전문가에게 맡겨지는 경우가 많다.

SI 중심의 산업 구조, 그리고 전문가에 대한 평가 체계가 없고 단지 머리 수에 의해 개발자에 대한 판단이 이루어지는 상황에서 개발자의 성공 사례는 나올 수 없다. 대기업의 협력 업체에서 일하는 많은 개발자들이 과중한 업무로 인해 참다못해 전업을 하거나 건강이 나빠져서 자의반 타의반 일을 더 이상 할 수 없게 되곤 한다. 그러한 이유 때문에 많은 개발자들이 스스로를 막장 인생이라고 표현하고 있다.

엉성한 개발자 관리
둘째, 소프트웨어 업체들이 개발자를 제대로 관리하지 못하고 있다. 소프트웨어 개발은 멘탈(mental) 작업이다. 인간의 정신에 의해 결과물이 만들어지고 그것이 성공과 실패를 좌우한다. 하지만 국내 대부분의 소프트웨어 업체들은 그러한 멘탈 작업에 적합한 업무 환경을 제공하지 못하고 있다. 또한 커리어 관리도 이루어지지 않고 있다. 물론 실적에 대한 보상도 미비하다.

개발자들에 대해 출퇴근 시간을 정확하게 체크하고(아니, 출근시간을 지키는지 체크하고 퇴근시간은 얼마나 늦는지 체크한다), 집중할 수 없는 시끄러운 환경을 제공하고, 업무 실적의 가치를 제대로 평가하지도 못한다. 심지어 복장 점검을 하기도 한다. 또한 요즘 개발자들은 전문적인 교육은 고사하고 일일 세미나에 참석하는 것도 어려운 형편이다. 많은 기업들이 최소한의 투자조차 기피하고 있기 때문이다.

그것은 중소기업은 말할 것도 없고 소위 초일류 기업을 지향한다는 대기업도 마찬가지이다. 열악한 업무 환경을 제공하면서 성과에 있어서는 최고의 아웃풋을 강요한다. 개발 환경만 제대로 제공되지 못하는 것이 아니라 관리도 제대로 안되고 있다. 부적절한 관리자들이 개발자를 정신적으로 학대하고 있다. 소프트웨어 개발자로서 생존하기 위해서는 사회 구조적 환경, 그리고 기업문화와 싸워야 한다. 많은 선배 개발자들이 그런 생존을 위한 싸움에서 졌고 결국 사라져 갔다.

개발자들의 스킬 부족과 닫혀진 태도
셋째, 끝으로 개발자들의 커뮤니케이션 스킬 부족과 태도 문제를 지적하지 않을 수 없다. 이 문제는 한국적 기업문화(상명하복)와 결합하여 더욱 복잡한 문제를 야기하고 있다. 개발자들은 특히 다른 직종에 비해 성격이 까칠한 경우가 많다. 자신만의 지식과 세계가 있기 때문에 그것이 전부라고 우쭐한 채로, 다른 개발자나 다른 직종을 존중하지 못하는 사람들이 꽤 많다.

하지만 “타인이 원하는 것에 대해 관심을 갖지 않는 사람”은 인생의 가시밭길을 걷게 된다. 그런 태도는 타인과의 협업을 어렵게 하고 결국 자기 자신이 원하는 것도 얻지 못하게 한다. 젊은 시절에는 그런 태도에도 불구하고 큰 문제가 없을 수 있겠지만, 30대 중반이 넘을 때까지도 태도를 변화시키지 못할 경우 이후에 많은 고난을 겪게 된다. 그것은 이미 인간의 역사에서 증명된 삶의 법칙이다.

똑똑하고 샤프한 개발자들은 종종 있다. 하지만 타인의 관심사에 진정으로 주의를 기울이고 타인에게 친절한 마음을 가진 개발자를 만나기란 참으로 힘들다. 이것은 다른 직종도 마찬가지이겠지만 (개발자 출신인 필자가 볼 때에는) 개발자들의 세계에 유독 이런 까칠함과 폐쇄성이 심하다.

물론 그런 독불장군적 태도가 단지 개발자들의 탓만은 아닐 것이다. 많은 개발자들이 피해 의식을 갖고 있으며 그것이 타인에 대한 공격적 태도로 나타나기도 한다. 사회적 환경의 미비, 그리고 커뮤니케이션 스킬이 부족한 개발자들. 이 조합이 더욱 안타까운 결과를 만들어낸다.

추가적으로 언급할 점은, 혁신해야 할 여러 가지 네가티브한 요인에도 불구하고 개발자들끼리 잘 뭉치지 못한다는 사실이다. 외국과 달리 개발자 커뮤니티의 활동이 많지 않다. 물론 JCO(자바 개발자 커뮤니티), SCA(소프트웨어 커뮤니티 연합) 등 개발자들의 모임이 없는 것은 아니지만 가끔 오프라인 모임이나 컨퍼런스를 개최할 뿐, 별다른 ‘사회 변혁적 활동’을 구현하지는 못하고 있다. 개발자들의 실상을 알리고 대안을 마련하고 정부나 기업들과 접촉을 하고 해외에 진출하고 창업을 하는 등의 좀 더 적극적으로 행동하는 것이 필요하다.

아마도 필자의 이런 글에 대해 그저 현실에 대한 비판에 불과하다고 얘기하는 이도 있을 것이다. 하지만 대응 방안을 마련하기 위해서는 먼저 냉정하게 현실을 정리하지 않을 수 없다.

요약해보자. 대기업 계열사들이 장악한 SI 위주의 산업 구조에서 개발자들은 성장하지 못하고 성공하지 못한다. 이런 사회 풍토에서 과연 존경 받거나 성공한 개발자들이 얼마나 되는가? 또한 많은 소프트웨어 업체들의 기업 문화가 후진적이다. 제대로 된 업무 환경을 제공하지도 못하면서 프로젝트 관리도 안 된다. 그러면서 성과에 대해서는 초일류를 원한다. 이율배반적이다.

개발자들의 태도 문제도 있다. 환경을 바꾸지 못하면 자기 자신을 바꾸어야 한다. 개발자 스스로 그런 인식을 가져야 한다. 피해의식에 사로잡혀 있는 것만으로는 삶이 억울하지 않은가? 개인적으로 커뮤니케이션 스킬을 향상시키고 타인에 대해 친절한 태도를 갖추는 인간 수양이 필요하다. 그리고 동료 개발자들과 함께 변혁을 위해 협업하고 개척해나갈 부분이 있다는 것을 알고서 행동해야 한다.

왜곡된 업계 구조 속에서 가만히 있으면 퇴출될 뿐이다. 우리에게는 행동이 필요하다. 이후의 컬럼에서 하나씩 대응 방안을 다루어보도록 하겠다.

출처 : ZDNet Korea - 류한석(IT 컬럼니스트)
    

설정

트랙백

댓글

[AS3] ActionScript 3.0의 스텝 가이드

Programming/ActionScript 3.0 2007. 7. 14. 07:25
ActionScript 3.0 이행 스텝 가이드
R Blank
Adobe Flex 2와 Flash CS3 Professional에서 생성된SWF 파일을 실행하는 Adobe Flash Player 9는 Flash 플랫폼의 새로운 파워업을 구현한다고 할 수 있습니다. Flash Player 9를 이용하면 Flash 7이나 8로 제작한 프로젝트에 비해 최고30배 고속으로 실행되는 프로젝트를 제작할 수 있습니다.

Flash Player 9의 퍼포먼스가 큰 폭으로 향상한 이유는 Flash나 Flex 의 디벨로퍼가 기술한 코드를 해독하는 ActionScript Virtual Machine (AVM )을 새롭게 개발하고 있는 것을 들 수 있습니다. 또 ActionScript 3.0은 테크놀로지의 좋은  파트너라고도 할 수 있습니다 ActionScript의 최신 버전 ActionScript 3.0 에도 대폭적인 개량이 이루어지고 있습니다. ActionScript 3.0은 구버전보다 훨씬 파워풀함과 동시에 ActionScript 언어를 ECMAScript 국제 규격에 완전하게 준거시킨 버전이기도 합니다. 그 때문에 ActionScript 3.0은 종래의 Flash 디벨로퍼가 익숙했던 것 이상의 엄밀함이 요구됩니다.


알파치는 0에서 1의 범위에서 지정한다
기존의 ActionScript에서는 무비 클립의 알파 프롭퍼티를 0부터 100사이의 값으로 지정하고 있었지만 ActionScript 3.0에서는 0 부터 1 까지가 알파값의 범위가 됩니다. 이러한 변경은 그 자체가 별 것은 아니지만 ActionScript 3.0을 시작하는데 있어서 충분히 주의해 둘 필요가 있는 것이라고 할 수 있습니다. 디벨로퍼가 디버그 작업에 몇 시간을 낭비하거나 의지를 잃는 사태에 빠질 수도 있는 변경사항입니다.

이것과 같이 단순한 변경사항이 많이 있습니다. 예를 들어 지금까지 MovieClip 프롭퍼티로 사용되고 있었던 언더 스코아가 모두 삭제되어 있거나( 「_x 」는 「x 」, 「_width 」는 「width 」가 됩니다), Video 클래스의 attachVideo() 메소드가 보다 적절한 이름의attachNetStream() 으로 변경되어 있거나 합니다. ActionScript 3.0의 습득을 원한다면 ActionScript 테크놀러지 센터에 액세스 하는 것을 추천합니다.

무비 클립의 변경 사항

다음의 코드가 작동한다면 멋지지 않습니까?.

var mc:MovieClip = new MovieClip();

그렇습니다, ActionScript 3.0에서는 이 코드가 올바르게 기능합니다. 이것은 기존의 Flash 디벨로퍼에 있어서 가장 큰 개념상의 변경 사항이라고 할 수 있을지도 모릅니다. ActionScript 3.0 에는 새로운 표시 리스트가 있어서 이것이 Flash Player 위에 있으면서 여러분의 SWF 파일의 실질적인 물리 아키텍처를 구성합니다.

기존의 Flash에 있어서의 최대의 무거운 짐이라고 한다면 무비 클립이 SWF 파일상의 모든 물리 오브젝트의 친타입으로서 다루어지고 있던 것입니다. 이것은 모든 요소가 무비 클립이거나 모든 요소에 타임라인이 필요한 것이 아닌데도 말입니다. ActionScript 3.0에는 DisplayObject라는 이름의 새로운 클래스가 있어서 MovieClip은 단지 표시 오브젝트의 한 종류로서 존재합니다. 또 하나의 표시 오브젝트는 스프라이트입니다. 이러한 DisplayObject의 각 종류에는 다른 능력이 갖춰져 있습니다(각각 다른 자원을 이용합니다). 즉, 무비 클립에 대해서 할 수 있는 것과 스프라이트에서 할 수 있는 것이 각각 다릅니다.

위에서 보았던 코드가 무비 클립을 생성한다고 하여 이 무비 클립이 자동적으로 표시되는 것은 아닙니다. 무비 클립을 표시하려면 해당 DisplayObject 클래스를 스테이지 또는 다른 표시 오브젝트에 첨부할 필요가 있습니다. 무비클립(또는 모든 표시 오브젝트)을 어디에 배치할까는 addChild() 또는 addChildAt() 메소드를 이용해 Flash에 명시적으로 지시할 필요가 있습니다.

이것은 다양한 가능성이 있습니다. 예를 들어 지금까지의 Flash의 경우 무비클립은 특정의 타임 라인에 관련지을 수 있었기 때문에 무비클립을 다른 타임라인상으로 이동할 수 없었지만 앞으로는 removeChild()나 addChild()를 이용하여 표시 리스트내의 표시 오브젝트의 위치를 동적으로 변경할 수 있습니다(예를 들어, 프로젝트가 있는 부분의 타임 라인으로부터 무비 클립을 삭제하고 이것을 프로젝트내의 완전히 개별적인 무비 클립으로 이동 것이 가능합니다). 복잡하게 얽히는 타임라인의 문제점은 회피할 수 있을 것입니다.

_root 는 어디에?
위에서 설명한 변경사항을 바탕으로ActionScript 3.0에서는 _root의 개념도 없어졌습니다. 즉, SWF 파일의 메인 타임라인의 참조가 없어졌습니다(AS3에서는 메인의 타임라인을 유지할 필요성이 없어졌습니다). 또,  만능적으로 액세스 가능했던 Stage 클래스도 없어졌습니다.

그럼 ActionScript 3.0에서 이러한 개념이 어떻게 되냐하면 스테이지 또는 스테이지의 자식이 관련지을 수 있었던 표시 오브젝트는 각자, Stage로 불리는 해당 스테이지에 의해서 참조를 가지게 됩니다. 예전에 _root 로서 파악해 온 것은 향후 Stage 프롭퍼티로 참조할 수 있습니다.

새로워진 패키지
패키지로서 중요한 것은 허용량의 대소가 아니라 몇 개의 클래스를 포함할 수 있는가 하는 것입니다. 패키지와 일련의 클래스는 디벨로퍼가 코드를 정리하는 목적으로 이용할 수 있는 툴입니다. ActionScript 2.0의 패키지는 클래스 파일을 수용하기 위한 컴퓨터상의 폴더이며 코드를 정리하기 위한 편리한 툴 정도 였습니다. 그리고 각 파일에는 오로지 1개의 클래스 밖에 포함할 수 없습니다. 또한 클래스명과 파일명을 완전하게 일치시키지 않으면 안 된다고 하는 제약이 있었습니다.

그러나 AS3는 package 스테이트먼트를 이용해 ActionScript (.as ) 파일 내에서 정의 가능한, 진정한 의미의 패키지를 취급할 수 있게 됩니다. AS 파일에 패키지(또는 네스트화 된 복수의 패키지)를 수록하여 이 안에 1개 또는 복수의 클래스를 포함하는 것이 가능합니다.

이 변경이 프로그래머를 더 혼란스럽게 하는 것으로 보일지도 모르지만 실제로 이 새로운 코드 구조를 시험해 보면 그 유연성이 마음에 들 것입니다. 필자 자신도 이 기능이 코딩 체재에 얼마나의 영향을 미칠까에 대해서 회의적이었지만 작업을 진행하면서 클래스(특히, 순수한 데이터 클래스등)가 매우 간단하게 작성할 수 있게 된 것을 실감하고 있습니다. 패키지에 관한 이번 변경은 ActionScript 프로그래머에 의해 좋은 객체 지향프로그래밍 수법을 제시하는 것이라고 할 수 있겠습니다.

7 개의 주요 패키지/클래스
ActionScript 3.0의 클래스 파일을 사용하기 전에 알아야할 것은 지금까지 ActionScript에 내포되고 있던 일련의 Flash Player 클래스를 ActionScript 3.0에서는 명시적으로 import하지 않으면 안 된다는 것입니다. 만일 텍스트 필드를 작성하고 싶은 경우에는 다음의 예와 같이 텍스트 필드 클래스를 명시적으로 읽어들일 필요가 있습니다.

import flash.text.TextField;

또 텍스트 패키지의 모든 클래스를 읽어 들이고 싶은 경우에는 다음과 같이 기술합니다.

import flash.text.*;

import 스테이트먼트는 변경사항이 없기 때문에 ActionScript 2.0와 같은 방법으로 이용할 수 있습니다. 앞으로 import 스테이트먼트가 예전보다 자주 필요할 뿐입니다. 소정의 클래스를 명시적으로 읽어들이지 않으면 클래스 파일로 완성되는 것은 큰 폭으로 제한되게 됩니다.

ActionScript 3.0의 패키지와 클래스 파일이 익숙하지 않거나 어느 클래스가 필요하게 되는지를 고민하고 싶지 않은 경우는 다음의 7 개의 패키지를 기억해 두면 좋을 것입니다. 이 7개의 패키지에는 Flash 어플리케이션 또는 FLA 에 필요한 클래스의 대부분이 포함되어 있습니다(보다 프로패셔널적인 개발 방법으로서는 필요한 클래스만을 읽어들이도록 해 주세요).

import flash.net.*;
import flash.events.*;
import flash.display.*;
import flash.geom.*;
import flash.ui.*;
import flash.utils.*;
import flash.text.*;

document 클래스를 활용한다

document 클래스는 모든 디벨로퍼에 있어서 유익한 것이지만 특히 메인 타임라인에 1 프레임만을 배치하는 것과 같은 디벨로퍼에 있어서 가장 유용한 것입니다. Flash 어플리케이션을 코딩 할 때 디벨로퍼의 상당수는 FLA 의 단일 프레임에 모든 요소를 배치하여 불과 1행의 ActionScript를 이용하고 제작한 외부 클래스 파일을 호출하고 있습니다. 앞으로는 이 1행의 코드마저 불필요하게 되어 퍼블리시 설정의 다이알로그 박스에서나 스테이지가 선택 되고 있을 때의 프롭퍼티 패널상에서 직접 FLA 에 document 클래스(제작중의 FLA 에 대한 단일의 클래스 파일)을 할당할 수 있습니다.

이 클래스는 반드시 Sprite 또는 MovieClip을 계승하는 것이 필요합니다.(document 클래스이기 위해). 이 클래스의 constructor함수는 해당 SWF 파일의 읽기와 함께 자동적으로 불려 갑니다.

비트 맵 및 무비의 읽기 방법
loadMovie() 메소드(혹은 예전의 ActionScript로 말하면 MovieClipLoader() 클래스)는 대부분의 Flash 디벨로퍼에 있어서 빠뜨릴 수 없는 존재라고 할 수 있겠습니다. 여기에서는 Flash 9 컨텐츠에 Flash 무비 또는 비트 맵(JPEG ,PNG ,GIF)을 읽어들이기 위한 중요한 7행의 코드를 소개하기로 하겠습니다. 이하에 나타내는 코드는 스프라이트를 사용한 간단한 예지만 이 밖에도 다양한 변이를 생각할 수 있습니다.
var bgToLoad:String = "05092007.gif";
var bgLoader:Loader = new Loader();
var bgURL:URLRequest = new URLRequest(bgToLoad);
bgLoader.load(bgURL);

var bg:Sprite = new Sprite();
bg.addChild(bgLoader);
addChild(bg);
이 코드에서는 우선 Loader 오브젝트를 작성하고 미디어 파일에 포인트 한 URLRequest 오브젝트를 사용해서 외부 미디어의 읽기를 지시하고 있습니다. 이 때 미디어를 읽어들이게 하는 앞의 표시 오브젝트(bg)가 확실히 존재하는 것을 확인하고 이 코드는 메인의 타임 라인에 존재하게 되므로 맨 마지막 줄의 addChild에 의해서 bg 스프라이트를 스테이지상에 배치하고 있습니다.

XML의 읽기 방법
Flash 유저의 대부분이 외부 SWF 파일 또는 비트맵 읽기에 익숙한 것과 같이 무비에 XML을 사용하고 데이터를 읽어들이는  케이스도 빈번히 볼 수 있습니다. XML의 이용에 관해서는 ActionScript 3.0에서 비약적으로 편리한 기능이 많이 준비되어 있습니다. 이러한 편리한 기능에 접하기 전에 우선 XML 파일을 읽어들이기 위한 기본적인 코드를 소개해 둡니다.
var xmlSrc:String = "myData.xml";
var ur:URLRequest = new URLRequest(xmlSrc);
var ul:URLLoader = new URLLoader();

ul.addEventListener(Event.COMPLETE,dataLoaded);
ul.load(ur);

function dataLoaded(evt:Event):void
{
trace(evt.target.data);
}
이 코드에서는 우선 사용하고 싶은 XML 파일에 포인트 하는 URLRequest 오브젝트를 작성하고 그 다음에 URLRequest를 읽어들이는 URLLoader를 작성합니다. 그리고 COMPLETE 이벤트(XML 의 읽기 완료)의 청취자로서 dataLoaded() 메소드를 추가하고 있습니다. dataLoaded() 메소드 안에서는 이벤트 자체의 target 프롭퍼티의 data 프롭퍼티에 포인트 하는 것으로 XML을 trace 하고 있습니다.

비약적으로 편리하게 된 XML의 해석
이것으로 ActionScript 3.0의 훌륭한 XML 기능인 ECMAScript for XML (E4X ) 을 이용할 준비가 갖추어졌습니다(ActionScript 3.0은 국제적인 오픈 표준 규격의 ECMAScript 262에 완전 준거하고 있습니다). E4X의 자세한 해설은 다른 기회로 미룹니다만 데이터의 취급이 중요하게 대두되고 있고 ActionScript 3.0에서는 이 부분이 큰 폭으로 개선되고 있는 것을 고려하여 하이라이트를 소개하기로 하겠습니다.

ActionScript 2.0에서 디벨로퍼의 대부분이 XML의 읽기와 동시에 Flash 데이터에의 해석•변환을 실시하여 처리 시간으로서 프로세서에 큰 부담이 되었습니다. 그러나 ActionScript 3.0과 E4X를 이용하면 노드를 직접적으로 참조할 수 있어서 XML의 트리 구조를 파일 시스템과 같이 손쉽게 취급하는 것이 가능합니다.

Flash Player 9에서 주목하는 신기능
지금까지 소개한 내용을 참고로 하여 ActionScript 3.0에의 대한 우려가 어느 정도 해소되었다고 생각합니다. 다음은 컨텐츠 제작의 폭을 한층 더 넓힐 가능성을 숨긴 Flash Player 9의 몇 개의 신기능에 대해서 다루기로 하겠습니다.

우선 첫 번째는 풀 스크린 모드 입니다. 본래 이 모드는 비디오 컨텐츠 체험을 JavaScript에 손대는 일 없이 확충하는 목적으로 개발된 것이지만 비디오 이외의 모든 어플리케이션에서도 이용할 수 있습니다(다만, 키보드로부터의 입력은 무효화됩니다).

Flash CS3의 새로워진 비디오 재생 컴퍼넌트에 이 기능이 포함되어 있습니다. 지금부터는 ActionScript에 접하는 일 없이 간단하게 풀 스크린 대응의 비디오 어플리케이션을 개발하는 것도 가능합니다(이 경우 HTML 안의 embed/object 나 SWFObject 코드의 allowFullScreen 파라미터를 잊지 않고 true로 설정하는 것에 주의해 주세요).이 기능에 대해 자세한 것은 Tracy Stampfli 씨가 집필한 Flash Player 디벨로퍼 센터 기사 「Flash Player 9 의 풀 스크린 모드에 대해 」를 참조해 주세요.

또 하나의 주목 할만한 기능은 뮤직 투시기을 작성할 때 사용할 수 있는 오디오 스펙트럼 해석 기능 입니다. 새롭게 정비된 SoundMixer 클래스에는 computeSpectrum()라고 하는 이름의 메소드가 포함되어 있어서 이 메소드를 이용하는 것으로 음악을 수치화할 수 있습니다. 그리고 수치화된 데이터를 바탕으로 쿨한 오디오 애니메이션이나 뮤직 투시기를 작성할 수 있습니다. 이 기능을 소개하는 매우 효과적인 튜토리얼에 대해서는 Peter deHaan 씨의 블로그의 엔트리 를 참조해 주세요.

그리고 마지막으로...
이 기사를 마치기 전에 참고 정보를 수집하기 위한 가이드를 소개하고 싶지만 그 전에 우선 이번 완전히 새로운 언어가 도입되었음에도 불구하고 매우 포괄적인 Flash CS3 Professional 헬프 파일을 제작한 Flash 서포트 팀에 대해서 칭찬을 보내고 싶습니다.

ActionScript 3.0과 Flash CS3는 아직 신출내기 단계입니다. 따라서 아직 관련 자료가 그만큼 많지는 않습니다. 향후 자료가 증가해 갈 것은 틀림없습니다. 현시점에서의 퍼스트 스텝으로서는 ActionScript 3.0과 Flash에 관한 최신 또는 갱신판의 기사, 샘플, 퀵 스타트 튜토리얼 등이 다수 게재된 Flash 디벨로퍼 센터를 북마크하는 것을 추천합니다. 또 Adobe.com에서 공개중의Flash CS3 LiveDoc 및Flex 2 LiveDoc도 참조하도록 해 주세요.(이 기사에서도 반복하여 참조한 것처럼) 이것들은 계속적으로 갱신되는 헬프 파일을 포함한 유용한 자원이며 각 항목에 대해서는 아도브의 서포트 스탭이나 다른 디벨로퍼가 코멘트를 쓰는 곳도 준비되어 있습니다.

아울러 2006년 중순부터 ActionScript 3.0과 Flex 2에 관한 복수의 서적과 DVD 를 출판하여 Flash 커뮤니티에 공헌해 주셨던 Joey Lott 씨에 대해서 이 자리를 빌려 Flash 커뮤니티의 일원으로서 개인적인 사의를 표하고 싶습니다. 이러한 서적•DVD는 매우 알기 쉬운 참고 자료입니다. 그리고 Colin Mook 씨에 의한 「Essential ActionScript 3.0 」가 출판되는 것을 기다릴 뿐입니다.

어땠습니까.이 기사를 읽는 것으로 ActionScript 3.0의 개념 이해가 깊어지면 다행입니다. 여러분도 꼭 이 훌륭한 최신 테크놀러지를 경험해 보세요.

영문 포스트 주소 : http://www.adobe.com/newsletters/edge/may2007/articles/article6/index.html

    

설정

트랙백

댓글

[AS3] EventDispatcher의 이해

Programming/ActionScript 3.0 2007. 7. 13. 13:09
자료를 찾다가 AS3의 이벤트 모델에 대해 쉽게 설명된 자료가 있어서 내용 추가 및 수정하였다. AS2의 컴포넌트에서 사용했던 EventDispatcher는 AS3에서 모든 표시 오브젝트에서 사용하고 있는 EventDispatcher의 표준이 되었다. AS2에서는 addListener도 사용했으나 AS3에서는 좀더 구체적으로 Event를 dispatch 할 수 있는 EventListener만을 사용하고 있다.

AS3 이벤트 모델 개요
AS3의 이벤트 처리는 AS2의 이벤트처리와 조금 다른 것을 볼 수 있다.

1. 이벤트는 “전파”한다
AS3의 표시 오브젝트 DisplayObject으로부터 발생한 이벤트를 그 이벤트를 받은 오브젝트 뿐만이 아니라 다른 오브젝트에서도 리슨 할 수 있다.

발생한 이벤트(클릭되었다 등)는 상자가 된 오브젝트를 부모로부터 자식에게 자식로부터 부모에게 이벤트가 전해져 가는 모델을 채택하고 있다. 이 개념은 이벤트의 전파(event propagation)라 불린다. 이벤트는 트리 구조 안을 이동하면서 각층(노드)에서 대응하는 리스너가 있을지를 검사하고, 있을 경우에는 그 리스너를 실행하게 된다.

예를 들어, 아래와 같이 상자 구조가 있다고 했을 때 DisplayObject (Sprite)를 생각해 보면, Sprite mc_01의 안에 mc_02 라는 Sprite이 있고 그 안에 mc_03라고 하는 Sprite이 있는 구조로 되어 있다. 여기서 mc_03를 클릭한다고 했을 때 AS2에서는 mc_03에 리스너를 등록할 필요가 있었지만 AS3에서는 mc_03 뿐만이 아니라 mc_02와 mc_01라는 Sprite에 설정한 리스너로 mc_03에서 이벤트를 취급할 수가 있다.

 
[상자 구조 샘플]

이것을 적절히 사용하면 이벤트 처리를 집중화시키는 것이 가능하다 .예를 들면 mc_02 ,mc_03에 공통의 이벤트 처리를 하고 싶은 경우라면 각각의 오브젝트에 이벤트 리스너를 등록할 필요가 없다.

2. 전파의 종류
전파는 아래와 같이 3단계로 분류된다.

1. 캡처-단계
2. 타켓-단계
3. 버블링-단계

이벤트의 전파는 원래 DOM (문서 오브젝트 모델)에 대한 이벤트 모델로서 브라우저에 도입된 것이다. (Netscape의 「이벤트 캡쳐링」모델,  Microsoft의 「이벤트 버블링」모델) W3C에 책정되고 있는 이벤트 모델이나 DOM에 대해서는 더 많은 정보가 필요해서 생략한다. 그러나 그 구현 방법은 ActionScript의 이벤트모델과 매우 유사하기 때문에 간단하게라도 알아 두는 편이 도움이 될 것 같다.

3.  캡쳐-단계
AS3에서 제일 초기에 실행되는 것은 이 캡쳐-단계다. 계층 구조의 오브젝트를 검사(리스너가 있는지를 조사)해 가면서 발생한 이벤트에 대응하는 리스너가 있으면 실행하게 된다. 캡쳐-단계에서의 이벤트는 루트로부터 이벤트가 발생한 타겟을 향해서 전파해 나간다.

위 샐플로 이야기하면 mc_03이라는 무비클립이 클릭되었을 경우 타겟은 mc_01 ,mc_02의 순서로 이벤트의 검사하게 된다. 타겟이 되는 mc_03의 이벤트 검사는 캡쳐-단계에서는 포함되지 않는다.

4.  타겟-단계
두번째로 이벤트의 검사를 하는 것은 타겟 단계이다. 이벤트가 발생한 타겟 자체의 이벤트 리스너를 실행한다. AS2의 관점에서 생각하면 이 타겟 단계만 실행된다고 할 수 있다. ‘

5.  버블링-단계
마지막에 이벤트의 검사를 하는 것은 버블링 단계다. 캡쳐-단계와는 반대로 타겟으로부터 루트를 향해서 전파 해 나간다.

위 샘플로 말하면 mc_03이 클릭되었을 경우 타겟은 mc_02 ,mc_01의 순서로 이벤트의 검사를 한다. 타겟이 되는 mc_03의 이벤트 검사는 버블링 단계에서도 포함되지 않는다.

6.  리스너는 중복 실행되지 않는다
여기서 생각해볼 것은 위에서 캡쳐단계와 버블링단계에서 처럼 리스너가 이중으로 실행된다고 생각할 수 있겠으나 그렇지는 않다. AS3의 캡쳐단계에서 리스너는 디폴트로 무효가 된다. 즉, 실질적으로 타겟으로부터 시작해 루트를 향해서 이벤트가 전파 해 나갈 뿐인 것이다. 물론, 캡쳐단계에서 리스너를 유효하게 할 수도 있지만 그럴 경우에는 버블링 단계에서 리스너가 무효가 된다.
양쪽 모두의 이벤트를 유효하게 할 수도 있다 이는 아래에서 이야기한다.


AS3 이벤트 관련의 클래스, 메소드에 대해
이벤트의 전파를 어떻게 제어하는 지와 관련된 클래스나 메소드에 대해 살펴보면 다음과 같다.

1.  addEventListener 메소드
AS3의 표시 오브젝트인 DisplayObject는 EventDispatcher를 상속하고 있다. 따라서 DisplayObject인 모든 군은 addEventListener 메소드를 사용할 수 있다. 여기서 AS3의 EventDispatcher.addEventListener 의 문장구조를 보면 다음과 같다.
addEventListener(
type:String,
listener:Function,
useCapture:Boolean = false,
priority:int = 0,
useWeakReference:Boolean = false
):void
먼저 기본이 되는 인수 type과 listener에 대해서는 기존 AS2의 EventDispatcher 와 다르지 않다. type 은 이벤트 타입(이벤트의 이름, “click” 등)이다. listener는 리스너 핸들러 함수다. 이벤트가 발생하여 리슨 되었을 때에 실행되는 함수다. 나머지의 인수는 옵션인데 설정하지 않는 경우는 디폴트 값이 적용된다.

useCapture는 캡쳐-단계에 리슨을 실시할지의 Boolean 값이다. 디폴트 값은 false다. useCapture를 true로 설정했을 경우 그 리스너는 캡쳐-단계에 이벤트를 리슨 하게 되지만 반대로 버블링 단계에서는 이벤트를 리슨 하지 않는다.

양쪽 모두 리슨 하는 경우는 useCapture의 값을 true / false로 하는 2개의 이벤트 리스너를 등록할 필요가 있다. 또, 레퍼런스에 의하면 캡쳐 단계에서 이벤트를 리슨 하게 되면 계산 처리의 부하가 커진다고 하니 특별한 이유가 없을 때에는 디폴트 값 false로 해 두는 것이 좋을 것이다.

priority는 우선도를 나타낸다. 수치가 큰 것일 수록 선행 처리된다. priority 값이 같은 경우에는 등록된 순서대로 처리된다. 부의 값도 이용할 수 있으므로, 디폴트값(0)을 기준으로 우선도를 설정할 수 있다. 다만, 우선도의 높은 처리가 완료되고 나서 낮은 처리가 다시 시작되는 것은 아니다..

useWeakReference는 리스너에 의한 참조가 약참조인지 어떤지를 나타내는 Boolean 값이다. 디폴트는 false이고 이는 강참조를 나타낸다. useWeakReference의 값을 true로 했을 경우에는 리스너의 가베지 콜렉터로부터 회피된다. 이에 대한 내용은 전에 작성한 포스트에서 확인할 수 있다.

2.  Event 클래스(오브젝트)
AS2의 EventDispatcher는 리스너에게 건네지는 이벤트 오브젝트와 type 프롭퍼티는 Object형태로 전달되었다. 하지만 AS3에서는 Event 클래스가 준비되어 있고 그것을 확장한 여러 가지 서브 클래스가 있다. 예를 들면 마우스 이벤트용의 MouseEvent 클래스나, 키보드 이벤트용의 KeyboardEvent 클래스 등이다.

KeyboardEvent 이벤트는 조작된 키의 키코드를 가지는 등 각각이 잘 정리되어 있다. Event 클래스를 확장하여 자작의 커스텀 클래스를 만들 수도 있다. 이는 예전 포스트에서 이미 내용을 기술해 놓았다.

3.  Event 클래스의 프롭퍼티
이벤트 오브젝트의 베이스가 되는 Event 클래스의 프롭퍼티를 보면 다음과 같다.

bubbles 프롭퍼티는 그 이벤트가 버블링 할지를 나타내는 Boolean 값이다. 디폴트는 false이고 그 경우 이벤트는 버블링 하지 않는다. MouseEvent 등은 true로 설정되어 있고 버블링 단계도 기능한다. 서브 클래스마다의 bublles 프롭퍼티는 레퍼런스를 참조해야 할 것 같다.

cancelable 프롭퍼티는 이벤트의 디폴트 동작을 캔슬할 수 있을지의 Boolean 값이다. 디폴트 동작의 캔슬에 대해서는 전 포스트에서 기술 한 적이 있다. isDefaultPrevented 프롭퍼티는 캔슬이 끝난 상태인지 어떤지를 보존하는 Boolean 값이 된다.

currentTarget / target 프롭퍼티는 각각 타겟의 참조다. target은 이벤트가 발생한 오브젝트의 참조다. currentTaget은 이벤트가 전파 하고 있을 때 이벤트가 어디에 있는지를 나타낸다. 즉, 오느곳의 오브젝트로 리스너를 검사하고 있는지를 나타내어 그 오브젝트의 참조를 돌려준다. target 프롭퍼티는 하나의 이벤트 오브젝트로 공통이지만 currentTaget 프롭퍼티는 전파 하는 과정에서 변해간다.

eventPhase 프롭퍼티는 이벤트가 어느 단계에 있는지를 나타내는 정수치를 가지고 있다.
1 - 캡쳐-단계
2 – 타겟-단계
3 – 버블링-단계

type 프롭퍼티는 이벤트 타입을 나타내는 String 값이다. 예를 들면 "click" 이나 "mouseOver" 등. addEventListener 의 type 값과 조합된다. 리스너는 이 값을 지정하여 이벤트를 리슨 한다.

4.  이벤트는 타겟 단계 밖에 동작하지 않아?
캡쳐-단계와 버블링 단계가 일어나는 것은 DisplayObject 오브젝트만이다. AS2 같이 표시 되어 있지 않은(표시 리스트에 없다) 오브젝트로부터도 이벤트는 dispatch 된다. 예를 들어 “로드가 완료했다”등이라고 하는 것과 같은 이벤트에 대해서도 dispatch 및 청취자는 같은 구조를 취한다. 이러한 이벤트는 많은 경우 전파 할 필요가 없고 이벤트는 타겟으로 직접 플로우 한다.

5.  이벤트의 전파를 정지한다
Event 클래스에는 stopPropagation / stopImmediatePropagation라고 하는 메소드가 있다. 이것들을 이용하면 이벤트의 전파를 도중 캔슬할 수도 있다. 즉, 리스너 안에서 건네 받는 이벤트 오브젝트를 이용하여 그 이벤트의 전파를 멈출 수 있다.

stopPropagation 메소드는 그 이벤트의 전파 자체는 정지하지만 현재의 노드(검사중의 오브젝트)의 리스너는 모두 처리한다.
stopImmediatePropagation 메소드는 전파도 정지하고 현재의 노드의 다른 리스너도 처리하지 않는다.

6.  이벤트의 디폴트의 동작을 캔슬한다
많은 이벤트에는 이벤트 발생시에 디폴트로 실행하는 동작이 있다. Event 오브젝트의 cancelable 프롭퍼티가 true의 경우에 한해서 Event.preventDefault 메소드를 이용하면 이러한 동작을 캔슬할 수 있다.

아래는 레퍼런스의 내용이다.

「예를 들어, 유저가 텍스트 필드에 문자를 입력했을 경우 디폴트 동작에서는 문자가 텍스트 필드에 표시됩니다. TextEvent.TEXT_INPUT 이벤트의 디폴트 동작은 캔슬하기 위해 preventDefault() 메소드를 사용해 문자를 표시하지 않게 할 수 있습니다.」

7.  이벤트의 dispatch
이벤트의 dispatch는 AS2의 EventDispatcher와 같이 dispatchEvent 메소드를 실행할 뿐이다. 다만, dispatchEvent에 건네주는 인수가 AS2에서는 Object이고 AS3는 Event 오브젝트라는 것이 다르다.
새로 Event 오브젝트를 만들고 dispatchEvent의 인수로 건네주게 된다.

Event오브젝트의 constructor는 다음과 같은 문장구조를 갖는다.
Event(event_type:String, bubbles:Boolean, cancelable:Boolean)
bubbles 와 cancelable은 옵션으로 생략 할 수 있다. 간단한 dispatchEvent는 아래와 같다.

my_obj.dispatchEvent(new Event(MouseEvent.CLICK));


    

설정

트랙백

댓글

[AS3] SoundMixer를 이용한 스펙트럼

Programming/ActionScript 3.0 2007. 7. 12. 00:44

var s:Sound = new Sound();
var sc:SoundChannel;
var ba:ByteArray = new ByteArray();
var array:Array;

s.load(new URLRequest("sound.mp3"));
sc = s.play(0,1);
this.addEventListener(Event.ENTER_FRAME, spectrum);
function spectrum(event:Event) {
        var a:Number = 0;
        SoundMixer.computeSpectrum(ba,true,0);
        for (var i=0; i < 50; i++) {
                a = ba.readFloat();
                var num:Number = a*400;
                trace(num);
        }
}
 





기본적으로 as3에서 스펙트럼을 구현할 때 위와 같은 형태로 만들 수 있다. 크로스 도메인 정책 파일을 서버에 구현해 놓지 않으면 로드된 사운드의 데이터에 액세스할 수 없다. 이는 BitmapData의 경우도 같다.


아래는 샘플로 작업한 위 결과물의 코드다.

package{

import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.events.Event;
import flash.events.MouseEvent;

import flash.media.Sound;
import flash.media.SoundMixer;
import flash.media.SoundChannel;

import flash.net.URLRequest;
import flash.utils.ByteArray;


public class SoundSpectrumTest extends Sprite {
        private var s:Sound;
        private var ba:ByteArray;
        private var mcAry:Array;
        private var main1:Sprite;
        private var sc:SoundChannel;
        private var recTotalNum:uint;


        public function SoundSpectrumTest() {
                s = new Sound();
                ba = new ByteArray();
                mcAry = new Array();
                main1 = new Sprite();
                sc = new SoundChannel();
                recTotalNum =300;
                addEventListener(Event.ADDED_TO_STAGE, initialize);
        }
        private function initialize(evt:Event):void {
                removeEventListener(Event.ADDED_TO_STAGE, initialize);
                loadSound();

        }
        private function setButtonEvent():void{
              play_mc.addEventListener(MouseEvent.CLICK, playHandler);
              stop_mc.addEventListener(MouseEvent.CLICK, stopHandler);

        }
        private function playHandler(evt:Event):void{
                sc.stop();
                createEnterFrame();
                sc = s.play(0, 10);
        }
        private function stopHandler(evt:Event):void{
                removeEnterFrame();
                sc.stop();
        }

        private function startSpectrumDisplay():void{
                var gap:uint = 1;
                for(var i:uint=0;i<recTotalNum;i++){
                        var mc:Rec = new Rec();

                        mc.x = i*(mc.width+gap);
                        mc.y = 230;
                        main1.addChild(mc);
                        mcAry.push(mc);

                }

                addChild(main1);
                main1.x = uint(stage.stageWidth/2 - main1.width/2);
                main1.y = uint(stage.stageHeight/2 - main1.height/2);
                createEnterFrame();
        }
        private function createEnterFrame():void{
                addEventListener(Event.ENTER_FRAME, leftSpectrum);
                addEventListener(Event.ENTER_FRAME, rightSpectrum);
        }
        private function removeEnterFrame():void{
                removeEventListener(Event.ENTER_FRAME, leftSpectrum);
                removeEventListener(Event.ENTER_FRAME, rightSpectrum);
        }
        private function loadSound():void {
                s.load(new URLRequest("sound.mp3"));
                s.addEventListener(Event.COMPLETE, loadedSound);

        }
        private function loadedSound(evt:Event):void{
                startSpectrumDisplay();
                setButtonEvent();
                sc = s.play(0, 1000);
        }
        private function leftSpectrum(event:Event):void {
                var left:Number;
                var leftNum:Number = 0;
                var leftTotalNum:Number = recTotalNum/2;

                SoundMixer.computeSpectrum(ba,true,0);

                while(leftTotalNum>=0){
                        left = ba.readFloat();
                        leftNum = left*400*sc.leftPeak;

                        mcAry[leftTotalNum].height = leftNum;
                        leftTotalNum--;
                }

        }
        private function rightSpectrum(event:Event):void {
                var right:Number;
                var rightNum:Number = 0;
                var rightTotalNum:Number = recTotalNum/2;

                SoundMixer.computeSpectrum(ba,true,0);

                while(rightTotalNum<recTotalNum){
                        right = ba.readFloat();
                        rightNum = right*400*sc.rightPeak;

                        mcAry[rightTotalNum].height = rightNum;
                        rightTotalNum++;
                }
        }
}
}
    

설정

트랙백

댓글