SPE(Simple Physics Engine)

Programming/Physics Engine 2007. 8. 9. 00:30
SPE(Simple Physics Engine) 라는 물리엔진인데 전혀 심플하지 않은 것 같다. 언어가 생소한데 무슨 언어인지는 잘 모르겠다... 아무튼 데모로 제공하고 있는 자료가 있어서 다운 받아서 실행해 봤는데 퍼포먼스가 엄청나다 이런 퍼포먼스가 웹상에서 지원이 된다면 엄청난 변화가 일어나지 않을까 싶다.

그 변화의 주축이 플래시라면... 앞으로의 기술 발전에 따라 충분히 가능한 일이 되지 않을 까 싶다. 자료를 다운 받아서 실행하면 바로 데모를 볼 수 있는데 시간 있는 분들은 한번 받아서 즐겨 보시길....









사용자 삽입 이미지


사용자 삽입 이미지 사용자 삽입 이미지 사용자 삽입 이미지


    

설정

트랙백

댓글

[AS3] APE에 추가된 클래스

Programming/Physics Engine 2007. 8. 8. 18:25
APE의 code repository에 보니 다운로드로 제공하고 있는 소스 파일 이외에 3개의 클래스가 은근슬적 추가된 것을 알게 되었다. 3개의 클래스는 IForce, VectorForce, CollsionEvent 이 세개의 클래스다. Force관련 추가된 클래스는 장력에 관련된 클래스를 제공하기 위해 만들어 놓았는데 기존에는
APEngine.addMasslessForce(new Vector(0,3));
형태로 Vector 클래스를 사용하였으나 이와 구분되는 VectorForce를 통해서
APEngine.addForce(new VectorForce(false,0,3));
이러한 형태로 사용하게 되었다. 추가된 VectorForce는 APEngine 클래스의 internal static Array 변수 forces에 등록됨으로써 중력에 관련하여 복합적으로 적용이 가능하게 되었다.  

CollsionEvent 클래스는 충돌을 체크하기 위해 Event 클래스를 확장하여 만들어 놓았다. 이는 AbstractItem 클래스를 확장하고 있는 클래스에 대한 충돌을 이벤트처리하기 위해 만들어져 있다. 실제로 code repository에 있는 AbstractItem 클래스는 EventDispatcher를 상속하고 있다. CollsionEvent에는 아래와 같은 이벤트타입이 있다.
public static const COLLIDE:String = "collide";
public static const FIRST_COLLIDE:String = "firstCollide";
COLLIDE는 충돌이 발생할 때마다 매번 dispatch 하며 FIRST_COLLIDE는 처음 충돌이 발생한 시점에서 한번만 dispatch하게 된다.

이 이벤트 처리는 Flade에서 지원하던 충돌 관련 기능을 추가한 것이다. 이로서 Flade에서 지원하던 대부분의 기능은 APE에 포함된 것으로 보이며 앞으로 오브젝트에 관련된 클래스들이 추가 될 것으로 기대된다.

    

설정

트랙백

댓글

[AS3] 3대(APE, Revive, Fisix) Physics Engine 정리

Programming/Physics Engine 2007. 8. 8. 11:15
며칠 동안 2D 물리엔진을 검토 테스트해 보고 가장 알려져 있는 3가지 물리엔진에 대한 개인적인 생각을 적어 볼까 한다. 깊이 있게 테스트해보지 않은 관계로 자세한 부분까지 이야기 할 수는 없을 것 같고 개인적으로 테스트해본 결과에 대한 짧은 생각을 정리해 본다. 좀더 깊이 있는 테스트는 각자 관련 사이트에서 소스를 다운 받아서 테스트 해 보길 바란다.











3대 Physics Engine 정리

타이틀

APE

Revive

Fisix

제작

MIT(Alec Cove)

Andre michelle

Fisix 회사

라이센스

LGPL

Free

Free(제한적)

규모

API 문서

Directory Listing Denied

다운로드 한 소스로부터

Adobe Flex2 Language Reference

특징

Simple

고속, 정확

다기능

표현 범위

정방형 파티클 등

베이지어곡석 표면 처리 등

로프, 프렉탈, 지형 등

테스트 예

APE

Revive

Fisix


 

APE

먼저 처음 접했던 것은 APE 물리엔진이었다. 이것은 AS2 버전으로 이미 알려졌던 Flade 엔진을 AS3로 고치면서 새롭게 APE라는 이름으로 나오게 되었다. 3개의 엔진 중에 가장 심플한 클래스 구조를 가지고 있다. 19개의 클래스 중에 public 클래스는 불과 12개 밖에 되지 않기 때문에 소스를 분석하는데도 그리 어렵지 않을 것 같다.

아직 AS2버전에 있던 기능들을 모두 APE에 적용한 상태는 아니기 때문에 앞으로 버전업을 통해서 추가될 것으로 기대된다. 기본적으로 정방형 형태와 파티클 형태인 원들을 만들 수가 있는데 wheel과 같이 자동차 바퀴와 같은 파티클을 통해서 역학운동 표현이 가능하다.

그러나 아직까지 많은 기능을 포함하고 있지 않기 때문에 표현의 범위가 적다. 다각형을 표현할 경우 파티클들의 조합으로 가능할 것으로 생각되지만 실질적인 클래스를 지원하고 있지 않기 때문에 파티클들을 extends 해서 사용할 필요가 있다.

하지만 비교적 간단한 방법으로 표현이 가능하기 때문에 사용상에 어려움은 없다. API 문서를 지원하지만 원본 소스를 직접 보고 테스트 해보는 것이 도움이 될 것 같다.

 
Revive

Revive는 두 번째로 접하게 된 물리 엔진이다. 2005, 2006 MAX conference에도 스피커로 참여했던 Andre michelle이 만든 엔진이다. Revive의 경우는 베이지어 곡선 처리가 가능하여 surface 표현할 때 곡선처리가 가능하다. 물리엔진의 계산 표현이 비교적 정교하여 움직임이 매끄럽고 속도가 빠르다. 마우스 이벤트에 대해 기본적으로 제공하고 있기 때문에 약간의 확장을 통해서 마우스를 통한 인터렉션이 자유롭다.

엔진의 API문서는 제공되고 있지 않으며 소스코드에 있는 몇 개의 샘플을 통해서 충분히 손쉽게 사용해 볼 수 있다. 다운 받은 엔진의 소스를 그대로 사용할 경우 몇 가지 error를 발견할 수 있는데 이는 단순한 package import를 하지 않은 것이기 때문에 필요한 package import하여 사용해야 한다. 이는 아무래도 앙드레미쉘이 class path default로 설정해 놓은 상태에서 클래스를 저장하여 에러를 발견하지 못한 듯 싶다.

Revive도 파티클의 조합으로 다각형을 표현해 볼 수 있는데 경계가 되는 파티클들이 범위를 벗어났을 때 약간을 오류가 발생하고 있어서 다각형의 경우는 새로운 기능이 확장되어야 할 듯 싶다. 이 문제로 Revive package 외에 physics package를 만들어 놓았는데 physics 패키지에서는 경계 부분의 오류를 바로잡은 다각형을 지원하고 있다. 하지만 클래스 자체가 사용하기 용이하게 제작되어 있지 않은 관계로 앞으로 업데이트에 기대를 가져봐야 할 것 같다.

 
클래스 구조

* de/
    o popforge/
        + revive/

                      # application/ - 어플리케이션
                            * SceneContainer.as – 뷰어
                            * Simulation.as - 물리 엔진

                      # display/ - 표시
                            * ExtDrawAPI.as – Graphics을 사용하고 호를 그리는 확장
                            * IDrawAble.as – 표시오브젝트 관련 Interface

                      # forces/ -
                            * FixedSpring.as - 고정 용수철
                            * IForce.as -
힘을 가지는 오브젝트를 위한 Interface
                            * Spring.as -
용수철

                      # geom/ - 지오메트리
                            * BezierCubic.as – 3 베이지어곡선
                            * BezierQuadric.as - 4
베이지어곡선
                            * BoundingBox.as - 바운딘
                            * ICurve.as - 곡선을 위한 Interface
                            * Vector.as - 2
차원 벡터

                      # member/ - 물체
                            * Immovable.as - 움직이지 않는 물체의 base class
                            * ImmovableBezierQuadric.as -
움직이지 않는 4 베이지어곡선
                            * ImmovableCircleInner.as - 움직이지 않는 원
                            * ImmovableCircleInnerSegment.as - 움직이지 않는 호
                            * ImmovableCircleOuter.as - 움직이지 않는 원
                            * ImmovableCircleOuterSegment.as - 움직이지 않는 호
                            * ImmovableGate.as
                            * ImmovableGroup.as -
움직이지 않는 그룹
                            * ImmovablePoint.as - 움직이지 않는 점
                            * Movable.as - 움직이는 물체의 base class
                            * MovableCircle.as -
움직이는 원
                            * MovableParticle.as - 움직이는 점
                            * MovableSegment.as - 움직이는 선

                      # resolve/
                            * DynamicIntersection.as -
동적 접점
                            * IDynamicIntersectionTestAble.as - 동적인 접점을 테스트하는Interface
                            * IResolvable.as

        + surface/ - 인터페이스

                      # display/ - 표시
                            * DefaultTextFormat.as - 이 라이브러리의 디폴트 텍스트 포맷
                            * FPSCounter.as - FPS 카운터

                      # io/ - IO
                            * PopKey.as –
키 코드 상태를 관리
                            * PopMouse.as - mouse button의 상태를 관리

                      # valuation/ -
                            * Potentiometer.as –
미터

Fisix

Fisix 엔진은 0.5 alpha버전으로 공개되어 있으나 위의 APE, Revive 보다 많은 기능을 포함하고 있다. 소스를 다운로드 하면 API문서, 라이브러리, 샘플 6개와 나머지 라이선스와 관련된 텍스트 파일을 볼 수 있다. Public 클래스는 47개 정도 되어 꽤 많은 기능을 제공하고 있다. as파일은 없으며 swc 파일만을 배포하고 있는 듯 하다.

제공하는 샘플
* Example1 … 타이머, 엔진 표현, 직선 표면 1 , 차 바퀴
* Example2 … ENTER_FRAME , 엔진 표현, 차 바퀴
* Example3 … ENTER_FRAME , 엔진 표현, 용수철, 마우스 interaction
* Example4 …
숫자 키1 ~4 ,5 ~6 모드 변환, 파티클의 자동 삭제
* Example5 … 로프, SWF 부품(타이어)
* Example6 …
유모차

Fisix 엔진의 경우는 직접적으로 많이 접해보지 않았기 때문에 다음 기회에 포스트해 보도록 하겠다.


3개 엔진을 접해본 결과 결과적으로 기능적인 면에서는 Fisix가 우위를 점하고 있다고 하겠다. 또한 커뮤니티 사이트도 비교적 활발하게 운영되고 있는 것을 높이 평가할 만 하다. 하지만 구체적은 클래스 구조를 탐구하기 어려운 부분이 있고 다기능으로 인한 클래스 구조의 복잡함은 응용에 있어서 까다로운 부분이 없지 않다.

APE의 경우는 Flade 엔진을 개선한 부분도 있으나 아직까지 많은 기능을 포함하고 있지 않기 때문에 응용 과정에서 기존의 클래스를 확장하여 가공할 필요가 있다. 하지만 기본적으로 원본 클래스를 가공하여 사용하는 것은 라이센스의 규약에 있어서 문제가 될만한 것이기 때문에 기존의 클래스를 가공하기 보다는 확장을 통해서 기능을 추가해 사용해야 할 것으로 보인다.

클래스 구조가 비교적 단조롭기 때문에 물리엔진 보다는 잘 짜여진 클래스 구조를 공부하는데 도움이 될만한 자료라고 생각된다.

Revive의 경우는 앙드레미쉘의 개인적인 성향이 강한 물리엔진이기 때문에 약간의 범용적이지 않은 부분도 보이지만 엔진으로서의 가치와 앞으로 문제점을 보완한다면 충분히 좋은 엔진이 될 것으로 기대된다. 개인적으로는 physics 패키지와 revive 패키지를 적절히 접목하여 좀더 구체적이고 단단한 물리엔진을 만들면 좋을 것 같다.

physics revive 패키지를 분석해 본 결과 세밀한 코드 자체에는 비슷한 부분이 있지만 전체적인 흐름(구조)에서는 다른 형태를 가지고 있어서 이 둘을 하나로 혼합하기에는 적지 않은 시간과 생각이 필요할 듯 싶다. 하지만 앙드레미쉘의 열정이라면 언젠가는 지금보다 바람직한 물리엔진을 만들어 내지 않을까 기대해 본다.

3개의 물리엔진에서 어떤 것이 좋고 어떤 것이 나쁘다는 결론은 내리기 어렵다. 3개의 물리엔진 모두 진화과정에 있기 때문에 앞으로의 업데이트 과정을 지켜봐야 할 듯 싶다. 물리엔진이라는 것이 기본적인 파티클을 통해서 재미적인 결과물을 보기 위한 목표가 될 수 없기 때문에 응용에 있어서 사용하기 편하고 안정성이 높은 것이 높은 점수를 받을 수 밖에 없다
    

설정

트랙백

댓글

연말에 등장하는 FlashPlayer9 update3에서 실현되는 기능 향상이란?

Programming/Etc 2007. 8. 7. 05:55
퍼포먼스 향상에 주력 한 업데이트

2006년 6월에 발표된 flashPlayer9는 flash CS3 시대를 예감 시키는 중요한 내용을 포함하고 있었다. FlashPlayer9는 올 연말에도 대폭적인 업데이트를 예정하고 있다고 한다. Flash나 ActionScript의 향후를 예측하는데 있어서 중요한 FlashPlayer9 update3의 개요에 대해서 Adobe Systems사 FlashPlayer담당 그룹 프로덕트 메니저 Emmy Huang의 이야기다.

Update3은 주로 퍼포먼스 향상에 주력하고 있어 다양한 신기능의 추가나 기능 강화를 도모하고 있다고 한다. 또 이번은 크로스 플랫폼에서 제공하는 것을 중시하고 있고 처음으로 Windows/Macintosh/Linux판을 동시에 출시 한다고 한다.

추가되는 새로운 기능으로서는 크게 나누어 4개가 있는데, 우선 첫 번째로 거론되는 것이 하드웨어의 가속화에 의한 풀 스크린 모드이다.(예전에 포스트로 올려 놓은 것이 있는데 동영상을 위해서 기초적인 기능만을 첨부한 swc파일 컴포넌트로 복사해야 한다)  update3은 하드웨어 스켈링을 하기 위한 랜더링 속도를 향상하여 고해상도인 브라우저상에서 재생하고 있는 동영상을 부드럽게 재생할 수 있는 것이 특징이라고 한다. 물론 종래의 버전에서도 풀 스크린을 서포트하고 있고 고해상도의 동영상을 재생할 수 있었지만 컴퓨터의 처리 능력이 높지 않으면 재생이 어려웠던 것이 사실이다. 그러나 update3에서는 보다 많은 머신으로 고해상도의 동영상을 풀스크린으로 재생 할 수 있다. 『웹 브라우저로 이만큼의 HD 퀄리티의 영상을 제공할 수 있는 것은 adobe에 있어서도 매우 익사이팅한 일입니다』 라고 FlashPlayer 그룹 프로덕트 매니저의 Emmy Huang의 이야기다.

리치 인터넷 어플리케이션 관련 기능 강화


이 밖에도 리치 인터넷 어플리케이션 관련해서도 기능 강화가 있다고 한다. Adobe 플랫폼 컴포넌트에 추가된 새로운 플레이어의 캐시는 플랫폼 라이브러리를 포함하는 장소에서 정확히 브라우저 캐시와 같이 한 번 다운로드를 해 저장하면 두 번째에서는 곧바로 사용할 수 있게 된다고 한다. 이 기능을 우선 최초로 활용하는 것은 Flex 체제라고 한다. 약 500KB 정도의 Flex 파일을 캐시  시키는 것으로 swf파일의 사이즈를 작게 하는 것과 동시에 start up 시간을 단축할 수 있다고 한다. 현재 adobe labs에서 베타판을 다운로드하여 이 기능을 사용해 볼 수 있다. 미래지향적으로 라이브러리를 추가해 나가기 때문에 캐시를 사용해 다양한 작업을 시도할 수 있을 것이라고 이야기한다.

또 Flash와 브라우저와의 통신에 사용하는 API가 있지만 이 커뮤니케이션도 개선되고 있다고 한다. 즉 브라우저의 컴퍼넌트와 FlashPlayer의 통합, 인터그레이션이 보다 좋아지고 있다고 한다.

그 외의 추가 기능은 아래와 같다.

Internet Exploler(IE)에 보안 관련 API가 서포트 되고 있었지만 Windows 플러그인 외에 FireFox에도 서포트 된다는 설명이다.

Flash Media Server(FMS)에 전달되는 컨텐츠의 보호를 할 수 있도록 RTMP 프로토콜로 암호화가 서포트 된다고 한다.

    

설정

트랙백

댓글

[AS3] Array의 index값이 소수이면 index가 아니다?

Programming/ActionScript 3.0 2007. 8. 6. 12:57
var ary:Array = new Array(111,222,333);
trace(ary[1/2]); // undefined
AS3의 dynamic 클래스의 인스턴스는 실행시 동적으로 프로퍼티를 추가할 수 있는데 예를 들어
var obj:Object = new Object();
obj.value = 444;
trace(obj.value); // 444
위와 같이 obj에 추가한 value 변수의 값을 동적으로 할당할 수 있다. ActionScript에서는 이러한 동적인 프로퍼티의 할당은 해시 맵(연상배열 or 결합배열)으로 되어 있어 [] 연산자로 액세스가 가능하다.
var obj:Object = new Object();
obj.value = 555;
trace(obj["value"]); // 555

obj["name"] = "AS3";
trace(obj.name); // AS3
이와 같이 Array도 dynamic class이므로 동적으로 프로퍼티를 할당할 수 있다.
var ary:Array = new Array(111,222,333);
ary["value"] = 444;
ary["name"] = "AS3";

trace(ary.value); // 444
trace(ary["name"]); // AS3
trace(ary[0]); // 111

배열의 index를 문자열이 아닌 음수나 소수로 할 경우에는 정수로 치환되지 않고 문자열인 결합배열로 취급한다.
var ary:Array = new Array();
ary[1/2] = 111;
trace(ary[0.5]); // 111
trace(ary["0.5"]); // 111

배경에는 length를 통해서 배열 원소의 개수를 취득할 수 있는데 이때 결합배열(문자열 키로 참조)로 되어 있는 것은 length에 포함되지 않는다.
var ary:Array = new Array(111,222,333);
ary[1/2] = 111;
trace(ary.length); // 3

아래와 같이 동적으로 배열의 인덱스 값을 계산하여 사용할 경우에는 int형으로 치환해 주는 것에 주의해야 한다.
var ary:Array = new Array(111,222,333);
ary[int(1/2)] = 444;
trace(ary[0]); // 444

    

설정

트랙백

댓글

[AS3] 1행짜리 Tetris

Programming/ActionScript 3.0 2007. 8. 6. 08:47

[Flash] http://jasu.tistory.com/attachment/cfile9.uf@244FC33F58802128306F6E.swf


게임방법 : [H][L]왼쪽과 오른쪽, [J][K] 회전, [SPACE]는 떨어뜨리기.
게임 화면을 클릭해서 키보드 포커스를 줄 필요가 있다.


* import *를 사용함.
* 정수명이나 이벤트명은 직접적으로 쓰면 import를 생략.
* for문이나 if 의 생략 할 수 있다 {}은 생략.
* const 보다 var를 씀.
* with 사용할 수 있는 곳은 사용.
* true , false 보다 1 ,0
* switch ~case 보다 함수 테이블을 사용.
* new Array() 보다 []
* drawRect()의 endFill()를 생략.
* 인스턴스 변수를 1 행으로 전부 선언하면 var 를 줄일 수 있다.
* 로컬 변수 를 인스턴스 변수로 옮기면 var를 삭제할 수 있다.
* 클래스명과 constructor 이외의 public ,private는 삭제.
* 배열 의 첨자에 사용한 int 형 변수 이외의 「: 형명」은 삭제.
* 변수 이름이나 함수 이름을 1 문자로.
* 개행은 모두 삭제, 연속하는 공백은 하나의 공백으로.
* 연산자 ,{ ,} ,( ,) ,; , 의 전후의 공백은 삭제.
* 「} 」의 직전의 「; 」는 삭제.

이러한 방법으로 외국의 한 ASer가 1872 문자(1.83kb)의 테트리스를 만들어 놓은 것이 있어 올려 놓는다. 0x000000과 같은 것을 0으로 할 수 있겠지만 이미 질려서 여기까지 한다는 제작자의 설명이 있었다. 테트리스는 게임 프로그래밍에 있어서 기초적인 것이지만 프로그래밍의 중요한 구조적 성격을 가지고 있다고 생각된다.

예전 DOS시절에 C언어로 헥사와 테스트리스를 접목한 게임을 만든 적이 있었는데 그때 만들었던 게임의 룰은 테트리스 처럼 가로 행이 채워졌을 때도 삭제하고 대각선과 세로에서도 같은 색이 연속으로 5개 있을 때도 삭제하게 했던 기억이 난다. 도스 시절이었기 때문에 아마도 5.25인치 디스크에 보관을 하다가 잃어버린 것 같다.

Assembly 언어는 대학교 다닐 때 가장 골치 아픈 녀석이었다. 직접 기계어로 작성한다는 매력과 그 속도 면에서 반할만한 언어이기는 했지만 그것을 이해하기에는 나의 두뇌가 너무 아날로그적이었던 기억이다. C언어를 배울 당시에도 point(*) 개념으로 point -> point 까지만 들어가도 그때부터 뇌세포가 사경을 헤맸으니…

그러고 보면 ActionScript는 참 친절한 언어라는 생각이 든다… 나 또한 ActionScript를 향해 좀더 친절해 져야겠다는 생각이 든다.. 쿠쿠



Tetris.as 소스

package{import flash.display.*;import flash.text.*;public class Tetris extends Sprite{var W=10,H=20,T=16,C=[0x000000,0x00FFFF,0xFFFF00,0x22FF22,0xFF2222,0x4444FF,0xFF8844,0xFF22FF],P=[[[1,1,1,1]],[[0,2,0],[2,2,2]],[[3,3,0],[0,3,3]],[[0,4,4],[4,4,0]],[[5,5],[5,0],[5,0]],[[6,6],[0,6],[0,6]],[[7,7],[7,7]]],s=[30,20,10,5],b=[],p,r,t=new TextField(),f=[],l=0,c=0,g,j:int,i:int,v:int,u:int;public function Tetris(){t.x=W*T;t.autoSize="left";t.text="Next:";addChild(t);for(j=0;j<H;++j){b[j]=[];for(i=0;i<W;++i)b[j][i]=0}f[72]=function(){v-=w(v-1,u,p)};f[74]=function(){m(1)};f[75]=function(){m(0)};f[76]=function(){v+=w(v+1,u,p)};f[32]=function(){d();h()};stage.addEventListener("keyDown",function(e){if(f[e.keyCode]){f[e.keyCode]();n()}});h();h();addEventListener("enterFrame",function(e){if(--c<0){c=s[int(l/10)];if(w(v,u+1,p)){++u;n()}else{d();h()}}})}function m(o){var q=new Array(p[0].length);for(j=0;j<q.length;++j)q[j]=[];for(j=0;j<p.length;++j)for(i=0;i<q.length;++i)if(o)q[i][p.length-1-j]=p[j][i];else q[q.length-1-i][j]=p[j][i];if(w(v,u,q))p=q}function n(){with(graphics){clear();for(j=0;j<H;++j)for(i=0;i<W;++i){g=0;if(u<=j&&j<(u+p.length)&&v<=i&&i<(v+p[0].length))g=p[j-u][i-v];if(!g)g=b[j][i];beginFill(C[g]);drawRect(i*T,j*T,T,T)}for(j=0;j<r.length;++j)for(i=0;i<r[j].length;++i){beginFill(C[r[j][i]]);drawRect((i+W+1)*T,(j+2)*T,T,T)}}}function w(x:int,y:int,p){for(j=0;j<p.length;++j){if(0>(y+j)||(y+j)>=H)return 0;for(i=0;i<p[j].length;++i){if(0>(x+i)||(x+i)>=W)return 0;if(p[j][i]&&b[y+j][x+i])return 0}}return 1}function d(){for(;w(v,u+1,p);u++);for(j=0;j<p.length;++j)for(i=0;i<p[j].length;++i)if(p[j][i])b[u+j][v+i]=p[j][i];for(j=0;j<H;++j)if(b[j].indexOf(0)<0){b.splice(j,1);b.unshift([]);for(i=0;i<W;++i)b[0][i]=0}l++;if(l/10>=s.length)l=0}function h(){p=r;if(p){v=(W-p[0].length)/2;u=0;if(!w(v,u,p))t.text="GAME OVER"}r=P[int(Math.random()*P.length)]}}}

*위 소스를 Tetris.as 파일로 생성하여 Flash CS3에서 Document class에 등록하고 퍼블리시 하면 된다.

    

설정

트랙백

댓글

[AS3] 스크립트 최적화 간단 정리

Programming/ActionScript 3.0 2007. 8. 6. 05:16

    *  기본
          o for 루프로 배열내 참조를 하는 경우는 미리 배열의 길이를 구하여 변수를 int/uint 형태로 한다.
          o 다른 클래스의 정수는 일단 로컬의 변수에 값을 대입하고 나서 루프를 사용한다.
          o 로컬 변수 선언은1 행으로 정리한다.
          o (AS2와 같이) 조건문이나 명령문을 고쳐 쓰지 않는다.
          o Object 형태는 사용하지 않는다.
          o 배열의 요소를 읽을 때는 형태 캐스트를 한다.
          o 가능한 한, int 형태를 사용한다
          o Point 형태나 Rectangle 형태등 잘 사용하는 오브젝트의 정수를 만들어 돌린다.
          o 패키지 변수·정수나 패키지 함수를 사용해서 가능한 한 클래스명 참조를 줄인다.
          o (.graphics나.transform 등의) 글로벌getter 프롭퍼티를 2 회이상 사용하는 경우는 로컬 변수에 대입해 사용한다.
          o getDefinitionByName(getQualifiedClassName(object))를 사용하는 대신에 커스텀 리플렉션 메소드를 만든다.
    * 표시
          o 프레임마다 비트 맵 처리가 필요한 경우, 미리 비트 맵 데이터를 작성하여 fillRect()/copyPixels()를 사용한다.
          o mx.utils.GraphicsUtil.drawRoundRectComplex()보다 flash.display.Graphics.drawRoundRectComplex()를 사용한다.
    * 비트 연산화
          o 2 의 누승을 곱하는 경우는 왼쪽 시프트를 사용한다.
          o 2 의 누승을 나누는 경우는 오른쪽 시프트를 사용한다.
          o int 정수 변환은 「>> 0 」
          o int 형태의 변수 교체에는 XOR 연산을 사용한다.
          o 부호의 변환에는 NOT 연산이나 XOR 연산을 사용한다.
          o 2 의 누승으로 나머지를 취할 때는 AND 연산을 사용한다.
          o AND 연산으로 짝수 판단한다.
          o Math.abs()를 사용하지 말고 절대치를 요구한다.
          o 2 개의 int 형태 변수의 부호가 일치할지를 조사할 때는 「eqSign = a ^ b >= 0; 」형태를 사용한다.
          o R5G5B5로부터 R8G8B8 에의 변환에는 비트 시프트를 사용한다.


    * TextField.text에 문자열을 추가할 때는 「+= 」으로 연결하는 것이 아니라 appendText()를 사용한다.
    * 필터의 blurX, blurY 프롭퍼티의 값은 2의 누승으로 한다.
    * 변수 중에 가능한 것은 할 수 있는 한 정수화 한다.
    * 루프의 내부로부터 가능한 처리를 줄인다.
    * 참조는 할 수 있는 한 짧게 한다.

    

설정

트랙백

댓글

[AS3] caurina Tweener 클래스 사용 방법

Programming/ActionScript 3.0 2007. 8. 5. 01:17
caurina Tweener는 Papervision3D를 접하면서 알게 되었는데 플래시에서 지원하고 있는 Tween 클래스보다 다양한 기능과 그 사용법도 간단하다. static 메소드를 지원하여 Tweener.addTween() 형태로 사용하며 파라미터로 넘겨주는 것은 아래와 같다.

Tweener 사용 방법


Tweener.addTween(DisplayObjectInstanceName, {x:-1050, y:300, _bezier:[{x:-575, y:450, z:-375}, {x:411, y:275, z:-337}, {x:344, y:114, z:370}, {x:-466, y:56, z:398}, {x:-336, y:305, z:-1177}], time:10, transition:"easeoutinexpo"});

위와 같이 트윈을 적용한 인스턴스와 그 인스턴스에서 트윈할 프로퍼티의 적용값을 지정하며 _bezier 형태로 복수의 포인트 간 포인트 적용으로 동선을 임의로 제작할 수 있다. time은 적용 시간을 나타내며 초단위이다. transition은 에싱의 형태를 지정.
           
Tweener.addTween(cube, {onStart:tweenStart, onComplete:tweenComplete, rotationX:active, rotationY:active, rotationZ:active, time:1.5, transition:"easeinoutexpo"});

위와 같이 모션의 시작 시점에서 실행할 handler 메소드를 지정할 수 있으며 끝나는 시점과 update마다 실행 하는 handler 메소드도 지정 가능하다. handler 메소드의 종류는 아래와 같다.

handler 종류
///////////////////////////////////////////////////////////////////////

onStart : tween 시작 핸들러 등록
onComplete : tween 큰 핸들러 등록
onUpdate : tween 진행중 핸들러 등록

이 밖에서 여러가지 핸들러 메소드를 지원하고 있다.

transitions 종류
///////////////////////////////////////////////////////////////////////
easeoutquad             // mx.transitions.easing.Regular.easeOut
easeinoutquad          // mx.transitions.easing.Regular.easeInOut
easeoutinquad
           
easeincubic
easeoutcubic
easeinoutcubic
easeoutincubic
           
easeinquart
easeoutquart
easeinoutquart
easeoutinquart
           
easeinquint
easeoutquint
easeinoutquint
easeoutinquint
           
easeinsine
easeoutsine
easeinoutsine
easeoutinsine
           
easeincirc
easeoutcirc
easeinoutcirc
easeoutincirc
           
easeinexpo        // mx.transitions.easing.Strong.easeIn
easeoutexpo        // mx.transitions.easing.Strong.easeOut
easeinoutexpo        // mx.transitions.easing.Strong.easeInOut
easeoutinexpo
           
easeinelastic        // mx.transitions.easing.Elastic.easeIn
easeoutelastic        // mx.transitions.easing.Elastic.easeOut
easeinoutelastic    // mx.transitions.easing.Elastic.easeInOut
easeoutinelastic
           
easeinback        // mx.transitions.easing.Back.easeIn
easeoutback        // mx.transitions.easing.Back.easeOut
easeinoutback        // mx.transitions.easing.Back.easeInOut
easeoutinback
           
easeinbounce        // mx.transitions.easing.Bounce.easeIn
easeoutbounce        // mx.transitions.easing.Bounce.easeOut
easeinoutbounce        // mx.transitions.easing.Bounce.easeInOut
easeoutinbounce


클래스 내부를 살펴보면 아래와 같은 코드를 확인 할 수 있는데 아래와 같이 _frame에 대한 모션도 적용 가능하며(이 클래스를 사용하면 따로 gotoAndPlay 모션 클래스를 제작할 필요도 없어보이지만 간단한 사용을위해서는 따로 제작해서 사용하는 편이 효율적일 듯 싶다.아무래도 프레임간 모션 적용으로 프레임을 많이 필요로 할 듯 싶다) _color 속성으로 사용하면 RGB값으로 DisplayObject의 tint색을 변경하는 모션도 가능하다. 또한 blur값 변경과 사운드 볼륨의 경우도 마찮가지...

DisplayObject의 프로퍼티가 아닌 Tweener 클래스 자체에서 내부적으로 가공하여 사용한 프로퍼티의 경우는 앞에 _를 붙여서 사용하고 있다.

// Normal properties
Tweener.registerSpecialProperty("_frame", frame_get, frame_set);
Tweener.registerSpecialProperty("_sound_volume", _sound_volume_get, _sound_volume_set);
Tweener.registerSpecialProperty("_sound_pan", _sound_pan_get, _sound_pan_set);
Tweener.registerSpecialProperty("_color_ra", _color_property_get, _color_property_set, ["redMultiplier"]);
Tweener.registerSpecialProperty("_color_rb", _color_property_get, _color_property_set, ["redOffset"]);
Tweener.registerSpecialProperty("_color_ga", _color_property_get, _color_property_set, ["greenMultiplier"]);
Tweener.registerSpecialProperty("_color_gb", _color_property_get, _color_property_set, ["greenOffset"]);
Tweener.registerSpecialProperty("_color_ba", _color_property_get, _color_property_set, ["blueMultiplier"]);
Tweener.registerSpecialProperty("_color_bb", _color_property_get, _color_property_set, ["blueOffset"]);
Tweener.registerSpecialProperty("_color_aa", _color_property_get, _color_property_set, ["alphaMultiplier"]);
Tweener.registerSpecialProperty("_color_ab", _color_property_get, _color_property_set, ["alphaOffset"]);
Tweener.registerSpecialProperty("_autoAlpha", _autoAlpha_get, _autoAlpha_set);

// Normal splitter properties
Tweener.registerSpecialPropertySplitter("_color", _color_splitter);
Tweener.registerSpecialPropertySplitter("_colorTransform", _colorTransform_splitter);

// Scale splitter properties
Tweener.registerSpecialPropertySplitter("_scale", _scale_splitter);

// Filter tweening properties - BlurFilter
Tweener.registerSpecialProperty("_blur_blurX", _filter_property_get, _filter_property_set, [BlurFilter, "blurX"]);
Tweener.registerSpecialProperty("_blur_blurY", _filter_property_get, _filter_property_set, [BlurFilter, "blurY"]);
Tweener.registerSpecialProperty("_blur_quality", _filter_property_get, _filter_property_set, [BlurFilter, "quality"]);

// Filter tweening splitter properties
Tweener.registerSpecialPropertySplitter("_filter", _filter_splitter);

// Bezier modifiers
Tweener.registerSpecialPropertyModifier("_bezier", _bezier_modifier, _bezier_get);

그리고 Tweener 클래스에서는 첫 파라미터인 DisplayObject에 DisplayObject를 복수로 가지고 있는 Array를 등록할 경우 Array에 있는 모든 DisplayObject에 해당 트윈을 적용 할 수 있다.

_bezier의 경우는 Papervision3D에서 주로 사용되었는데 이는 카메라의 위치나 각도를 변경할 때 효과적으로 사용되고 있다. 2D 형태에서도 복잡한 동선의 경우에 기존의 트윈 클래스의 모션이 매끄럽지 못하여 그 모션을 적용하기 위한 클래스를 따로 제작해서 사용해야 했지만 제공하고 있는 샘플을 통해서 쉽게 동선을 그리고 좌표를 축출할 수 있다.  그동안의 트윈 클래스에서 아쉬웠던 부분들을 속시원하게 채워주고 있는 듯 싶다.

코드가 업데이트 되고있는 위치
http://code.google.com/p/tweener/
    

설정

트랙백

댓글

물리를 좋아하는 사람들...

Programming/Etc 2007. 8. 4. 11:19
MIT sketching라는 제목으로 youtube에 올라와 있는 동영상이다. 물리 역학을 이용한 스케치 어플리케이션을 설명을 하고 있는데 결과물도 결과물이지만... 순간 머리속으로 이게 가능한가하는 생각마저 든다. 실행 화면과 설명하는 그림이 다른거 아닌가 했었는데 역시나 .... MIT 두뇌 집단 훌륭하다...

관련 사이트
http://icampus.mit.edu/MagicPaper/













    

설정

트랙백

댓글

[AS3] cacheAsBitmap 적용시 고속처리를 위한 팁

Programming/ActionScript 3.0 2007. 7. 31. 07:48

인스턴스를 표시할 때 구형과 같이 Rectangle형태를 갖고 있지 표시오브젝트의 경우 그래픽이 포함되지 않은 부분(투명한 부분)에 색을 넣으면 알파 블랜딩 처리를 생략하여 조금 고속으로 표현할 수 있다. 인스턴스의 투명 부분에 색을 입히려면 각 인스턴스의 프롭퍼티에 있는 opaqueBackground 에16 진수 칼라를 지정하면 된다.

입혀진 배경색에 해당하는 부분은 마우스 이벤트를 받지 않는 영역이다.








import flash.display.Sprite;

var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x0000FF);
circle.graphics.drawCircle(40, 40, 40);

circle.cacheAsBitmap = true;
circle.opaqueBackground = 0xFFFFFF;

circle.addEventListener(MouseEvent.MOUSE_OVER, function(evt:Event){
        trace("over");
});

addChild(circle);
    

설정

트랙백

댓글

[AS3] 이벤트 핸들러 함수에 파라미터 넘겨주기

Programming/ActionScript 3.0 2007. 7. 31. 07:10

로컬 변수를 선언하고 있는 함수 내에서 새롭게 함수를 동적으로 작성하면 로컬 변수를 보관 유지하는 함수를 만들 수 있다. 인수로부터 건네 받는 변수도 로컬 변수이므로 보관 유지가 가능하다.

function createFunc(param1) {
        var param2 = 2;
        var param3 = 3;

        return function() {
                trace(param1, param2, param3);
        }
}
var func = createFunc(1);
func(); // 1 2 3

이러한 형태를 이용하면 이벤트에 건네주는 함수에 파라미터를 넘겨 줄 수 있다.

var count = 0
stage.addEventListener (Event.ENTER_FRAME,enterFrameHandler(count));

function enterFrameHandler (count) {
        return function (event){
                trace("count :"+count);
                count ++;
        }
}

결과 :
count :0
count :1
count :2
count :3
.
.
.

    

설정

트랙백

댓글

[AS3] 클래스 오브젝트 취득

Programming/ActionScript 3.0 2007. 7. 31. 06:06

문자열로부터 클래스 오브젝트를 취득
문자열로부터 클래스를 인스턴스화하려면 getDefinitionByName() 함수를 사용한다. 인수에 클래스명을 문자열로 지정하면 클래스 오브젝트를 반환한다.

 
변수의 내용의 형태를 문자열로 취득
변수의 내용의 형태를 조사하려면 getQualifiedClassName() 함수를 사용한다. 인수에 변수를 대입하면 내용에 어떤 형태의 데이터가 들어가를 문자열로 반환한다.






var mc : MovieClip = new MovieClip(); 
var value_name : String = getQualifiedClassName(mc);
trace(value_name); // flash.display::MovieClip

var class_obj : Object = getDefinitionByName(value_name);
var mc2 : MovieClip = new class_obj();
trace(mc2); // [object MovieClip]


 

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.utils.getDefinitionByName;


var bgColor:uint = 0xFFCC00;
var size:uint = 80;

getDefinitionByNameExample();

function getDefinitionByNameExample() {
        var ClassReference:Class = getDefinitionByName("flash.display.Sprite") as Class;
        var instance:Object = new ClassReference();
        instance.graphics.beginFill(bgColor);
        instance.graphics.drawRect(0, 0, size, size);
        instance.graphics.endFill();
        addChild(DisplayObject(instance));
}
    

설정

트랙백

댓글

ferryhalim.com의 플래시 게임

Programming/Etc 2007. 7. 30. 06:25
사용자 삽입 이미지

은근히 중독성이 강하다... 당신의 순발력은? ^^

http://www.ferryhalim.com/orisinal/g3/bells.htm
    

설정

트랙백

댓글

[CS3] 패널 도킹 방지를 위한 팁

Programming/ActionScript 3.0 2007. 7. 29. 16:53
Flash CS3 뿐만이 아니라 adobe CS3 제품군들은 기본적으로 패널들을 특정 위치에 도킹할 수 있는 기능이 있어 사용자가 원하는 위치에 특정 패널을 도킹하여 사용할 수 있게 되었는데 가끔은 이런 기능이 필요 이상으로 적용되는 경우가 종종 있다.

이런 불필요한 도킹을 방지하기 위해서는 위치를 옮기고 싶은 패널을 드레그 할 때 Ctrl 키를 누른 상태에서 옮기면 어디에도 도킹하지 않고 자신이 원하는 곳에 올려놓을 수 있다.

간단하지만 플래시 툴을 편하게 다루기 위해서 아주 요긴한 사용법인데 이와 같은 정보는 쉽게 찾기 어려운 것 같다…

    

설정

트랙백

댓글

[AS3] hitArea 제거 방법

Programming/ActionScript 3.0 2007. 7. 29. 06:35
Sprite를 생성할 경우 보통 hitArea는 그 안에 있는 표시오브젝트가 된다. 이 때문에 아래 버튼을 놓고 위에 hitArea를 갖고 있는 DisplayObject를 올려놓을 경우에는 아래에 있는 버튼에 이벤트가 발생하지 않는다. 이는 캡처단계와 버블링 단계가 도달할 수 없는 서로 다른 오브젝트이기 때문이다.

이럴 경우 아래에 있는 버튼에 마우스 이벤트를 발생하기 위해서는 다음과 같은 방법으로 해결할 수 있다.

내부 그래픽이 있는 overDisplayObject를 맨 앞(index 최상)에 놓고 아래에 버튼이 있을 때

1. overDisplayObject.mouseEnabled = false;
2. overDisplayObject.hitArea = new Sprite();

2 번과 같이 적용하게 되면 overDisplayObject의 hitArea을 그래픽이 없는 Sprite로 대체 하기 때문에 overDisplayObject의 hitArea가 사라져 아래에 있는 버튼에 마우스 이벤트를 보낼 수 있다. 1번의 경우는 DisplayObjectContainer에 있는 속석을 사용한 방법으로 오브젝트에서 마우스 이벤트를 받지 않도록 설정할 수 있다.



    

설정

트랙백

댓글

플래시의 CPU 문제에 대한 단상

Programming/Etc 2007. 7. 29. 06:13
플래시를 전문적으로 하지 않는 기획자나 다른 개발자의 경우에는 플래시의 CPU문제(버벅거림)에 대해서 막연하게 생각하는 경우가 많다. 플래시의 CPU 사용에 대한 문제는 항상 국내의 화려한 비주얼의 걸림돌이 되곤 한다.

플래시의 CPU 문제는 단적으로 말하면 flashplayer가 한번에 처리해야 하는 계산이 많다는 것을 의미한다. 예를 들면 아래와 같은 경우다.

비주얼 문제
* 복잡한 라운드 처리가 되어 있는 백터 이미지
* 그라데이션이 적용된 백터 이미지
* 알파가 적용된 DisplayObject
* 프레임이 진행하고 있는 MovieClip의 다수 복제
* 큰 사이즈의 이미지(백터 and 비트맵)
* 플래시에서 필터를 적용한 오브젝트의 움직임
...

액션스크립트 문제
* Array의 length
* .연산자
* ["instance name string"] 참조
...

이 밖에도 많은 경우의 수에 의해서 플래시 내에서 처리되는 속도는 차이가 날 수 밖에 없다. 아무리 좋은 디자인으로 표현이 되었더라도 동적인 움직임으로 표현을 해야 하는 플래시 개발자들은 이러한 문제를 항상 안고 작업을 한다.

플래시가 버전업을 하며 날로 발전을 하고 있음에도 그 발전에 대해 충분히 활용하지 못하는 경우가 많은 것 같다. 예를 들면 플래시8 버전부터 추가된 BitmapData, Bitmap 클래스는 ActionScript로 비주얼적인 표현을 할 수 있지만 위에서 이야기한 플래시의 CPU문제를 어느 정도 해결할 수 있는 방법이기도 하다.

플래시 스테이지상에 있는 모든 오브젝트들은 플래시플레이어가 계산해야 하는 영역 안에 있기 때문에 언제든지 CPU의 과부화를 만들어 낼 소지가 있다. 따라서 보여지는 화면 내에 걸쳐있는 모든 오브젝트들의 묘화에 필요한 계산을 줄이기 위해서 BitmapData 클래스를 사용할 수 있다. 

특정 DisplayObject 안에 있는 수많은 오브젝트들을 하나의 DisplayObject로 변환하고 다시 되돌리는 클래스를 만들어 특정 DisplayObject를 하나의 DisplayObject로 변환했다가 그 안에 있는 개별적인 요소의 기능을 사용해야 할 경우에는 원래의 DisplayObject로 변환하여 사용하지 않을때 낭비되는 CPU 문제를 해결할 수 있다.

블로그의 INFINITE의 왼쪽 메뉴의 경우도 위와 같은 방법을 사용한 예다. 마우스를 오버했을 때 메뉴가 나타나고 원래의 오브젝트로 되돌려 버튼을 사용하도록 하고 다시 메뉴 영역에서 마우스를 아웃 했을 때는 하나의 MovieClip으로 대체하여 불필요한 요소를 제거했다.

플래시의 CPU문제와 용량의 문제는 항상 비례하는 것이 아니다. 그리고 파일 용량과 RAM용량 또한  그러하다. 가끔 기획자나 디자이너들이 플래시의 CPU문제 == 파일용량크기 와 결부시키는 경우를 종종 보게 된다.

INFINITE의 메뉴 같은 경우를 보면 원래의 DisplayObject를 되돌려야 하기 때문에 메모리 영역에서 삭제해서는 안 된다. 이 때문에 RAM용량을 줄이는 방법이 아니며 이는 오로지 화면상에 표시되는 오브젝트들로 인해서 flashplayer에 의한 CPU 낭비를 줄이기 위한 방법인 것이다.

요즘은 플래시 개발자와 디자이너가 전문성을 위해서 분업화 되어 있지만 그로 인해서 디자이너들이 플래시에 대한 이해가 부족하여 생기는 문제도 다분히 존재하는 것 같다. 개인적인 생각이지만 국내 웹에이전시에서는 각 분야의 전문성도 중요하지만 작업자 간의 커뮤니케이션에 필요한 기본적인 타 업무에 대한 이해와 교육이 필요한 시기가 아닌가 싶다.

    

설정

트랙백

댓글

[AS3] 코드 길이를 줄여보자

Programming/ActionScript 3.0 2007. 7. 29. 05:10

DisplayObjectContainer의 배치에 사용되는 메소드들은 반환형으로 DisplayObject를 반환한다. 이를 통해서 DisplayObject생성, 배치, 참조의 보관 유지를 한 줄로 해결할 수 있다.

 
아래 소스와 같이 사용하면 특정 DisplayObject를 원하는 인덱스 위치로 이동할 때 코드 라인을 줄일 수 있다.









import flash.display.Sprite;

var spriteAry:Array = new Array();

for
(var i:uint;i<4;i++)
spriteAry.push(addChild(new Sprite()) as Sprite);

var lastChild:Sprite = spriteAry[spriteAry.length-1];

// lastChild를 맨 앞면으로 이동.
addChild(removeChild(lastChild));
trace(getChildIndex(lastChild));

// lastChild를 맨 뒤로 이동.
addChildAt(removeChild(lastChild), 0);
trace(getChildIndex(lastChild));

    

설정

트랙백

댓글

[FlashCS3] Transform Extension...

Programming/ActionScript 3.0 2007. 7. 25. 02:08

munegon라는 일본 ASer가 제공한 EachTransformer Extension...


이 Extension은 복수의 심볼에 대해서 좌표를 고정한 상태에서 각각의 오브젝트를 변형하는 확장 기능이다.


예를 들어서 기존의 Transform의 경우에는 복수의 오브젝트를 선택하여 사이즈를 줄일 경우에는 복수로 선택한 전체 사이즈를 기준으로 줄이기 때문에 각각의 오브젝트의 좌표가 이동하는 문제가 발생한다.


이로 인해서 수 많은 오브젝트들을 일괄적으로 사이즈만 줄일 경우에는 각각의 오브젝트들을 선택하여 줄여야 하는 번거로움이 있으나 이 확장 기능을 사용하면 복수의 오브젝트를 한꺼번에 선택하고 사이즈를 줄이더라도 기존에 위치하고 있던 좌표상에서 각각의 오브젝트의 기준점에서 사이즈를 변경하기 때문에 편리하다.


특히 텍스트 모션에서 각각의 글자에 대해서 일괄적으로 사이즈를 줄일 때 요긴하게 사용할 수 있을 듯 싶다.



* 이 확장기능은 FlashCS3 버전에서만 사용할 수 있다.

    

설정

트랙백

댓글

[AS3] INFINITE의 네비게이션 제작

Programming/ActionScript 3.0 2007. 7. 23. 12:32

AS3를 공부하면서 처음으로 실질적으로 사용 가능한 네비게이션을 블로그의 INFINITE 메뉴에 있는 프로젝트에 적용해 보았다. AS3의 개념이 확실히 마음속에 들어오지 않은 터라 여러가지로 만들면서도 공부하게 되었는데, 초기 유스케이스 및 UML을 그리지 않고 머리 속에서 이렇게 하면 되겠지 싶어서 하다 보니 구조를 잘못 설계하여 중간 지점부터 다시 코드 작성을 했다. 단기적인 작업을 많이 해왔던 터라 초기 구조설계에 소홀히 했던 것은 앞으로 조금씩 문서화 작업을 통해서 기초설계에 좀더 신경을 써야 할 것 같다.

그 동안은 필요해서라기 보다는 AS3의 개념적인 부분과 기능적인 부분을 닥치는 대로 자료를 찾아 공부하다가 실질적으로 필요에 의해서 제작하다 보니 여러 가지로 어려움이 많았던 것 같다.

구조로 보면 AS2에서는 굳이 그렇게 할 필요가 없는 것들이 AS3에서는 그렇게 해야하는 것으로 바뀐 것들도 있고 AS2에서 어떠한 방법을 구현하기 위해서는 우회적인 방법을 동원해야 했던 것이 AS3에서는 간단한 방법으로 되는 경우도 있다.

메뉴는 xml데이터를 불러들여 메뉴를 정렬하게 되는데 깊이는 3으로 세팅되었으나 xml에 따라서 무한 깊이까지 가능할 듯 싶다. AS2가 아닌 막 공부를 시작한 AS3로 제작하다보니 AS2에서 설계하던 머리 속 생각과는 다른 구조로 제작할 수 있고, 또 그렇게 해야 한다는 것을 느끼게 된다.

보기에는 간단해 보이는 네비게이션이지만 클래스 구조에 어느 정도 생각이 필요했다. INFINITE 안에는 앞으로 공부하면서 제작되는 샘플들을 수록할 듯 싶다. 아직 담으려는 컨텐츠에 대해서는 깊이 있게 고민은 해보지 않았다.

Container의 구조는 왼쪽 메뉴를 통해서 버튼을 클릭했을 때 화면 중간에 컨텐츠를 보여주는 형태가 될 것 같다. 예전에 AS2버전으로 작업했던 UI&CL:ab 프로젝트의 구조와 비슷할 듯 싶다.

    

설정

트랙백

댓글

[AS3] XML 클래스의 length() 메소드는 왜...

Programming/ActionScript 3.0 2007. 7. 21. 01:57
xml을 로드하여 네비게이션을 만들던 중에 AS3의 xml에 있는 메소드 length()는 왜 getter, setter 접근자 함수를 사용하지 않았는지 의문이 든다. 보통 Array에서 흔히 사용하는 length는 set, get 접근자 함수를 사용하여 캡슐화 원칙에 준하는 사용하기 편리한 인터페이스를 제공하고 있는데 AS3에서 Dot syntax를 사용하게 된 XML 클래스에서는 유독 일반 메소드 형태로 length() 메소드를 제공하고 있다.

배열과 같은 형태로 사용하지만 배열이 아니라는 것을 암묵적으로 알려주기 위해서 그러했는지 아니면 다른 의도가 있는지 모르겠다. 아무튼 lenfth()를 lenfth로 표기하면서 값이 찍히지 않아서 한참을 물끄러미 바라보다가 이 글을 쓴다.





레퍼런스 내용

length ()  메서드    
AS3 function length():int

XML 객체의 경우 이 메서드는 항상 정수 1을 반환합니다. XMLList 객체에 값이 하나만 포함된 경우 XMLList 클래스의 length() 메서드는 1을 반환합니다.

반환값
    int — 모든 XML 객체에 대해 항상 1을 반환합니다.

    

설정

트랙백

댓글

[AS3] UIScrollBar 클래스 응용

Programming/ActionScript 3.0 2007. 7. 20. 12:43
AS3에서 제공하고 있는 UIScrollBar 컴포넌트의 경우는 스크롤 대상이 되는 scrollTarget이 TextField로 한정하고 있다. ActionScript로 RIA 형태의 프로젝트를 진행하다보면 ScrollBar를 많이 사용하게 되는데 이때 TextField를 대상으로 하는 ScrollBar도 많이 사용하지만 가장 사용빈도가 놓은 것은 특정 무비클립(AS3에서는 DisplayObject)에 Object들을 나열하여 스크롤 형태를 제공하는 경우가 많이 발생한다.

AS3에서 제공하고 있는 component의 경우에는 플래시 폴더에 보면 swc파일이 아닌 as파일로 정리되어 있으니 컴포넌트가 어떻게 구성되어 있는지 시간 날때 확인해 보는 것도 괜찮을 것 같다.

C:\Program Files\Adobe\Adobe Flash CS3\en\Configuration\Component Source\ActionScript 3.0\User Interface\fl\controls

기존에 있던 UIScrollBar 그대로 사용하되 target이 되는 TextField를 DisplayObject 형태로 변형하였기 때문에 flash CS버전에서 제공하는 컴포넌트를 그대로 사용할 수 있게 하였다.


휠을 이용하여 스크롤할 경우에 익스플로러에서 포커스를 가져가버리는 문제가 있는데 패치가 되야 할 것 같다.

컴포넌트가 보이지 않는 문제는 파이어폭스의 문제나 flashplayer의 버전 문제가 아니라 엉뚱하게도 티스토리에서 기본적으로 플래시를 임베드 시킬때 생성하는 코드가 예전 방식으로 처리되고 있는 문제였다. 티스토리에서 자동 임베드 코드 생성시에 수정하여야할 부분이다...





    

설정

트랙백

댓글

[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++;
                }
        }
}
}
    

설정

트랙백

댓글

[AS3] 스코프

Programming/ActionScript 3.0 2007. 7. 9. 22:25

기본적으로 ActionScript의 컴파일러는 현재 스코프 내에 사용하고자 하는 변수를 찾을 수 없을 때에는 상위 스코프에서 찾게 된다. 아래와 같은 코드를 AS2에서 실행해보면 다음과 같이 출력되는 것을 알 수 있다.












// AS2 코드 결과
var _this:String = "global";
trace(_this);  // 출력 :  global

function subScopeFunction() {
        trace(_this);  // 출력 : global
        var _this:String = "local";
        trace(_this); // 출력 : local
}
subScopeFunction();
trace(_this);  // 출력 : global

하지만 AS3에서는 사정이 좀 다르다.

// AS3 코드 결과
var _this:String = "global";
trace(_this);  // 출력 :  global

function subScopeFunction() {
        trace(_this);  // 출력 : null
        var _this:String = "local";
        trace(_this); // 출력 : local
}
subScopeFunction();
trace(_this);  // 출력 : global

위 코드에서 보이는 것과 같이 AS3에서는 전역 변수와 지역 변수명이 같을 경우에는 지역변수는 지역 스코프 내에서만 유효한 값을 갖게 된다. 이는 ActionScript 3.0의 컴파일러가 컴파일을 시도할 때 스코프 내의 변수들을 먼저 불러오기 때문이다.

subScopeFunction() 스코프 내의 첫 번째 행에서 global영역에서 지정한 변수명과 동일한 변수명을 사용하여 출력을 하였으나 subScopeFunction() 스코프 내에 global 변수명과 동일한 지역변수를 var를 통해서 선언하였기 때문에 최초 subScopeFunction() 함수를 컴파일 할 때 라인 위치와는 상관없이 지역변수 _this의 메모리 영역을 먼저 잡아 놓게 된다. 이 때문에 subScopeFunction() 첫 행의 결과는 null을 출력한다.

AS3에서는 형태 지정이 없는 변수만 디폴트 값이 undefined이고 String이나 Object의 디폴트 값은 null, Boolean 는 false, uint는 0, Number는 NaN 값이 디폴트 값이다.


 

    

설정

트랙백

댓글

[AS3] 변수 형태에 관한 이야기

Programming/ActionScript 3.0 2007. 7. 9. 19:41

AS3의 형태 시스템의 특징은 다음과 같다. 아래의 코드에 대해서 생각해 보면 오브젝트형의 변수 str에 수치 0을 대입하여 공문자열과 비교하고 있다.

var str:* = 0;
if ("" == str) {
        trace("str은 공문자열");
}


위의 If 문은 공문자를 검출하기 위한 것이지만 실제로 이 코드를 실행하면 ”str은 공문자열”이라고 출력된다.

이 결과는 AS3가 약한 형태 성질을 가지고 있기 때문에 일어난다. ActionScript에서는 '+' 등의 오퍼레이터에 의해서 복수의 데이터형이 혼합되면 처리 전에 암묵적으로 형태 변환을 한다. 예를 들면 trace("count:" + 0)와 같이 문자열과 수치를 더하면 0의 값이 문자열로 변환되어 count:0이라는 결과를 얻게 된다. trace 예와 같은 암묵적 형태 변환은 ActionScript 3.0 이전 버전에서도 있었던 것이지만 위에서 처음 예로 든 코드의 경우는 ActionScript 2.0에서는 공문자열과 str은 같지 않은 것으로 나온다.

암묵적 형태 변환은 위의 trace() 예와 같이 비교적 편리한 기능으로서 사용되지만 한편으로는 예기치 못한 결과가 나올 수 있다. 예를 들면 위에 언급한 코드의 경우 실제로 컴파일러가 어떠한 변환을 통해 true 라는 결과가 나오는지 개발자가 직감적으로는 이해 하기가 어려운 점이 있다.

    

설정

트랙백

댓글

[AS3] CustomMath 클래스 테스트 - Angle

Programming/ActionScript 3.0 2007. 7. 9. 06:25
Sprite의 angle 테스트를 해보았다. 라이브러리에 있는 Sprite에 클래스를 등록할 때 동립된 클래스 파일로 존재하지 않고 main 클래스 소스파일 내에 internal class로 정의할 경우에는 라이브러리에 있는 Sprite을 참조하지 못한다. 아무래도 AS3의 namespace 때문이지 않을까 싶다.

전체적으로 확실히 AS3에서 속도가 향상된 듯 싶다. 7*15(105개)의 Sprite을 main 클래스의 Event.ENTER_FRAME  이벤트를 적용하여 움직임을 주었는데 CPU에 그렇게 큰 부담이 없는 듯 싶다.

MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_UP 이벤트를 적용해 봤는데 MouseDown일 때 움직임이 재미있다. 초등학교 운동회때 엄마를 졸라서 샀던 색깔종이(?!) 같다...



[Flash] http://jasu.tistory.com/attachment/cfile29.uf@25428C395880211C108D39.swf





    

설정

트랙백

댓글

[AS3] custom 이벤트의 기본적인 dispatchEvent 사용

Programming/ActionScript 3.0 2007. 7. 7. 23:05
Event 클래스를 확장하면 자신의 커스텀 이벤트 클래스를 정의할 수 있다. 예를 들면 아래와 같은 경우다.
















package{
import flash.events.Event;
public class CustomEvent extends Event{
public function CustomEvent(){
super("customEvent");
}
public override function clone():Event{
return new CustomEvent();
}
}
}

(Event의 서브 클래스로 상속할 때는 clone() 메소드를 오버라이드할 필요가 있다.)

EventDispatcher 클래스의 dispatchEvent() 메소드를 사용하면 자동으로 이벤트의 dispatch가 생긴다. 예를 들면 Sprite는 EventDispatcher의 서브 클래스이기 때문에 다음과 같이 CustomEvent을 dispatch 할 수 있다.
package{
import flash.display.Sprite;
public class CustomEventSprite extends Sprite{
public function dispatchCustomEvent():void{
dispatchEvent(new CustomEvent());
}
}
}

그리고는 이벤트 처리를 호출하기 위해 이벤트 리스너를 등록하면 된다.
package{
import flash.display.Sprite;
public class EventTest extends Sprite{
public function EventTest(){
var ceSprite:CustomEventSprite = new CustomEventSprite();
ceSprite.addEventListener("customEvent", onCustomEvent);
ceSprite.dispatchCustomEvent();
}
private function onCustomEvent(evt:CustomEvent):void{
trace("dispatch CustomEvent");
}
}
}

하지만 AS3에서는 다중 상속이 허용되지 않기 때문에 모든 클래스를 EventDispatcher의 서브 클래스로 만들 수 있는 것이 아니다. 상속하고 있는 클래스의 경우에는 IEventDispatcher 인터페이스를 사용한다. 클래스 내부에서 EventDispatcher의 인스턴스를 가져와서 처리를 Delegate하는 방법이다.

    

설정

트랙백

댓글