[UPL002] RTMFP를 이용한 커뮤니케이션

Project/UPL 2009. 6. 23. 22:31


UPL의 두 번째 작업으로 FlashPlayer10 버전부터 추가된 Real-Time Media Flow Protocol(RTMFP) 통신을 이용하여 채팅 기능을 구현하였다. RTMFP가 기존의 Real-Time Messaging Protocol(RTMP)와 다른 점을 이야기 한다면 크게 두 가지로 볼 수 있다. 하나는 RTMP의 경우 데이터를 client가 공유하기 위해 Flash Media Server가 꼭 필요했던 반면 RTMFP의 경우는 FMS 필요 없이 FlashPlayer 간 직접 통신이 가능하다.(플래시플레이어 간 통신을 위해 호스트 통합 서비스인 Adobe Stratus를 통해서 부여된 id를 이용해서 서로 통신을 한다.) 그리고 두 번째로는 RTMP의 경우는 TCP 프로토콜을 사용하여 데이터 손실 없는 안정적인 통신을 할 수 있는 반면 속도에는 한계는 있었다. 그러나 RTMFP는 UDP를 사용함으로써 데이터 손실이 발생할 가능성이 있지만 속도 면에서는 빠르다.


무엇보다도 미디어 서버를 사용하지 않고 직접 플래시플레이어 사이에 통신을 할 수 있고 속도 면에서도 빠르다는 강력함이 무척 매력적이다.



UPL002에서는 RTMFP를 이용하여 해당 swf을 띄워놓으면 자동으로 채팅의 참여자가 되며 자신의 마우스 움직임과 타이핑 내용이 실시간으로 해당 swf를 띄워놓은 동시 접속자의 화면에 표현된다. swf를 여러 개 띄워놓고 테스트할 수도 있다.

개발 구조는 하나의 swf안에서 서버와 클라이언트 역할을 같이 하게 되며 접속을 하면 기존에 접속된 사용자들의 id를 모두 연결하고 자신의 id도 등록한다. 이때 특정 사용자가 브라우저를 닫거나 swf 실행을 종료할 경우 해당 아이디를 삭제하는데 최종 사용자의 경우에는 자신을 닫는지 여부를 확인할 방법이 없다. 따라서 모든 사용자가 종료하더라도 하나의 아이디는 잔존하며 이후 최초 사용자가 접속을 할 때 기존의 id의 연결을 실패할 때 해당 아이디를 삭제하는 형태로 제작 되었다.

RTMFP의 경우 UDP를 사용하므로 방화벽 차단이 되어 있는 네트워크 상에서는 외부에서 접속한 사용자와 연결이 되지 않을 수 있다.


관련 자료 참고 링크
http://kb2.adobe.com/cps/405/kb405549.html
http://www.adobe.com/devnet/flashplayer/articles/rtmfp_stratus_app.html
http://download.macromedia.com/pub/labs/flashplayer10/flashplayer10_rtmfp_faq_070208.pdf
http://www.adoberia.co.kr/iwt/board/board.php?tn=pds_tech&page=2&id=244&mode=view
http://wooyaggo.tistory.com/tag/rtmfp

    

설정

트랙백

댓글

[UPL001] 카운트 모션

Project/UPL 2009. 6. 17. 01:02



UPL의 첫 번째 작업으로 예전에 만들었던 카운팅 모션을 올려봤다. 숫자 카운팅에는 여러 가지 모션을 적용할 수 있을 듯싶은데 개인적으로는 그냥 틱~ 하고 나오는 게 좋긴 하다. 아래 결과물은 화면에서 마우스 클릭을 하면 Math.random()으로 가져온 값을 가지고 모션을 적용한다.

배경으로 나타나는 숫자 모션의 경우는 텍스트의 글자 단위로 잘라서 모션을 적용한 형태이고, 날라오는 듯한 모션의 경우에는 FlashPlayer10버전부터 추가된 3D 속성을 이용하여 글자 단위로 모션을 적용, 전체 묶음으로 중앙 위치 조절이 적용되었다.

UPL에서 default로 적용되는 왼쪽 상단의 기능은 아래와 같다.
표시되는 숫자는 FPS 값과 메모리 용량을 확인할 수 있도록 되어 있다. 메모리용량의 경우는 정확한 용량이라기 보다는 해당 결과물이 진행하는 과정에서 메모리의 증감을 표시하기 위함이다.

위, 아래 화살표 :  FPS를 증가, 또는 감소시키기 위해 사용할 수 있음
P : UPL 진행하는 블로그 카테고리 경로 링크
H : object, embed HTML코드 복사(clipboard copy)
U : swf 경로 복사(clipboard copy)
F, N : FullscreenMode 적용(필요 없을 경우 비활성화 처리됨)




    

설정

트랙백

댓글

정보의 가시화 그리고 플래시 개발자의 역할

Programming/ActionScript 3.0 2009. 5. 31. 08:12


정보의 가시화.
컴퓨터가 발달하지 않았던 시대에는 그래프의 탄생이 정보의 가시화에 혁명처럼 다가왔던 시대가 있었다. 그로부터 몇 백 년이 지난 지금은 어떠할까, 컴퓨터가 발달하고 인터넷이 빠르게 발전하면서 대량의 정보, 그 자체를 분석하고 처리하는 능력은 그때와는 비교도 할 수 없을 정도로 발전했지만 아직까지도 정보를 효과적이고 완벽하게 가시화 할 수 있는 방법은 존재하지 않는 것 같다. 가면 갈수록 컴퓨터의 정보처리 능력과 더불어 인문학이 주요 이슈로 떠오르고 있는 이유도 여기에 있는 것이 아닐까.

데이터는 데이터 자체로 의미를 지닐 수는 없다. 데이터는 인간이 이해할 수 있는 것으로부터 그 가치를 가지게 된다, 그렇다면 데이터를 인간이 이해하기 편하게 표현하려면 어떻게 해야 할까.

정보 가시화에 필요한 기본적인 시각 요소들은 사이즈, 색채, 관련성, 좌표 등이 있다. 흑백 인쇄와 같이 제한적인 환경이 아닌 인터넷에서는 이러한 기본적인 시각 요소들을 다양하게 사용할 수 있다. 더욱이 모든 이용자의 접근성을 위한 대체 컨텐츠를 제공 해야 하는 부담을 줄이기 위해서는 앞에서 열거한 모든 요소들을 적절히 활용하는 것이 필요하다.



또한 인터넷 매체로 넘어오면서 정보를 단순히 가시화해서 보여주는 것에 머무르지 않고 사용자와 시스템간에 상호 의사소통을 함으로써 인간이 데이터를 이해하는데 보다 많은 도움을 주고 있다. 그러한 관점에서 본다면 플래시는 이러한 시대를 제대로 만났다고 할 수 있다. 플래시는 발전을 거듭하면서 데이터 분석과 처리를 효율적으로 수행하고 있으며 플래시만의 특화된 디자인적인 요소를 충분히 활용함으로써 다양한 시각화를 표현 할 수 있게 되었다. 물론 좋은 펜을 가지고 있다고 하여 글을 잘 쓰는 것은 아니겠지만 정보를 효과적으로 가시화할 수 있는 발판을 마련했다는 점에서 의미가 있다고 하겠다.

플래시는 앞으로도 많은 발전을 거듭하겠지만 그 동안은 도구 자체로써 발전을 했다면 이제는 그 도구를 최대한 활용하여 효과적이고 최적화된 콘텐츠를 생산하는 인력을 키우는데 노력 해야 할 것이다. 앞에서 언급한 것처럼 정보는 정보 자체로 그 의미를 지닐 수 없듯이 말이다.

플래시 개발자의 역할.
위에서 말한 효과적인 컨텐츠를 생산하기 위해서는 플래시 개발자에게는 다양한 역량을 요구하게 된다. 플래시 기술을 보유한 엔지니어를 넘어 정보를 어떻게 가공하여 가시화 할 것인가에 대한 근본적인 문제를 효과적으로 구상할 수 있는 기획력, 그리고 그러한 표현을 현실화 할 수 있는 디자인 능력이 요구된다. 물론 요즘은 전문적인 역량을 요구하게 되면서 각 분야의 기술력이 높아졌지만 그러한 업무 분담 시스템으로 인해 결과적으로는 컨텐츠의 퀄리티가 매끄럽지 않은 경우가 많이 발생한다.

이런 문제점을 보완하기 위해서는 플래시 개발자뿐만 아니라 모든 작업자는 수동적인 작업자가 되어서는 안 된다고 생각한다. 각 분야의 전문가들의 의견을 최대한 수렴하고 존중하되, 기획, 디자인, 플래시 기술을 떠나서 최종 사용자의 입장에서 문제점을 지적하고 더 나은 결과물을 얻기 위해 노력해야 한다. 따라서 끊임없이 각 분야의 전문가들과 커뮤니케이션을 해야 하는 것이다.

사실 본인 또한 다른 작업자들을 설득하는 것에 많은 부담을 갖는 것이 사실이다. 하지만 주관적인 자신의 생각이 아닌, 사용자의 입장에서 충분히 생각하고 제시하는 객관적인 설득은 다른 작업자들도 충분히 공감을 할 수 있을 것이라고 믿는다.

플래시라는 기술은 업무의 특정이 완벽하게 구분되는 분야가 아니다. 구조적인 부분에서는 기획, 비주얼 부분에서는 디자인, 기술적인 부분에서는 프로그래밍을 항상 고민해야 하는 특성이 있다. 따라서 플래시 개발자의 역할은 모든 작업자들에게 보다 많은 커뮤니케이션을 유도하는 윤활유 역할을 수행할 필요가 있다.

각 분야의 전문가들은 자신이 바라보는 관점에서 욕심을 내기 마련이다. 하지만 그 욕심이 해당 프로젝트가 나아갈 방향에 부합하지 않거나, 사용자의 사용 패턴을 충분히 고려하지 않은 욕심이라면 다시 생각해볼 필요가 있다. 보통 일선에서는 이러한 역할을 기획에서 하는 경우가 많지만 기획자의 역량에도 한계가 있기 때문에 무조건 기획자에게 책임을 전가해서는 안 된다고 생각 한다.

사실 본인도 그러한 역할을 조금이나마 수행하기 위해서 노력은 하고 있지만 커뮤니케이션 스킬이 많이 부족하다 보니 어려움이 많은 것이 사실이다. 하지만 이러한 노력조차 하지 않는다면 해당 프로젝트는 철학이 없는 이벤트로 끝날 가능성이 크다고 생각한다.

따라서 플래시 개발자는 모든 작업자의 편의를 위해 개발하기 보다는 최종 결과물을 받아들이는 사용자 입장을 항상 고민하고, 그것이 완벽하게 옳다고 스스로 판단되지 않을 경우에는 프로젝트의 완성도를 위한 커뮤니케이션을 회피해서는 안될 것이다.

물론 현실적으로 어려움이 있는 것은 사실이다. 프로젝트의 일정상 어려움도 있을 것이고 커뮤니케이션 과정에서 다른 작업자의 영역을 침범한다고 좋지 않게 바라볼 수도 있다. 하지만 자신이 옳다고 판단하는 것에 대해 다양한 의견을 들어보는 것만으로도 프로젝트 뿐만이 아니라 모든 작업자들에게 도움이 될 것이라고 생각한다.


 

    

설정

트랙백

댓글

실무자를 위한 액션스크립트 3.0 스킬업 과정

Project/Programming 2009. 4. 9. 01:33

이번에 아는 형님의 도움으로 액션스크립트 3.0 강좌를 개설하게 되었다.  컴퓨터 학원은 고등학교 시절에 정보처리기능사 자격증 반을 다녔던 것이 전부인 나에게 가당치도 않은 일이지만 컴퓨터 학원은 주입식이어서는 안 된다는 내 소신을 시험해 볼 좋은 기회일 듯싶어서 욕심을 내보았다. 물론 강좌를 신청한 분들에게 기대한 만큼의 무엇을 전달하지 못할 수도 있겠으나 내가 할 수 있는 부분에 있어서는 최선을 다 해볼 요량이다.

강좌는 초중급으로 프로그래밍 언어에 대한 기본지식이 있거나 액션스크립트 2.0에서 3.0으로 넘어가는 분들을 대상으로 하였다. 따라서 기본적인 프로그래밍 언어에 대한 설명은 따로 시간을 할애하지 않을 생각이다.

사실 6강 18시간이라는 시간은 커리큘럼의 모든 부분을 자신의 것으로 만들기에는 턱없이 부족한 시간이다. 하지만 독학으로 공부하며 방향을 잡지 못하거나 본인이 공부하고 있는 것이 맞는 것인지 의심되는 분들에게는 도움이 될 것이라 믿는다.

본 강좌에서의 중심은 객체지향언어인 액션스크립트로 작업을 함에도 불구하고 oop의 장점을 충분히 활용하지 못하는 기존의 습관을 바꿔보는 것이다. 강좌가 끝날 때 이 부분에 대해서 느낌을 찾으시는 분들은 좋은 경험이 될 것이라 생각한다. 본 강좌에서 디자인패턴을 메인 메뉴로 올려놓은 것은 디자인패턴을 공부하기 위한 것이 아니라 많은 프로그래머들에게 입증된 디자인패턴의 구조를 토대로 본인의 코딩, 구조화 습관에서 생각의 전환을 하기 위해 디자인패턴을 다룰 것이다.

아무쪼록 강좌를 신청하신 분들, 그리고 본인 또한 좋은 경험이 되길.... ^^

http://www.dikr.co.kr/courses/ac1_003.asp


 

    

설정

트랙백

댓글

[CS4] Vector의 이해

FlashCS4(FlashPlayer10) 버전에서 지원하고 있는 Vector 객체에 대해서 정확히 무엇이며 어떤 역할을 하는지에 관한 자료를 정리하는 차원에서 이야기 해 볼까 한다.

일단 아래는 FlashPlayer10 레퍼런스 문서에 있는 Vector에 관한 기본 내용이다.











----------------------------------------------------------------
Vector 클래스를 사용하면 벡터에 액세스하고 이를 조작할 수 있습니다. 벡터는 요소의 데이터 유형이 모두 같은 배열입니다. 요소의 데이터 유형을 Vector의 기본 유형이라고 합니다. 기본 유형은 내장 클래스 및 사용자 정의 클래스를 포함한 모든 클래스일 수 있습니다. 기본 유형은 Vector 변수를 선언할 때 및 클래스 생성자를 호출하여 인스턴스를 만들 때 지정됩니다.

Array와 마찬가지로 배열 액세스([]) 연산자를 사용하여 Vector 요소의 값을 설정하거나 검색할 수 있습니다. 또한 몇 가지 Vector 메서드를 통해 요소 값을 설정 및 검색하는 메커니즘이 제공됩니다. 이러한 메서드로는 push(), pop(), shift(), unshift() 등이 있습니다. Vector 객체의 속성 및 메서드는 Array의 속성 및 메서드와 비슷하며 대부분의 경우 동일합니다. 사용하는 Array의 모든 요소가 같은 데이터 유형인 경우 항상 Vector 인스턴스를 사용하는 것이 좋습니다.

Vector의 기본 유형은 접미사 유형 매개 변수 구문을 사용하여 지정됩니다. 유형 매개 변수 구문은 다음 예제와 같이 마침표(.), 여는 각괄호(<), 클래스 이름, 닫는 각괄호(>) 순서로 구성됩니다.

var v:Vector.<String>;
 v = new Vector.<String>();

예제의 첫 번째 행에서는 변수 v를 Vector.<String> 인스턴스로 선언합니다. 즉, 이 변수는 String 인스턴스만 포함할 수 있으며 String 인스턴스만 검색할 수 있는 Vector(배열)를 나타냅니다. 두 번째 행에서는 동일한 Vector 유형(요소가 모두 String 객체인 Vector)의 인스턴스를 생성하여 v에 할당합니다.

Vector.<T> 데이터 유형으로 선언된 변수에는 같은 기본 유형 T로 생성된 Vector 인스턴스만 저장할 수 있습니다. 예를 들어 new Vector.<String>()을 호출하여 생성된 Vector를 Vector.<int> 데이터 유형으로 선언된 변수에 할당할 수는 없습니다. 기본 유형은 정확히 일치해야 합니다. 예를 들어 다음 코드에서는 객체의 기본 유형이 변수의 선언된 기본 유형과 다르므로 코드가 컴파일되지 않습니다. Sprite가 DisplayObject의 하위 클래스이지만 결과는 마찬가지입니다.

// This code doesn't compile even though Sprite is a DisplayObject subclass
 var v:Vector.<DisplayObject> = new Vector.<Sprite>();

기본 유형이 T인 Vector를 T의 수퍼 클래스의 Vector로 변환하려면 Vector() 전역 함수를 사용합니다.

Vector 클래스에는 데이터 유형 제한뿐만 아니라 Array 클래스의 경우와 다른 몇 가지 제한이 더 있습니다.

    * Vector는 밀착형 배열입니다. 1에서 6 사이의 위치에 값이 없어도 인덱스 0과 7에 값이 있을 수 있는 Array와 달리 Vector의 경우에는 모든 인덱스에 값 또는 null이 있어야 합니다.
    * Vector는 고정 길이일 수도 있습니다. 즉, 포함된 요소 수를 변경할 수 없을 수 있습니다.
    * Vector의 요소에 액세스할 때는 경계가 검사됩니다. 마지막 요소(length - 1)보다 큰 인덱스에서는 값을 읽을 수 없습니다. 현재 마지막 인덱스를 벗어난 인덱스에는 값을 설정할 수 없습니다. 즉, 기존 인덱스나 [length] 인덱스에만 값을 설정할 수 있습니다.

이러한 제한 사항으로 인해 Vector에는 모든 요소가 단일 클래스의 인스턴스인 Array 인스턴스보다 두 가지 우수한 점이 있습니다.

    * 성능: Vector 인스턴스를 사용하면 Array를 사용할 때보다 훨씬 빠르게 배열 요소에 액세스하고 반복할 수 있습니다.
    * 유형 안전: 엄격 모드를 사용하면 Vector에 잘못된 데이터 유형의 값을 할당하거나 Vector에서 값을 읽을 때 잘못된 데이터 유형을 사용하는 등의 데이터 유형 오류를 컴파일러에서 식별할 수 있습니다. 그러나 push() 메서드나 unshift() 메서드를 사용하여 Vector에 값을 추가할 때는 인수의 데이터 유형이 컴파일 타임이 아닌 런타임에 검사됩니다.
----------------------------------------------------------------

Array와 Vector
Vector는 ECMAScript4에서 도입된 기능으로 이번 FlashPlayer10에서도 적용이 되었다. 모든 요소가 동일한 객체를 포함해야 한다는 제약이 따르지만 위 레퍼런스의 내용과 같이 Array 배경보다 몇 가지 장점을 가지고 있다. 속도와 엄격한 유형검사가 그것이다.

Vector는 Array와 같이 Object를 확장하며 dynamic 클래스 이지만 Array와 같이 정의되지 않은 프로퍼티에 값을 할당할 수는 없다. 예를 들어

var arrStr:Array = new Array();
arrStr.name = "jasu";
trace(arrStr.name);

이런 형태로 실행을 하면 arrStr에 있는 name 속성을 런타임에서 생성하여 값을 참조할 수 있다. 하지만 Vector의 경우 컴파일에서 에러를 throw 한다.

var vecStr:Vector.<String> = new Vector.<String>();
vecStr.name = "jasu"; // error 1119: Access of possibly undefined property name through a reference with static type __AS3__.vec:Vector.<String>.
trace(vecStr.name);


Vector의 연속된 배열과 고정 길이
var arrStr:Array = new Array();
arrStr[0] = "100";
arrStr[1] = "200";
trace(arrStr[1]); // 정상적으로 컴파일 됨.

var vecStr:Vector.<String> = new Vector.<String>(2, true);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300"; // vecStr의 고정된 길이(2) 값을 벗어난 인덱스 참조로 에러 발생
trace(vecStr[2]);

var vecStr:Vector.<String> = new Vector.<String>(2, false);
vecStr [0] = "100";
vecStr [1] = "200";
vecStr [2] = "300";
trace(vecStr[2]); // 정상적으로 컴파일 됨.

Vector의 constructor 첫번째(length), 두번째(fixed) default 값은 0과 false이다.


Vector에서 push 메소드의 암묵적 형 변환
var vetStr:Vector.<int> = new Vector.<int>();
vetStr[0] = true; // TypeError 발생
trace(vetStr[0]);

var vetStr:Vector.<int> = new Vector.<int>();
vetStr.push(true);
trace(vetStr[0]); // output 1 (push 메소드 실행시 암묵적으로 할당된 값의 형을 강제 변환함.

Vector의 push 시에도 Type 체크를 하여 TypeError를 throw 해주는 것이 좋을 것 같으나 현재 Vector의 경우 push로 값을 넣을 경우 암묵적으로 강제 형 변환을 하고 있다.

정리
Vector의 경우 기존에 사용하는 문법과 약간은 다른 형태를 취하고 있기 때문에 처음 접할 때는 생소하다. 하지만 기존에 사용하던 방식 “:객체명”에서 :객체명.<단일형> 으로 추가하되, 그 Vector에는 포함하고자 하는 형태만 사용한다는 것을 머리 속에서 명확하게 인지한다면 기존에 Array를 사용하여 생기던 속도 문제와 에러를 예방할 수 있다는 차원에서 좀더 명확하고 빠른 알고리즘을 작성할 수 있지 않을까 싶다.



    

설정

트랙백

댓글

Box2D로 표현할 수 있는 것

Project/Programming 2009. 1. 3. 19:21
Box2D 물리 엔진을 이용하여 표현할 수 있는 방법 모색과 구조 공부를 위해서 사용해 보았었다. Box2D는 ActionScript 기반으로 제작된 것이 아니라 타 언어로 개발되어 다양한 프로그래밍 언어로 변화하였기 때문에 ActionScript 구조나 효율적인 면에서 다소 ActionScript와 맞지 않는 형태를 취하고 있다.

예를 들면 Box2D에서는 기본적인 수치 계산에 사용하는 값은  실 세계의 관점에서 미터 단위로 값을 사용하고 있다. 또한 무게도 kg단위로 표현이 되는데, 이로 인해서 표시객체로서 화면에 표현할 때는 다시 미터 단위를 pixel 단위로 변환해야 하는 수치계산부가 포함된다. 이로 인해서 불필요한 연산을 포함하게 되는 것이다.

그렇다고 하더라도 기본적인 프로그래밍 언어적인 측면에서 짜임새 있는 구조를 취하고 있다.
 
샘플로 제작한 결과물은 Box2D에서 사용할 수 있는 오브젝트 생성 및 오브젝트 끼리 서로 연관성을 유지할 수 있도록 연결해 주는 Joint을 통해서 서로 연결 관계를 만들어 낼 수 있다.

샘플 이미지



샘플 플래시




일단 화면에서 마우스를 드래그 하여 오브젝트를 생성 할 수 있다. 왼쪽에 나타나 있는 메뉴 버튼에 따라서 생성할 모양을 선택할 수 있다. 상단의 3개의 버튼(u,j,m)은 u는 unit 생성 메뉴를 나타내고 j는 joint 메뉴, 그리고 m은 생성한 오브젝트를 이동(move) 할 수 있는 기능 메뉴이다.

일단 생성할 수 있는 기본적인 오브젝트 모양은 삼각부터 8각까지이고 마지막 f는 자유로운 선 연결을 통해서 자율각도의 도형을 만들 수 있다. 자율도형의 경우에도 8개의 각만을 유지하는데 이는 Box2D(일반 다른 물리엔진에서도 대체적으로 그러하다)에서 8각 이상의 오브젝트에서는 물리 연산에 있어서 오류가 발생한다. 이는 각이 많은 경우 각에 따른 관성과 마찰력을 만들어 내는 연산에 있어서 한계점이라고 이해하면 될 것 같다.

각을 많이 만들 수 없기 때문에 단일 오브젝트로 자유로운 형태의 모양을 만들고 그것에 이미지를 맵핑 할 수 없는 것은 여러 개의 오브젝트를 묶어서 표현 할 수 있을 것이다.

또한 Box2D에서 자율 각도의 도형을 만들 때 지켜야 할 규칙에 대한 이야기를 하고 있는데 이는 이전 각도와 다음 각도의 연장선에서 안쪽에 새로운 각을 생성하면 엔진에 오류가 발생한다. 이는 물리엔진에서 표면의 각도에 따라 충돌 계산을 처리하는데 표면 안팎을 구분할 수 없는 계산의 사각이 발생하기 때문이다. 따라서 샘플에서는 자율도형을 만들 때에는 가이드 라인을 제공하고 있으며 그 가이드 색에 포인트를 생성할 수 없도록 처리해 놓았다. 그리고 Box2D에서 약간의 오류가 있는데 자율도형을 만들 때 시계방향으로 만들면 대체적으로 문제가 없지만 시계 반대방향으로 각도를 만들면 문제가 발생한다. 따라서 샘플에서 만들어진 자율도형의 경우에는 시계 반대방향으로  만들어진 각도의 포인터 배열 순서를 역으로 reverse하여 처리하였다.

오른쪽 상단의 메뉴 j에서는 Box2D에서 제공하는 joint 기능들을 포함하고 있다. 몇몇 기능은 구현되지 않거나 구현 과정에 있는 것들도 있다.

Joint는 오브젝트와 오브젝트를 잇는 역할을 한다. Box2D에서는 6종류의 조인트를 지원하고 있다.

b2DistanceJointDef
이는 오브젝트의 거리를 일정하게 유지하는 조인트이다.

B2RevoluteJointDef
이는 오브젝트와 오브젝트간의 연결을 통해 회전시키는 역할을 한다. 사람의 팔과 다리와 같은 관절 역할을 한다고 보면 될 것 같다.

b2PrismaticJointDef
이는 피스톤 같은 움직임을 표현한다. 오브젝트간의 직선으로 연결된 길을 통해서 직선 운동을 한다.

b2PulleyJointDef
도르래 같은 기능을 하는 조인트이다.

b2GearJointDef
기어 조인트이다. 기어에 의해서 연결되고 있는 관계를 나타내는 조인트이다.

b2MouseJointDef
마우스 조인트는 오브젝트를 마우스 인터랙션을 통해서 움직이기 위한 조인트이다. 샘플에서 오브젝트를 마우스로 클릭 후 드래그(메뉴중 M버튼이 눌려진 상태에서만)를 통해서 이동 가능한 것도 마우스 조인트를 사용하고 있기 때문이다.

그리고 샘플에서 마우스 오른쪽 버튼을 통해서 context 메뉴를 제공하고 있는데 오브젝트를 삭제하는 기능과 오브젝트의 정보를 확인하고 수정 할 수 있는 info 메뉴가 그것이다.

Info와 Remove 기능은 생성한 오브젝트 위에서만 사용 가능하다. 선택되는 오브젝트가 없을 때에는 기능이 처리되지 않는다. Remove는 해당 오보젝트를 바로 삭제해 준다. Info는 해당 오브젝트의 정보 값들을 오른쪽에 표시해 주고 있는데 해당 값들을 변경함으로써 오브젝트의 물리 값들을 변경할 수 있다. 예를 들면 마찰력, 관성, 탄력등…

또한 색 변경과 static으로 물리역학에 영향을 받지 않는(멈춰있는 장애물) 오브젝트로 만들 수도 있다.

왼쪽 하단에는 물리역학이 적용되고 있는 영역의 중력 값을 변경 할 수 있다. 실 세계에서의 중력은 위에서 아래(Y축)로만 적용되지만 여기서는 X축으로도 적용 가능하여 바람에 날리는 형태의 환경도 만들어 낼 수 있다.

그리고 마지막으로 화면에서 shift 키를 누른 상태에서 마우스로 원을 그리면 전체적인 메뉴를 볼 수 있는데 기능 중에는 구현되지 않은 것들도 있다. Fullscreen으로 적용할 경우 키보드를 사용할 수 없으니 normal 화면에서 사용할 수 있다.

몇 개월 전에 만들었던 결과물이지만 중간에 다른 일들로 인하여 잠시 손을 놓고 있었다. 사용하다 보면 약간 버그도 발생하고 있는데 나중에 시간이 허락되면 Box2D를 사용하는 방법에 대해서 포스팅을 하면서 수정하도록 하겠다. 시간이 허락이 될지는 잘 모르겠지만 말이다...;;

블로그를 통해서 새해 인사를 하지 못했는데 아무쪼록 제 블로그에 방문하는 모든 분들 2009년에는 명박스럽지 않은 즐거운 해가 되었으면 좋겠다. 모든 분들 새해 복 많이 받으세요~~ ^^

    

설정

트랙백

댓글

[AS3] 좋은 코드를 작성하기 위한 길

Programming/ActionScript 3.0 2008. 12. 27. 11:30
플래시는 에니메이션 저작툴이라는 디자인적인 탄생 배경을 탈피하고 많은 프로그래머들이 매력을 느끼는 컴퓨터 프로그래밍 언어로 발전하였다. 나는 어린 시절 장래 희망을 물어보면 컴퓨터 프로그래머라고 이야기하던 시절이 있었다.(그때는 5.25인치 디스크 한 장에 게임 하나가 들어가던 시절이었는데 아마도 게임을 하면서 스토리를 내 마음대로 바꾸고 싶었던 것 같다.)

하지만 그런 꿈은 삶의 역경 속에서 잊혀지고 나아가 컴퓨터 프로그래머라는 직업이 돈이 되는 직업은 아니라는 것을 알았을 무렵에는 이내 나의 꿈은 컴퓨터 프로그래머가 아니었다고 부정하였다. 결국 부정하던 장래희망의 굴레에 나를 몰아넣은 것은 플래시라고 할 수 있다. 내가 플래시를 처음 접했을 때는 이런 형태로 발전할지는 꿈에도 몰랐었으니 고로 나는 플래시에게 사기를 당한 것이다. ^^


나는 배우는 과정에 서있다. 항상 플래시의 발전을 따라가느라 정신 없이 허우적거리는 생활을 반복하고 있으니 아마도 내가 플래시라는 툴에서 손을 놓을 때까지 이러한 배움의 길은 끝이 없을 듯싶다.

배우는 과정에서 느꼈던 좋은 코드를 작성하는 방법에 대하여 이야기 해 볼까 한다. 본 내용은 일본 잡지에 실린 연재 코너의 내용을 ActionScript 버전으로 본인의 생각을 덧붙여 작성한 것임을 밝혀둔다.

좋은 코드란?
좋은 코드는 조직이나 프로젝트, 프로젝트 메니저에 따라서 그 정의가 다르게 해석될 수 있다. 하지만 보편적으로 좋은 코드로서 바람직한 방향은 있다.

정확하게 동작하는 것.
정확한 결과값을 도출하는 것은 신뢰할 수 있는 코드다.

빠르고 효율적으로 동작 하는 것.
결과 값을 도출하는 방법은 여러 가지가 있을 수 있다. 좋은 코드는 적절한 퍼포먼스로 동작한다.

방어적으로 버그를 생산하지 않는 것.
방어적 프로그래밍 방법론에 기초하여 정상적인 값이 들어 올 것이라고 가정하지 않고 부정확한 값이 와도 문제가 발생하지 않도록 방어적으로 코드를 작성한다. 이것은 처음에 열거한 정확하게 동작하는 것을 도와준다.

유지보수를 하기 쉬운 것.
프로젝트는 단기간에 수명을 다할 수도 있지만 우리가 상상하는 것보다도 길게 생명을 유지하는 것도 많다. 유지보수성을 높이는 것도 좋은 코드에 있어서 중요하다.

다른 사람이 봐도 이해하기 쉬운 것.
현재 작성한 코드를 미래에 자신이 보는 것과 현재 타인이 보는 것은 비슷하다고 볼 수 있다. 미래에 자신이 봐도 이해할 수 있는 코드는 좋은 코드라 할 수 있다.

쓸데없는 부분이 없는 것.
쓸데없는 코드를 작성하는 개발자는 없을 것이다. 다만 코드의 구현과정에서 기능 추가 및 다른 로직과의 연동 과정에서 불필요하게 파생하는 코드들은 지양할 필요가 있다.


좋은 코드를 작성하면 무엇이 좋은가?
좋은 코드는 프로젝트를 추진하고 성공적으로 이끌기 위한 기본적인 요소가 된다. 프로그래밍의 달인들은 심플하고, 유지보수성이 좋고 안정적인 코드를 빠른 속도로 작성한다. 테스트가 어려운 코드를 테스트가 가능하고 검증할 수 있는 코드로 변경함으로써 품질이나 생산성을 수백 배 높이기도 한다. 이것은 프로젝트의 성공에 있어서 큰 요소이다. 물론, 좋은 코드가 있으면 반드시 프로젝트가 성공하는 것은 아니다. 개발 프로세스나 메니지먼트, 커뮤니케이션등으로 좌우되는 경우가 더 많지만 이런 것들을 제외한다면 개발에 있어서 좋은 코드의 힘은 크다고 볼 수 있다.

프로그래머로서의 평가가 높아진다.
좋은 코드를 작성하는 프로그래머는 대체적으로 프로그래머로서 신뢰한다. 프로그래머로서의 평가가 조직으로서의 실제 평가나 이익에 결합될지는 소속하는 조직의 평가 제도나 프로그램 이외의 일도 포함하여 정해지는 것이 현실이다. 그렇다고 좋은 코드를 쓸 수 있는 것이 마이너스 평가로 이어지지는 않을 것이다.

일에 대한 만족감이나 자신감을 가질 수 있다.
두 번 다시 손대고 싶지 않은, 유지보수가 불가능한 코드를 써본 적이 있을 것이다. 이러한 낮은 퀄리티의 일을 해 놓으면 일에 대한 만족감을 얻을 수 없다. 반면 자신의 의지로 적절히 좋은 코드를 작성함으로써 품질이 높고 안정된 소프트웨어를 개발했을 때는 그에 대한 만족감도 높고 자신감을 갖고 일에 임할 수 있다. 앞으로 오랜 시간을 프로그래머로써 살아갈 것이라고 생각한다면 좋은 코드를 쓸 수 있는 레벨을 목표로 하는 것은 합리적인 일이다.

사실 좋은 코드를 작성하기 위해서는 하루아침에 이룰 수 없다. 그렇다면 좋은 코드를 작성하기 위해 구체적으로 무엇을 어떻게 해야 하는지를 살펴보자.

코드 리딩 - 읽어라, 코드를 읽고, 읽고, 또 읽어라.
음악이나 회화, 건축의 세계에서도 자신만의 발상으로 작품을 완성시키는 예술가는 없다. 다른 사람들의 작품을 보고 영향을 받거나 좋은 곳을 훔치거나 해서 자신의 작품을 만드는 것으로 작품을 낳아 왔다.

프로그래밍도 같다. 좋은 코드를 작성 하려면 좋은 코드이건 나쁜 코드이건 간에 다른 사람이 작성한 코드를 평소에 의식하고 읽는 것이 중요하다. 플래시는 특히 많은 오픈 소스가 인터넷에 열려 있기 때문에 다른 사람이 작성한 좋은 코드를 언제라도 부담 없이 읽을 수 있다. ActionScript 중급 정도의 실력자이지만 구조를 어떻게 만들어야 하는지 막막한 분은 특히 주목할 필요가 있다. 이런 단계에 머물러 있는 분이라면 코드리딩을 통해서 한 단계 발전한 자신을 발견할 수 있을 것이다.

코드리딩의 좋은 점은 알아도 코드를 읽는 방법을 모른다면 시작하기 힘든 일이다. 아래의 간단한 코드를 보면서 이야기 해보자.

package classes.data{

    import flash.events.Event;
    import classes.data.*;
    import classes.net.SimpleXMLLoader;
   
    public class DProvider extends SimpleXMLLoader{ // [1] 여기부터
           
        private var _xmlUrl:String;   
        private var _keywords:Array;
       
        public function DProvider(inUrl:String):void { // [2] 여기부터
            _xmlUrl = inUrl;
            addEventListener(Event.COMPLETE, onLoadedXmlHandler);
            loadXML(_xmlUrl);
        }    // [2] 여기까지

        private function onLoadedXmlHandler(e:Event):void { // [3] 여기부터
            var xml:XML = XML(data);
            _keywords = [];
           
            var len:int = xml.item.length();
            for (var i:int = 0; i < len; i++)
            {
                // [4] 여기부터
                _keywords.push(createKeyword(xml.item[i]));
            }
        }    // [3] 여기까지
       
        private function createKeyword(inKeywordNode:XML):KeywordBase
        {
            var keyword:KeywordBase;
            switch(int(inKeywordNode.level)) {
                case 1: keyword = new Keyword1(inKeywordNode);
                break;
                case 2: keyword = new Keyword2(inKeywordNode);
                break;
                case 3: keyword = new Keyword3(inKeywordNode);
                break;
                case 4: keyword = new Keyword4(inKeywordNode);
                break;
            }
            return keyword;
        } // [4] 여기까지
       
        public function get keywords():Array { return _keywords.concat(); } // [5]
    } // [1] 여기까지
}

위 클래스는 본인이 실무에서 작업했던 태그클라우드에서 사용했던 코드이다. 클래스의 기능은 xml데이터를 불러들여 level 노드 값에 따라서 해당 클래스들을 배열로 생성하여 제공한다.

위 클래스 외적으로 사용된 클래스는 다음과 같은 기능을 포함한다.
SimpleXMLLoader : 단순히 xml 데이터를 불러오는 기능을 한다. loadXML 메소드가 포함되어 있다.
KeywordBase : 키워드 무비클립의 기본이 되는 기능을 제공한다. (마우스 다운, 오버, 아웃등)
Keyword1 ~ Keyword4 : KeywordBase 를 상속하는 각 레벨에 따라 디자인이 서로 다른 클래스들

코드리딩을 할 때는 기본적으로 nest 단위로 읽어 내려가면 된다. 중간에 나타나는 다른 클래스들은 현재 블록을 전체적으로 훑어 보면서 유추하도록 하자. 중간에 다른 파일을 열어 읽게 되면 현재 읽고 있는 흐름을 놓칠 수 있기 때문이다.

50줄도 안 되는 코드지만 이 코드만 가지고도 작업된 클래스들의 절반 이상은 이해할 수 있다. 복잡한 기능을 하는 클래스는 아니기 때문에 읽으면서 구조적으로 어떻게 작성이 되었는지 알 수 있을 것이라 믿는다. 이런 훈련을 반복 하다 보면 현재 읽고 있는 클래스 이외의 다른 클래스들도 머리 속으로 그리는 과정을 얻게 된다. 이를 통해서 하나를 보면 열을 알게 되는 경지에 다다를 수 있을 것이다. ^^

구글에서 코드 검색엔진을 통해서 웹에 있는 원시 코드들을 검색할 수 있는 서비스를 제공하고 있다. 자신이 원하는 기능의 클래스명이나 메소드명으로 검색해서 코드리딩 연습을 하는 것도 좋은 방법이다. 또한 많이 알려진 클래스나 패키지들은 구조적으로 잘 설계된 것들이 많이 있다. 구조적인 관점에서는 그런 것들을 분석해 보는 것도 큰 도움이 된다.

http://www.google.com/codesearch
인터넷상에 공개되어있는 Subversion(repository)나 archive파일 등을 기계적으로 빠르게 검색 할 수 있다.

좋은 이름을 붙이자.
우리가 프로그래밍을 하고 있을 때 가장 막히는 부분은 변수명, 메소드명, 클래스명 이름을 붙이는 것이다. 그만큼 좋은 이름을 붙이는 것은 중요하다. 좋은 이름을 붙이는 것이 중요한 이유는 위에서 언급했던 코드리딩에서도 느낄 수 있듯이 관련 기능에 부합하는 좋은 이름을 붙이지 않으면 코드를 읽기가 어려워진다.(생각해보니 위에서 예로 든 코드에서도 어려움을 느낀 분들이 있을 것 같다 ^^;)

그렇다면 좋은 이름의 조건이 있을 법하다.

좋은 변수명, 메소드명, 클래스명은 이름이 그 코드의 내용을 올바르게 나타내고 있다. 그러한 이름은 이름을 보는 것만으로도 코멘트를 읽을 필요도 없이 그 역할을 이해할 수 있다. 좋은 이름은 코드의 이해를 돕지만 나쁜 이름은 읽는 사람을 혼란 시키고 착각을 낳아 버그 발생을 조장한다.

위 코드를 예로 들면 onLoadedXmlHandler 메소드 명을 onComplete로 했을 경우에 어떤 것이 Complete 되었다는 것인지 인지하기 어렵다. 위 클래스의 경우는 단순한 클래스이지만 클래스의 내용이 많고 complete 핸들러 함수를 여러 개 포함하고 있을 경우에는 메소드의 중복이 발생할 수도 있다.

public function get keywords():Array { return _keywords.concat(); }
의 경우에는 keyword에 복수를 뜻하는 s를 붙임으로써 전달 받는 keyword가 하나가 아니라 복수이며 배열이라는 것을 유추할 수 있다. 이 밖에도 아래와 같은 방법이 있다.

어두 이외의 모음을 삭제 (image ->img)
강한 소리를 남긴다. (server -> svr)
약어의 이용 (database -> db)

일관성이 있다.
좋은 이름은 코드 전체에서 일관된 흐름을 가져야 한다.

대칭성을 유지하는 것
begin <-> end
write <-> read
on <-> off

단어의 조합의 일관성
scoreAvg
scoreAverage
avgScore
위 이름은 하나의 클래스에서 중복 사용하지 않을 것.

관용어에 따라서
언어, 프로젝트, 회사나 팀 마다 명명에 관한 관용어(관습)가 있다. 예를 들면 Java의 경우는 메소드명은 소문자로 시작하는 것이 관습이며, C#은 대문자, C++은 멤버 변수에 prefix로 m_를 붙이는 것이 일반적이다. 관용어에 따른 명명은 누가 보더라도 알기 쉬운 이름이라고 이야기 할 수 있다.(ActionScript의 경우는 보통 자바와 언어적 문법이 비슷하기 때문에 자바와 같은 명명 관용어를 사용하는 경우가 많지만 개인적인 취향에 따라 다르게 사용하는 경우가 대부분이다.)

코딩 표준에 따라서
위와 같이 좋은 코드의 조건을 채우기 위해서도 코딩 표준이나 명명 규약을 정해 팀 멤버 전원이 맞추는 것이 중요하다. 작업자 1명이 단기적으로 작업하는 프로젝트에서는 본인이 원하는 규칙을 사용하면 되겠으나 조직의 힘을 바탕으로 얻을 수 있는 큰 프로젝트의 경우는 협업의 중요성이 대두되므로 이러한 코딩 표준을 맞추는 것이 장기적으로는 바람직하다고 볼 수 있다.

좋은 이름을 붙이기 위한 습관
항상 좋은 이름을 붙이는 것을 의식한다.
좋은 이름을 붙이려면 우선 의식적으로 노력을 해야 한다. 이것은 A라는 이름이 좋은가? 아니면 B라는 이름이 좋은가를 항상 신중하게 검토해 보고 적절한 이름을 결정하는 프로세스를 반복할 필요가 있다.

코드의 리딩이나 리뷰
자신이 모르는 완전히 새로운 이름을 만드는 것은 코드를 분별없게 만들 가능성이 크다. 본인이 작성한 코드를 스스로 리딩해 보거나 다른 사람에게 리뷰를 함으로써 사용할 수 있는 이름을 조금씩 늘려간다. (본인 같은 경우는 아는 단어의 수준이 메롱이기 때문에 코드작업을 할 때 항상 사전을 열어놓고 작업을 하는 습관이 있다. 이때도 주의할 것은 일회성으로 모르는 단어를 만들어 명명하는 것 보다는 그 단어를 충분히 숙지한 상태에서 이름으로 사용하는 것이 바람직하다 – 간혹 내가 만든 이름을 내가 이해하지 못하는 어처구니 없는 경우가 발생 하기도 한다. 메롱;;)

좋은 변수명
설명적인 변수명
변수에는 값이나 오브젝트가 대입된다. 변수명을 보는 것만으로도 무엇이 어떠한 역할을 하는지 명확한 것이 좋은 이름이라 할 수 있다.

예를 들어
var n:int;                                                 // 무슨 수치?
var languages:Array = [“kr”, “en”];     // 무슨 언어?
var flg:Boolean = false;                      // 무슨 플래그?
var userAgent:UserAgent                  // 무슨 유저 에이전트?

위와 같은 변수명은 나중에 되돌아보면 변수의 역할을 알 수 없다. 아래와 같이 좀더 구체적이고 명확한 이름으로 해 두면 되돌아 보거나 다른 사람이 봐도 이해하기 쉬운 코드가 된다.

var orderCount:int;                                                // 오더수
var availableLanguages:Array = [“kr”, “en”];     // 이용 가능한 언어
var existsSameName:Boolean = false;           // 동성동명이 존재할까?(존재 true)
var unknownUserAgent:UserAgent                  // 미지의 유저 에이전트

다만 변수는 변수의 종류와 그 변수의 스코프(변수의 값을 참조할 수 있는 범위, 변수의 선언으로부터 시작되어 변수의 값을 참조할 수 없게 될 때까지의 범위)에 의해서 좋은 이름의 성질이 다르다. 스코프가 넓으면 다양한 곳으로부터 참조되므로 영향 범위가 크다고 할 수 있다. 따라서 보다 구체적인 이름이 요구된다. 종류별로 보면 아래와 같다.

필드 변수, 클래스 변수
필드 변수는 인스턴스 변수이다. 필드 변수, 클래스 변수는 로컬 변수등과 비교하면 변수의 스코프가 넓기 때문에 특히 그 변수의 의미를 올바르게 표현한 이름이 바람직하다.

메소드의 파라미터
파라미터명은 알기 쉽고 간결한 이름이 좋을 것이다. 파라미터명은 이용자가 API레퍼런스로 참조하거나 Eclipse, FlashDevelop등의 통합 개발 환경으로부터 변수명의 후보로서 이용되므로 극단적으로 짧은 이름을 붙이는 것은 피해야 한다.

로컬 변수
메소드 내에서 일시적으로 선언되는 변수이다. 스코프가 긴 것도 있지만 for문과 같이 짧은 것도 있다. 스코프가 긴 것은 필드 변수와 같이 변수의 의미를 올바르게 표현하는 구체적인 이름을 붙이는 것이 좋다. 스코프가 짧은 것은 아래와 같이 사용구분만 적당히 해주면 된다.

관용어에 따르는 또는 따르지 않는다.
배열의 내용을 순서대로 처리하는 루프 카운터 변수(i,j,k)등과 같이 잘 사용되는 관습적인 변수명은 그대로 관용어에 따르는 편이 알기 쉬운 코드가 된다.
// 루프 카운터의 변수명이 관습적이지 않고 너무 길다 [X]
for (var empCounter:int=0 ; empCounter < employes.size ; empCounter++) {
          var emp:Employee = employees[empCounter];
    ...
}

// 루프 카운터의 이름이 관습적으로 짧고, 가독성이 높다 [O]
for (var i:int=0 ; i<employes.size ; i++) {
         var emp:Employee = employees[i];
    ...
}


다만 예외적인 경우도 있다. 구체적인 이름을 변수명으로 하는 편이 알기 쉬운 경우는 그렇게 사용한다. 예를 들어 좌표계를 취급하는 경우에는 아래와 같이 사용하여 가독성을 높일 수 있다.
// i,j의 어느 쪽이 x좌표, y좌표인지를 모른다 [X]
for (var i:int=0 ; i<width ; i++) {
    for (var j:int=0 ; j<height ; j++) {
        var color:uint = getColor(i, j);
        ...
    }
}

// 변수명을 x,y로 했으므로 알기 쉽다 [O]
for (var x:int=0 ; x<width ; x++) {
    for (var y:int=0 ; y<height ; y++) {
        var color:uint = getColor(x, y);
        ...
    }
}

위 for문의 경우, 중첩되는 var y:int=0 변수 선언은 for문 밖에서 선언해 주는 것이 바람직하다. 중첩된 for문 안에서 x가 카운팅 될 때마다 메모리상에서는 y라는 변수의 어드레스를 매번 push해야 하는 불필요한 리소스 낭비가 발생하기 때문이다. (이 부분에 대한 논쟁 이슈가 있다. 이후에 이야기할 로컬 변수의 스코프 부분에서 로컬 변수의 스코프는 가능한 작게 한다는 변수의 의존성에 따른 대원칙에 위배되는 것이기 때문이다. 이것은 사용하는 상황에 따라 적절히 혼용하는 것이 좋을 것이다.)
var x:int;
var y:int;
for (x=0 ; x<width ; x++) {
    for (y=0 ; y<height ; y+) {
        var color:uint = getColor(x, y);
        ...
    }
}

변수명을 짧게 하는 편이 가독성이 향상되는 경우도 있다.
충분히 인지할 수 있는 범위인 경우로 루프내의 변수나 짧은 메소드 내의 변수처럼 일시적인 변수는 짧게 하는 편이 반대로 가독성이 향상되는 경우도 있다.
// 변수명 siteContactChangelog는 너무 길다 [X]
for (var i:int=0; i<siteContactChangelogs.length ; i++) {
    var siteContactChangelog:SiteContactChangelog = siteContactChangelog[i];
    siteNames[i] = siteContactChangelog.getSiteName();
    siteTitles[i] = siteContactChangelog.getSiteTitle();
    sitePicIds[i] = siteContactChangelog.getPicId();
    sitePicNames[i] = siteContactChangelog.getPicName();
}

// 변수명 log는 충분히 그 의미를 이해할 수 있기 때문에 가독성이 좋다.[O]
for (var i:int=0; i<siteContactChangelogs.length ; i++) {
    var log:SiteContactChangelog = siteContactChangelog[i];
    siteNames[i] = log.getSiteName();
    siteTitles[i] = log.getSiteTitle();
    sitePicIds[i] = log.getPicId();
    sitePicNames[i] = log.getPicName();
}

좋은 메소드명
좋은 메소드명은 이름으로부터 그 기능을 예상할 수 있다. 메소드는 처리를 담당함으로 메소드명은 동사+목적어 형태인 것이 많다. 아래는 자주 사용되는 메소드명의 예이다.
 메소드의 역할                                         메소드명
 값 취득에 관한 메소드                           getXXX
 값 세트에 관한 메소드                           setXXX
 생성에 관한 메소드                                create, build, make, generate
 초기화에 관한 메소드                            initialize, setupXXX
 파기에 관한 메소드                               destroy, dispose
 상태 확인에 관한 메소드                      contains, exists

인스턴스 메소드는 dataFormat.parse와 같이 오브젝트명으로 조합하므로 합쳐졌을 때는 중복 없게 의미가 통하는 이름으로 한다. 메소드와 클래스명도 이와 동일하다.
// parseDateString은 클래스명 DateFormat과
// date라는 이름이 중복되어 약간 장황
var dateFormat:DateFormat = new DateFormat("yyyy-MM-dd");
var startDate:Date = dateFormat.parseDateString("2008-04-01");

// 클래스명 DateFormat과 메소드명 parse로
// 무엇을 처리하는지 충분히 이해할 수 있음.
var dateFormat:DateFormat = new DateFormat("yyyy-MM-dd");
var startDate:Date = dateFormat.parse("2008-04-01");

좋은 클래스명
변수명이나 메소드명과 비교해서 클래스명은 가용 범위가 크기 때문에 적절하고 좋은 클래스명을 붙이는 것이 중요하다. 좋은 클래스명은 이름만으로 무엇을 실시하는 클래스인가를 알 수 있다.

클래스명이 잘 떠오르지 않을 때는 자신이 만들려고 하는 클래스의 역할을 제대로 정리 할 수 있는지 없는지를 판단해 보아야 한다. 1개의 클래스에 복수의 책무를 넣거나 역할이 애매한 기능은 없는지를 생각해보고 해당 클래스에서 해결하고자 하는 문제를 차분히 생각해보고 클래스명을 다시 선택할 필요가 있다.

클래스명의 어휘 설계 능력
이름 명명에 관하여 자신이 모르는 표현, 개념은 쉽게 생각하기 어렵다. 보다 나은 표현을 선택하려면 여러 가지 코드나 서적을 읽거나 실제로 코드를 쓰고 시험하는 것이 중요하다. 그 경험을 통해서 이름에 관한 어휘가 조금씩 늘어난다. 본인 같은 경우는 영어권의 개발자가 작성한 기능과 메소드명을 보면서 의미해석을 한다. 사실 프로그래밍 과정에서 이름을 짓는 것은 생활에서 보편적으로 사용하지 않는 단어들도 많이 존재한다. 하지만 그만큼 자주 사용되는 단어들은 한정되어 있기 때문에 틈나는 대로 기억을 되살려 사용해 보는 것이 중요하다.

좋은 패키지명
ActionScript의 패키지명은 클래스나 자원의 논리적인 그룹을 만들어 계층 구조를 나타낸다 이것은 주로 이름의 충돌을 막기 위해서 사용된다. 패키지명은 그룹의 논리적인 내용을 나타내는 간결한 명사를 선택한다.

간혹 클래스를 만들지 않고 라이브러리에서 특정 무비클립을 동적으로 참조하기 위하여 Linkage에 클래스명만 기입하여 사용하는 경우가 있다. 이럴 경우 클래스가 플래시 컨텐츠전역에 오픈 되기 때문에 팀의 협업에 있어서 클래스명의 충돌을 야기할 수 있다. 이럴 경우 해당 클래스가 없더라도 관련된 패키지명을 명시함으로써 그러한 충돌을 줄일 수 있다. 

처음부터 좋은 이름을 사용할 수 있는 사람은 없다. 좋은 이름에 대해서 의식적으로 사용하려고 노력하는 것이 중요하다. 누구라도 알기 쉽고, 이해하기 쉬운 코드라고 하는 것은 항상 의식하고 노력하다 보면 점차적으로 좋은 이름을 지을 수 있는 요령이 생길 수 있을 것이다.


스코프를 의식한 프로그래밍
사실 모든 프로그래밍에서 스코프는 존재한다. 의식적으로 스코프를 컨트롤 할 수 있으면 보다 좋은 프로그래밍 스타일에 가까워질 것이다. 이번에는 스코프에 대한 이야기를 해보자.

우선 스코프는 Wikipedia에 다음과 같이 정의되어 있다.
프로그래밍에서 스코프란, 어느 변수나 함수가 특정 이름으로 참조되는 범위, 어느 범위의 밖에 있는 변수 등은 통상 그 이름만으로는 참조할 수 없다. 이때 이러한 변수는 스코프 밖에 있어 보이지 않는다 라고 말한다.

스코프는 변수, 메소드, 클래스등이 보이는 범위다. 그렇다면 보인다는 의미는 무슨 뜻일까? 보인다라는 것은 프로그래밍상에 있다는 것이다. 변수이면 변수명을 지정해 값을 읽고 쓰기가 가능하고 메소드는 호출해 사용할 수 있는 범위에 있는 것이다.

사용할 수 있다라는 것은 바꾸어 말하면 그것에 의존한다라고 이야기할 수 있다. 하나의 코드를 변경하고 싶을 뿐인데 수십 곳을 수정할 필요가 있을 수 있다. 이것은 변경하고자 하는 코드가 여러 곳에 의존하고 있으면 이와 같은 변경이 다른 부분에 영향을 준다.

스코프 == 보이는 범위 == 사용할 수 있는 범위 == 의존하는 범위

변수나 메소드의 스코프를 작게 하는 것으로 보이는 범위가 작아져 사용할 수 있는 범위, 의존하는 범위도 작게 할 수 있다. 스코프를 작게 하는 것으로 보다 의존성이 적어 변경이 용이한 프로그램을 작성 할 수 있는 것이다.

기억해 두는 것을 줄이자.
의존이 작아지는 것 이외에도 스코프를 작게 하는 것으로부터 도움이 되는 것이 있다. 프로그래밍은 본질적으로 복잡한 것이다. 복잡함에 대한 대책으로서 문제 영역을 가능한 작고, 이해 가능한 상태로 취급하는 것이 중요하다. 스코프를 의식적으로 작게 하는 것으로 프로그래머가 기억해 두지 않으면 안 되는 것, 주의하지 않으면 안 되는 범위는 작아져서 쉽게 이해할 수 있게 된다. 이것이 스코프를 작게 하는 것의 본질이라고 할 수 있다.

로컬 변수의 스코프
로컬 변수란 메소드 내에서 선언된 일시적인 변수다. Java나 Ruby의 로컬변수는 선언된 장소로부터 스코프가 시작되어 선언된 블록이 끝나면 스코프가 종료된다. ActionScript 2.0 에서도 순차적으로 메모리 할당이 이루어 졌기 때문에 메소드 내에서 상위에 선언된 변수와 하위에서 선언된 변수가 서로 다른 영역 범위의 스코프를 갖기 때문에 컴파일 시에 충돌이 발생하지 않았다.(Java, Ruby와 동일)

반면 ActionScript 3.0에서의 로컬변수는 스코프의 시작은 컴파일러가 블록에 접근했을 때 블록 내의 위치와는 상관없이 미리 메모리 주소가 할당된다. 이는 컴파일 시에 메모리 할당이 한꺼번에 선행되어 스코프가 동일하기 때문에 변수명 중복 에러 메시지를 출력하는 것이다.

하지만 일반적인 프로그래밍 언어에서는 변수의 의존도를 최소화하여 프로그램의 변경이 쉽게 하기 위하여 [로컬변수의 스코프는 가능한 작게 한다.] 라는 것이 대원칙이다.

필드 변수의 스코프
필드 변수는 인스턴스 변수다. 필드 변수의 스코프는 private / public 등과 같은 키워드를 통해서 정해진다. ActionScript의 경우 필드 변수에 대한 가시성은 스코프가 작은 순서로 4개가 지원된다.
private    : 오브젝트 내에서만 변수에 액세스 할 수 있다.
internal    : 같은 패키지 내에서 액세스 할 수 있다.
protected : 오브젝트 내 그리고 하위 클래스로부터 액세스 할 수 있다.
public : 오브젝트 밖에서 액세스 할 수 있다.

필드 변수는 모두 private가 기본 전략이다. 필드 변수에 외부나 하위 클래스로부터 액세스 하고 싶은 경우에는 set/get 등 액세스용 메소드를 따로 만들어 공개하는 것이 캡슐화에 도움을 준다. 하지만 기본 전략이 바람직하다고는 하지만 상속에 따른 장황함을 배제하기 위해서 protected나 public 접근자를 사용하는 경우도 발생한다.

인스턴스 메소드의 스코프
인스턴스 메소드는 인스턴스에 속하는 메소드를 말한다. ActionScript에서 메소드의 스코프 가시성도 필드 변수와 같이 4개이다. 메소드의 접근 제한은 최소인 private로부터 시작하여 점차적으로 internal -> protected -> public으로 나아가는 것이 바람직하다.

메소드 파라미터의 정보량
스코프에서 조금 벗어난 이야기이지만 메소드의 인수로 건네주는 정보량을 어느 정도로 하는 것도 의존성이라는 관점에서 보면 중요한 선택이다.

예를 들면 아래의 두 코드는 사원 정보를 취득하는 메소드이지만 1번은 인수가 사원ID이고 2번은 인수가 사원 오브젝트이다. 이 두 개의 코드 중에 어느 쪽이 좋은 코드라고 할 수 있을까?
// [1] 인수가 사원ID인 경우
public function getEmployee(inEmpId:int):Employee {
    return empDao.findById(inEmpId);
}

// [2] 인수가 사원 오브젝트의 경우
public function getEmployee(inEmp:Employee):Employee {
    return empDao.findById(inEmp.getId());
}

일반적으로 1번이 인수의 정보량이 적기 때문에 의존이 적고 좋은 코드라고 할 수 있다. 반면 2번은 사원 오브젝트가 가지는 모든 정보로 액세스가 가능하기 때문에 의존이 커지게 된다. 필요한 것은 사원의 ID이므로 그것에만 의존하여 코드를 작성하는 것이 바람직하다.

메소드를 이용하는 측면에서 사원 ID만으로 메소드를 이용할 수 있는 것과 사원 오브젝트가 필요한 것은 전혀 다르다. 더욱이 2번 메소드 내에서 구체적인 처리는 사원 오브젝트의 사원 ID만을 사용해 사원 정보를 검색하고 있다. 이것이 문서화 되어 있지 않을 경우, 코드를 읽지 않으면 그 사실을 알지 못한다. 인수에 불필요한 정보가 포함되어 있으면 사원 ID가 포함된 사원 오브젝트를 건네주어야 한다는 암묵적인 요구가 발생하기 쉽다.

위와 같은 문제 때문에 메소드의 인수는 필요 최저한의 정보를 가지는 것이 의존성이 적고 좋은 코드라고 말할 수 있다.

다만 인수가 너무 많아지는 경우는 인수를 오브젝트로 변경하는 편이 좋다. 기준으로서 인수의 개수가 5개를 넘는 메소드는 인수를 오브젝트로 변경하는 것을 검토할 필요가 있다.

static 메소드
static메소드(클래스 메소드)는 클래스에 속하는 메소드이다. ActionScript에서는 static 키워드를 붙여서 선언한다. static 메소드의 가시성은 인스턴스 메소드의 가시성과 같다. 반면 다른 점은 static 메소드는 필드 변수에 액세스 할 수 없다. static 메소드는 메모리에 미리 할당이 되는 반면 인스턴스 변수는 오브젝트가 인스턴스화 된 시점에서 메모리 할당이 되기 때문에 static 메소드 내에서 인스턴스 변수를 참조할 방법이 없는 것이다.

필드 변수에서 보면 인스턴스 메소드를 static 메소드로 변경했을 경우, 자신이 영향을 주는 메소드가 줄어 들게 되어 결과적으로 스코프는 작아진다. 필드 변수에 액세스 할 필요가 없고, 오버라이드가 필요하지 않는 메소드는 static 메소드로 하는 편이 좋은 경우가 많다. 물론 무조건 static으로 하는 것이 좋은 것은 아니다. 인스턴스가 생성되지 않은 시점에서 메모리에 할당이 되기 때문에 사용하지 않는 클래스의 static 메소드가 메모리에 상주하는 메모리 차원에서의 단점도 있다.
// 인스턴스 메소드의 경우
private var count:int;                                                           ┓
...                                                                                           |
private function regexGroup(inRegex:String):String { |변수 count의 스코프
    // 필드에 액세스 가능                                                     |
    return "(" + regex + ")";                                                   |
}                                                                                             |
...                                                                                            ┛

//static 메소드로 변경했을 경우
private int count;                                                                  ┓
...                                                                                            ┛변수 count의 스코프
static private function regexGroup(inRegex:String):String {
    // 필드에 액세스 불가
    return "(" + regex + ")";
}
...     ―변수 count의 스코프


코드의 분할
몇 천행이 넘는 메소드로 너무 많은 기능을 포함하고 있거나 메소드를 너무 세세하게 분할하여 흐름을 파악하기 어려운 코드는 좋은 코드라 할 수 없다. 좋은 코드가 되기 위해서는 가독성이 좋고, 유지보수성이 우수한 것이라고 위에서 언급했다. 메소드를 적절한 단위로 분할하는 것은 좋은 코드를 만드는 것에 중요한 역할을 한다.

코드를 분할하면 무엇이 좋은가?

가독성의 향상
메소드 코드의 길이가 100줄을 넘으면 처리의 흐름을 읽는데 어려움이 있다. 반면 30행 이하이면 내용을 이해하는 것이 용이하다.

유지보수성의 향상
분할에 의해 변수의 스코프가 작아지거나 처리 기능이 본래 있어야 할 클래스나 메소드로 이동하는 것으로 의존관계가 정리되어 유지보수성이 향상된다.

재이용성 향상
코드를 분할하면 코드의 중복이 줄어들어 이용 가능한 부품으로서의 메소드나 클래스를 만들 수 있다. 이것은 OOP 언어에서 좋은 방법이다.

캡슐화를 지킬 수 있다.
객체 지향에서는 캡슐화라는 개념이 있다. 메소드나 클래스의 상속에 의한 구체적인 구현이나 오브젝트 상태를 몰라도 메소드를 호출하는 것만으로도 각각의 오브젝트가 처리를 이행해 주는 것이다.

클래스의 관점에서도 비슷한 이득을 얻을 수 있다. ActionScript는 타 언어보다 MVC 페턴을 예로 들면 view에 해당하는 클래스가 Model에 비해 상대적으로 비대하다. 따라서 구조 작업에 있어서 이러한 view 그룹을 어떻게 분할하느냐에 따라서 유지보수성의 성패를 좌우한다고도 볼 수 있다.

위에서 좋은 코드를 위한 방법에 관하여 이야기를 했다. 연재에 실린 내용과 그것을 ActionScript에 맞게 수정하는 관계로 문장이 다소 매끄럽지 않는 점이 있을 것이다. 그런 부분은  이해해 주길 바란다.

사실 플래시는 타 언어에 비해서 버그가 발생할 가능성이 크다. 그 이유는 플래시의 강점인 모션을 항상 고민해야 하는 작업이기 때문이다. 일반적인 언어에서는 어떤 오브젝트가 나타나고 사라지는 사이에 시간이라는 개념을 포함할 필요성을 인식하지 못하지만 플래시는 모션에 따라 그 사이에 시간이 존재할 수 있다. 모션이 있는 사이에 예측하지 않은 사용자 반응이 있을 경우에는 버그가 발생할 수 있다. 플래시 개발자는 항상 이런 부분까지 예상하고 방어적 프로그래밍을 해야 한다.

위에서 이야기한 좋은 코드를 작성하는 것은 플래시의 작업에 많은 도움을 주지만 그런 것이 플래시 개발의 모든 약점을 보완해 주지는 못한다. 때로는 일반적인 좋은 코드로서의 방향에 영향을 주지 않는 범위 내에서 플래시의 장점을 극대화 할 수 있는 방법을 고민 해야 하는 것이다.

간혹 좋은 코드를 작성하는 방법을 물어보시는 분들이 있다. 물론 그것이 모르는 부분을 빨리 이해할 수 있는 좋은 방법일 수 있지만 쉽게 얻은 지식은 지식으로 머물러 지혜로 발전하지 못하는 경우가 많다. 더구나 본인 또한 그 방법을 찾고자 고민하고 배워가는 입장이기 때문에 도움을 주지 못하는 경우도 있다.

또한 플래시의 발전은 지식에 목말라 스스로 지혜를 얻으려 노력했던 선배들의 도움으로 커왔다고 나는 믿고 있기 때문이기도 하다. 위에서 이야기 한 내용은 본인 또한 노력하는 부분이고 이 포스트를 읽는 분들도 지혜를 얻기 위해 노력하다보면 좋은 코드를 생산할 수 있을 것이라 믿는다.



    

설정

트랙백

댓글

[AS3] DigiMix

Programming/ActionScript 3.0 2008. 7. 23. 13:27
    

설정

트랙백

댓글

[FlashPlayer10] Flash Player 10에서 보완된 기능 리스트

Programming/ActionScript 3.0 2008. 7. 21. 14:55
< 사용자 필터&효과 >

After Effects CS3에서도 사용되고 있는 Adobe Pixel Bender를 사용하여 사용자 필터, 브랜드 모드 등을 작성할 수 있습니다. Pixel Bender는 하이 퍼포먼스 화상 처리 언어입니다. Pixel Bender를 사용하여 Flash Player의 업데이트를 통해서 주어진 효과를 사용하는 것이 아닌 개발자의 독자적인 효과나 필터를 추가할 수 있습니다. 독자적인 효과나 필터는 기존의 Flash Player에 탑재되고 있는 필터와 함께 사용할 수 있습니다. 또 벡터, 비트맵, 비디오 등 모든 오브젝트에 적용할 수 있으며 오브젝트가 가지고 있는 인터랙티브적인 성질은 그대로 유지합니다. 사용자 효과는 런타임으로 적용할 수 있습니다. 또한 사용자 필터의 사이즈는 보통 1KB정도의 파일 사이즈를 갖기 때문에 플래시 콘텐츠의 용량 증가의 문제가 발생하지 않습니다.

 

< 3 차원 3D효과 >

모든 2차원 오브젝트를 3차원 형태로 변형할 수 있습니다. 사용자 필터와 같이 2차원 오브젝트가 가지고 있던 인터랙티브 성질은 그대로 유지됩니다. 기존의 Papervision3D나 Sandy, Away3D를 사용하여 3차원 처리를 고속으로 처리할 수 있습니다. 플래시툴에 기본적으로 제공하는 3차원 변형을 통해서 복잡한 3차원 처리를 간단한 코드로 기술할 수 있습니다.

 

< 새로운 텍스트 엔진 >

새로운 텍스트 엔진은 매우 유연한 텍스트 레이아웃을 제공합니다. 기존에 텍스트, 컨트롤을 통해 새로운 텍스트를 만드는 기술 보완했으며, 사용하기 쉬운 API를 제공합니다. 이로서 다양한 환경에서의 텍스트를 사용할 수 있게 되었습니다. Right-to-Left 식의 세로 형태의 레이아웃 타이포그래피도 지원됩니다.

 

<  텍스트 레이아웃 컴퍼넌트 >

레이아웃과 스타일 텍스트, 테이블, 인라인 이미지, 그리고 열 정렬을 지원합니다. 이로써 신문과 같이 복잡한 테이블 형태를 지원하게 되어 텍스트필드를 다양하게 사용할 수 있게 되었습니다.(기존에는 이러한 텍스트 필드 자체에서 지원되는 기능적 제약이 있어서 디스플레이 오브젝트에서 처리 프로세스를 따로 만들어야 하는 번거로움이 있었다.)

 

< 랜더링 API의 개선 >

기존에 화면처리에서는 특정 shape를 화면에 표시하고자 할 때 기존에 화면상에서 존재하던 그래픽 객체를 지우고 다시 그려야 하는 문제로 인하여 메모리나 성능 면에서 불필요한 시스템 자원을 낭비했었습니다. 이번 버전에서는 그러한 문제점을 보완하기 위해서 특정 shape의 일부분만을 교체할 수 있는 것이 가능하게 되어 메모리와 성능 면에서 효율적으로 처리할 수 있게 되었습니다.

 

< 컬러 관리 >

Flash Player 10은 비교적 정확한 색을 재현할 수 있게 되었다. 컬러 관리에서 swf를 sRGB 색공간(color space)으로 변경가능하며, 컬러 관리는 모니터의 ICC 칼라 프로파일과 동조하여 SWF의 색을 정확하게 재현합니다. 이는 런타임에서 실시간 컬러를 swf에 적용할 수 있습니다.

 

< 시각적인 퍼포먼스 개선 >

기존의 랜더링은 CPU가 모두 처리하였던 것을 GPU를 통해서 처리할 수 있게 되었습니다. 이로써 기존에 CPU처리 만으로 한계가 있던 화면처리 포퍼먼스를 향상시킬 수 있는 길이 열렸습니다. 결과적으로 그래픽 카드(하드웨어가속)을 이용하여 어플리케이션이 보다 매끄러운  반응 속도를 낼 수 있도록 향상되었습니다. (길이 열렸다는 의미는 아직은 GPU를 사용한 최적화에 따른 개발적인 이슈와 그에 대한 개발 가이드가 아직 나와 있지 않은 상태이기 때문이다. 앞으로 개발에 따른 문제점은 보완될 것이라 기대해 본다.)

 

< GPU로의 화상 처리 >

화상을 합성·필터의 적용·비디오의 재생이 보다 빠르게 실시할 수 있게 되었습니다. 모든 래스터 오브젝트는 비디오 카드를 사용해 처리됩니다. 하드웨어로 비트맵, 필터, 비디오를 처리하는 것은 기존의 소프트웨어로 랜더링하던 것보다도 빠르게 재생할 수 있습니다. GPU로 화상 처리하는 것은 HTML 파라미터로 사용 여부를 설정할 수 있으며 하드웨어를 사용할 수 있는 사용자 시스템에서만 적용됩니다. 사용자 하드웨어가 GPU를 사용할 수 없는 경우에는 기존대로 소프트웨어로 처리 합니다. Open GL 2.0으로 GLSL를 지원하고 있는 비디오 카드가 있는 경우에만 이 기능을 사용할 수 있습니다. Flash Player의 베타판에서는  GPU 가속으로 처리되고 있을 때는 좌측 상단에 녹색의 사각이 표시됩니다.

 

< GPU로의 비트맵 전송 >

새로운 HTML 파라미터의 설정을 통해서 SWF를 브라우저에 표시 할 때에 비디오 카드를 사용하도록 할 수 있습니다. 이 기능은 SWF를 새롭게 컴파일 할 필요 없이 사용할 수 있습니다. 이 기능은 Flash Player 9 Update 3으로 도입된 풀 스크린으로의 비디오 표시에 하드웨어 가속화 기능을 확장한 것으로, 랜더링 포퍼먼스가 개선되어 CPU 사용도 효율적으로 관리할 수 있습니다. 결과적으로 비디오나 화상을 사용하는 어플리케이션의 포퍼먼스가 개선됩니다.

 

< Anti-Aliasing 제거 엔진(Saffron 3.1) >

Saffron를 개량하여 특히 아시아권의 언어를 렌더링 할 때의 Anti-Aliasing 제거의 포퍼먼스나 품질이 개선되었습니다. 또 stroke 폰트를 지원하여 필요한 메모리를 경감시켰습니다.

 

< Vector 데이터형 >

Flash Player 10의 ActionScript 3.0에서는 ECMAScript 4를 통해서 제안되고 있는 Vector 데이터형을 지원합니다 .Vector 데이터형은 배열과 비슷하지만 요소가 모두 같은 형태가 아니면 안 되는 제약이 있습니다. 요소의 형태에 제약을 두는 것으로 배열 조작보다 포퍼먼스가 획기적으로 개선되었습니다. (일반 배열을 사용할 때 보다 10배 이상의 속도향상이 기대됨)

 

< 리치 미디어 >

Flash Player 10에서는 다음의 Adobe Flash Media Server나 다른 Adobe 제품으로 제공될 예정인 새로운 오디오·비디오 기능을 탑재했습니다.

 

< 다이나믹스 트리밍 >

네트워크의 상황에 따라 항상 최적인 비디오 품질을 유지하는 것이 가능하게 되었습니다. bit rate를 변화시키는 것을 통해서 비디오가 재생 중에 끊김이 없도록 할 수 있습니다. 이는 비디오 시청자의 대역에 맞는 비디오 전달이 가능하다는 것을 의미합니다. 앞으로 Flash Media Server에서는 네트워크의 상황에 따라 RTMP로의 비디오 전달로 bit rate를 변화시킬 수 있습니다. 리얼타임에 네트워크 상황과 CPU의 상황을 ActionScript로 확인할 수 있으므로 개발자는 그러한 정보를 바탕으로 비디오 전달을 컨트롤 할 수 있습니다. ( 동영상 플레이어로 동영상을 보다가 플레이되는 속도보다 다운로드되는 속도가 느릴 경우 중간에 버퍼링 시간으로 딜레이 되는 것을 개선할 수 있다는 의미)

 

< RTMFP (Real Time Media Flow Protocol) >

RTMFP는, 기존의 RTMP over TCP로 가고 있던 시큐어인 데이터 전달을 UDP로 실시하는 것입니다.이 기능을 이용하기 위해서는 앞으로 릴리스 되는 Flash Media Server나, 다른 Adobe 제품을 사용할 필요가 있습니다. UDP는 영상 전달을 위한 효율적인 프로토콜입니다. RTMFP로의 통신은 암호화를 위해서 영상을 보호할 수 있습니다. 이 기술은 2006년에 매수한 Amicima, Inc.에 의하는 것입니다 .

 

< File Reference runtime access >

Flash Player 9에서도 FileReference를 사용해서 로컬 파일에 액세스 하는 것은 가능합니다만 이 기능은 파일의 업 로드/다운로드를 수행하기 위한 것으로 Flash 어플리케이션에서는 일단 서버를 경유하지 않으면 로컬 파일의 데이터를 사용할 수가 없었습니다. 하지만 Flash Player 10에서는 파일의 읽고 쓰기를 위해서 서버를 사용할 필요가 없이 플래시 어플리케이션에서 읽어 들인 데이터를 바로 사용할 수 있게 되었습니다.

 

Flash Player 10의 flash.net.FileReference 클래스에 추가된 API

public function get data():ByteArray // 읽힌 데이터 (독해 전용의 프롭퍼티)

public function load():void          // 지정된 파일의 읽기 개시

public function save(data:*, name:String = null):void  // 저장처를 선택하는 다이얼로그를 표시, 그 후 데이터 저장

 

 

< 다이나믹 사운드 제너레이션 >

사운드 클래스는 사운드 오브젝트에 등록된 이벤트 리스너를 통하여 동적으로 생성된 오디오를 재생 가능하게 되었습니다.

 

< Large Bitmap Support >

Flash Player 10에서는 기존에 2880 x 2880픽셀로 제한했던 비트맵 최대 사이즈를16,777,216 픽셀(4096×4096 픽셀)까지 비트맵을 취급할 수 있게 되었습니다. (AIR를 통해서 듀얼 모니터에서 스트린캡쳐한 비트맵 데이터를 가공할 때 2880 사이즈를 벗어나 생겼던 에러로 고민한 적이 있는데 이를 통해서 쉽게 해결되었다.)

 

< context menu >

context menu용 ActionScript API를 사용하여 context menu를 좀더 자유롭게 제어가 가능하게 되었습니다. 표준 텍스트와 리치 텍스트의 양쪽 모두를 지원하고 있습니다. 클립보드 메뉴를 통해서 안전하게 제어된 방법으로 클립보드에 액세스 할 수 있으므로 텍스트의 페이스트용 핸들러를 쓸 수도 있습니다.

 

http://labs.adobe.com/technologies/flashplayer10/releasenotes.html


 

 

    

설정

트랙백

댓글

오랫동안의 침묵

Miscellaneous/Story 2008. 7. 19. 22:00
한동안 블로그를 통해서 이야기를 하지 못했다. 여러 가지 개인적인 일들도 있었고 예전의 생활 패턴과 달라진 이유도 한 몫을 했던 것 같다.

사람은 심리적으로 불안정하거나 힘들 때 소비지출이 늘어난다고 한다. 자신의 힘듬을 다른 것을 통해서 보상받고자 하는 심리라고 하는데, 이러한 소비자의 심리를 이용하는 마케팅 기법도 활용된다고 한다. 내가 요즘 그런 바보스런 소비자 역할을 톡톡히 했던 것 같다. 물론 스스로 투자 차원에서 소비가 이루어 졌다고 생각하기 때문에 나에게는 크게 불필요한 지출은 아니였다……..고 생각한다. 쿠쿠

오랫동안 풀지 못했던 이야기를 플래시를 통해서 이야기 봐야겠다. 그 동안 가지고 놀아볼까 싶어서 쌓아두었던 자료들을 들추어 봐야겠고, 책도 봐야겠고, 인생설계도 다시 해야겠다. 그리고 당분간 실험적으로 아침형 인간이 되어 보려고 한다.

아침형 인간의 시작은 이미 금요일부터 시작되었고 나머지들은 차근차근 해봐야겠다… 이번 주말은 오랜만에 따분하고 지루하게 보냈다. 다음주부터는 돈이 아니라 나에게 주어진 시간을 좀더 발전적인 방향으로 소비해 봐야 하겠다…

    

설정

트랙백

댓글

[Flash Player10] 의 GPU 서포트 기능에 관하여...

Programming/ActionScript 3.0 2008. 5. 24. 12:27
Flash Player10 의 GPU 서포트에 대해 Flash Player 팀의 스페셜리스트 Tinic이 blog에서 설명하고 있다.(What does GPU acceleration mean?)

Flash Player10에서는 direct 와 gpu 모드가 새롭게 추가된다.

•    direct 모드 : 화면에 최단 패스로 표시 하고 싶을 때에 사용한다.이 모드에서는 브라우저가 표시하는 영역과 Flash Player의 표시 영역이 겹쳐도 대체로 브라우저 측이 무시된다고 한다. 주로 비디오 재생에서 사용될 것으로 보인다.
•    gpu 모드 : 그래픽 카드의 기능을 이용해 오브젝트의 합성을 실시한다. 대부분의 무비 클립의 랜더링은 기존의 방식대로 소프트웨어가 처리한다.
이러한 GPU 서포트 모드를 이용하기 전에 우선 아래와 같은 사항을 주의해야 한다고 한다.
그래픽 카드의 기능을 사용했다고 반드시 랜더링이 빨리 되는 것은 아니다. 오히려 늦어지는 경우가 더 많을 가능성도 있다고 한다. GPU의 효과를 끌어 내려면 컨텐츠를 디자인할 때 GPU의 동작을 이해해 거기에 맞추어 설계할 필요가 있다고 한다. 그것을 위한 정보나 전용의 가이드는 가능한 한 빠른 시기에 제공할 수 있도록 할 것이라고 이야기 한다.

flashPlayer10에서는 아직은 시작 단계인 기능들이 새롭게 추가되고 있다. GPU기능은 아직은 시기상조이지만 앞으로 플래시의 성능을 높이는데 큰 역할을 할 것이라 본다. FileReference 또한 플래시가 서버와의 통신에 제한적이었던 부분을 좀더 자유로운 개발이 가능하도록 하고 있다.

New Text Engine이나 Text Layout Components 들은 html상의 레이아웃을 플래시 안에서 TextField로 구현이 가능할 것으로 본다. 다만 한글의 경우도 제대로 표현되기를 바란다.

이러한 성능의 발전 방향을 볼때 앞으로 플래시가 온라인과 오프라인의 경계를 무너뜨리는 크로스어플리케이션을 만드는 프로그래밍 언어의 중심이 될 수 있을 것으로 본다.
    

설정

트랙백

댓글

사용자 경험과 관계- Powers of Information

User Interface/Web 2008. 4. 13. 04:15
일본의 한 미술관 매점 단말용 컨텐츠로 제작된 사이트라고 한다. 단말기의 최소 해상도가 1920x1080이기 때문에 그 이하 해상도에서는 짤려서 보이고, 로컬에서 서비스되기 때문에 로딩 처리가 되지 않아서 이미지가 뜨기까지는 약간의 시간이 필요하다.

심플한 디자인과 절묘하게 어울리는 효과음이 전체적으로 사이트의 느낌을 살리고 있다. 가장 훌륭한 점은 정보 설계로부터 플래시 컨텐츠의 효과를 1:1로 적절히 사용했다는 점이다.

사용자 경험은 관계에 영향을 많이 받는다고 생각한다. 여기서 관계라는 의미는 연결을 의미하는데, 예를 들면 화면 밖에 있는 오른쪽 이미지를 보기 위해 현재 이미지를 왼쪽으로 밀어서 사라지게 하는 행동은 우리의 머리 속에서 현재 사진과 오른쪽 사진은 보이지 않는 선으로 연결되어 있고 화면에 보이는 사진을 왼쪽으로 보내면 오른쪽에 있는 사진이 나타날 것이라는 추측에서 비롯된다. 이 사이트의 경우도 뎁스의 트리형태 정보구조를 표현함에 있어서 틀 속에 틀이라는 형태로 진행하고 있어서 정보의 전달이 명확하다고 볼 수 있다.

다만 아쉬운 점은 각 뎁스별 현재 위치(컨텐츠 그룹명)에 대한 정보 전달이 화면 모션으로만 이루어지고 있어서 사용자가 기억하고 있어야 한다는 점이다. 왼쪽의 Power of Information 텍스트를 일률적으로 할게 아니라 각각의 뎁스에 따라 정보구조명을 적용했더라면 하는 생각이 든다.

http://kiki.ex.nii.ac.jp/powers_of_information/

사용자 삽입 이미지

    

설정

트랙백

댓글

즐거운 만남 플래시 컨퍼런스....

Project/Programming 2008. 4. 8. 05:43
4월 5일, 땡굴이 형님이 운영하시는 액션스크립트 까페에서 1차 컨퍼런스 행사가 있었다. 집요한 문군애절한 부탁에 보헤형과 함께 스피커로 나서긴 했으나 이런 행사에서 스피커로 서는 것이 처음인지라 무엇을 어떻게 준비를 해야 할지 난감했다.

일단 ‘무엇을’ 준비해야 하는가에 대한 고민을 오래 한 것 같다. 무엇이든 일단 시작해 보자는 생각에 프리젠테이션을 위한 프리젠테이션 템플릿을 만들기 시작했다. 무엇보다도 내가 알고 있는 일의 작업 스타일에 대한 이야기를 하는 것이 설명하기도 편하고 오시는 분들도 도움이 될 듯싶었기 때문이다.

일단 무엇을 만들 것이라는 것이 결정되고 일주일 정도 지났을 때, 나는 작업량의 절반 정도를 진행하고 있었다. 그러던 어느 날 작업하던 flashDevelop 패키지 파일이 열리지가 않아서 각각 클래스들을 열어 봤더니 총 7개 정도의 클래스 파일이 깨져서 열리지 않거나 다른 클래스 소스와 짬뽕이 된 코드가 눈앞에서 펼쳐져 있더라는….쿨럭…

외장하드에 자료를 보관하고 있었는데 외장하드의 물리적인 트랙 에러가 발생한 듯싶었다. 일단 살아 있는 코드를 다른 하드에 저장 했다. 소실된 클래스들을 다시 만들 생각하니 힘이 쫙 빠졌다. 문제의 클래스(총 3개 정도는 파일이 열리지 않았었고 4개 정도의 파일이 회사 작업 클래스 코드들과 얽혀 있었다)들을 작성하는 데는 3시간 정도의 작업 시간이 걸린 것 같다.(했던 작업을 다시 하는 것인지라 3시간이 길게 느껴지긴 했다.)

사용자 삽입 이미지사진출처 : 문군


아무튼 그런 우여곡절 끝에 프리젠테이션 템플릿은 완성이 되었다. 하지만 이제는 ‘어떻게’가 문제였다. 어떤 내용으로 이것을 잘 포장하여 이야기를 풀어야 하는지는 생각조차 하지 않았기 때문에….

결국 내용은 평소에 보던 책과 인터넷을 헤집고 다니면서 얻은 자료들을 토대로 준비하게 되었다. 마지막 날에는 감기몸살까지 찾아와서 고생을 좀 했으니 내가 할 수 있는 노력은 어느 정도 했다고 생각하는데 이런 발표자의 마음이 전달 되었는지는 잘 모르겠다.

사실 컨퍼런스에 오신 분들의 작업 스타일, 하는 일에 대해서 충분히 고려하지 못했다는 생각이 든다. 너무 내 안에 있는 이야기만 일방적으로 한 것은 아닌가 하는 아쉬움이 남는다.

발표가 끝나고 1차, 2차, 3차까지 달렸는데, 살인적인 입담을 소유하고 있는 진우와, 앞 테이블(나에게는 뒷 테이블이어서 다행이었다. 쿠쿠) 연인의 행각에 어쩔 줄 몰라 하시는 땡굴이 형의 모습에 새벽 첫차를 타고 집에 도착할 때까지 턱이 아프도록 웃었다.
사용자 삽입 이미지사진출처 : 문군사용자 삽입 이미지사진출처 : 문군

다시 한번 궂은 일 마다하지 않고 컨퍼런스를 준비해 준 땡굴이형님과 그 아이들(문군포함 스텝님들)에게 고마움을 전한다. 그리고 결코 가볍지 않은 행사 후원을 해주신 단군소프트 관계자 분에게도 감사하다는 말을 전하고 싶다.

사용자 삽입 이미지사진출처 : 문군



비록 발표는 아쉬웠지만 내가 할 수 있는 일은 마무리하는 것이 좋을 것 같아서 컨퍼런스 때 발표했던 프리젠테이션 템플릿 소스와 UML등을 압축하여 올려 놓는다. 시간에 쫓기며 진행한 작업이니 잘못 된 부분도 있을 수 있고 좀더 최적화 해야 하는 부분에서 쉽게 쉽게 진행한 부분도 있으니 이해를 바란다.

다시 한번 노파심에서 말씀 드리지만 이 자료는 OOP 개념에 대한 이해의 목적으로 만들어진 자료이기 때문에 완벽하지 않을 수 있다. 하지만 OOP를 처음 접하거나 느낌이 슬슬 오기 시작하신 분들에게는 조금이나마 도움이 될 수 있지 않을까 싶다.

아무쪼록 사회생활을 준비하고 열심히 공부 하려는 후배들에게 플래시가 즐거운 공부와 놀이가 되었으면 한다. 파이팅~ ^^

ActionScript발표자료.alz

ActionScript발표자료.a01

ActionScript발표자료.a00


사용자 삽입 이미지



    

설정

트랙백

댓글

Flickr API UML - as3flickrlib

Programming/ActionScript 3.0 2008. 1. 28. 14:57

Project Page: http://code.google.com/p/as3flickrlib/
Project Group: http://groups.google.com/group/as3flickrlib

위 구글 코드에서 오픈되어 있는 flickr API adobe 소스를 UML로 변환해 보았다. 필요하신 분들은 참고하시면 좋을 듯 싶다. 기본적인 상속과 합성관계만 형성해 놓은 상태, 대부분 합성으로 페키지가 구성되어 있다.

참고. 새벽에 작성한 관계로 틀린 부분이 있을 수 있음.










사용자 삽입 이미지

    

설정

트랙백

댓글

[AS3] CurvePointMotion

Project/Programming 2007. 11. 30. 00:55
    

설정

트랙백

댓글

Variable Notation for ActionScript

Programming/ActionScript 3.0 2007. 11. 7. 21:55

 플래시 액션스크립트 언어가 3.0으로 접어들면서 변수명 지정에 있어서 스스로 한계를 느껴서 변수명 표기법을 만들어 보았다. 기본적인 규칙은 헝가리안 표기법에 따랐으며 플래시의 특성에 맞는 타입들은 플래시 액션스크립트에서 권장하는 접미어를 사용 하였다.

 

사실 아래 이미지와 같이 표기법을 만들어 놓았지만 지금은 이와 같이 변수명을 지정하지 않고 있다. 이 테이블에서는 Scope 형태를 표기하기 위해서 g_, m_, l_, p_ 접두어를 사용하였는데, ActionScript 3.0으로 접어들면서 글로벌 변수의 개념이 불명확해 졌으며 접두어를 사용할 경우 변수명을 볼 때 한번 더 생각을 하게 만들기 때문에 읽기 어려운 점도 있는 듯하다. 그래서 이 테이블을 만들어 놓고도 사용하는 방법은 다음과 같다.

 

g_를 사용하는 글로벌 변수 표기는 제거 하고 클래스 속성변수(멤버변수)의 경우에는 _를 사용하며, 로컬 변수의 경우는 _를 없앴다. 그리고 파라미터로 넘겨받은 변수의 경우는 로컬변수에 포함하여 _가 없는 변수명을 하도록 했다. 따라서 이러한 표기법을 사용하면 아래와 같은 형태를 취한다.


package{
        public class VariableNotation extends Sprite{
                // ----------------- properties ---------------//
private var _strMsg:String; private const COUNT:int = 12;    // 상수는 대문자 표기
   // ----------------- Methods ----------------// public function VariableNotation():void{ _strMsg = “멤버변수 표기법”; initStart(); // 메소드는 대문자로 단어를 구분 } private function initStart ():void{ var strMsg:String = “로컬변수 표기법”; trace(“_strMsg : ”+_strMsg, “strMsg : ”+strMsg); } } }

표기법은 개인의 취향에 따라 다양한 형태를 나타낼 수 있지만 그때 그때 다른 표기법은 자신은 물론 다른 사람이 코드를 분석할 때도 어려움을 줄 수 있을 것 같다. 딱히 표기법이 없는 분들에게 권유해 본다.

사용자 삽입 이미지


    

설정

트랙백

댓글

[AS3] CenterPoint 클래스 예제

Project/Programming 2007. 10. 5. 18:39
표시 오브젝트들이 상속하고 있는 DisplayObject 클래스에는 globalToLocal(point:Point):Point 와 localToGlobal(point:Point):Point 메소드를 지원하고 있다. 이를 통해서 DisplayObject의 특정 좌표로 중심점을 이동하는 클래스를 테스트 해 보았다.

아래 예제에서는 rotation을 하고 있는 rectangle의 특정 좌표 점을 클릭하게 되면 DisplayObject의 중심점을 이동하며 한번의 클릭당 해당 오브젝트의 scaleX, scaleY를 각각 0.05 값만큼 증가시키도록 해 놓았다.

이는 실질적으로 표시 오브젝트의 중심점이 이동하는 것이 아니라 local 좌표와 global 좌표간의 gap에 따라서 위치 이동하는 것으로, 생성한 CenterPoint에 있는 get, set 메소드인 rotation 메소드를 통해서 로테이션이 컨트롤 되며, scaleX, scaleY의 값 또한 CenterPoint 클래스에 작성한 메소드를 통해서 컨트롤 되도록 되어 있다.


    

설정

트랙백

댓글

[스크린세이버] 바람과 데스크탑

Programming/Etc 2007. 9. 19. 04:16
웹 서핑중 재미있는 스크린세이버가 있어서 소개한다. 사내 프로젝트 일환으로 작업 했다고 하는데 발상이 재미있다. 플래시 AIR을 이용하여 데스크탑의 이미지를 비트맵데이타로 크롭하여 모션 효과를 준 듯하다. AIR을 이용하면 다양하고 기발한 결과물들을 만들 수 있지 않을까 싶다. 3.0에 어느정도 익숙해 지면 취미로 AIR도 접해봐야 겠다...

이 스크린세이버는 재미있기는 하지만 컴퓨터가 쉬어야할 시간에 너무 많은 일을 하고 있다. 화면 보호도 중요하지만 CPU가 너무 바쁜거 아닌지...

스크린세이버 제작자
프로그램 전반:키타무라 케이태
디자인/플래시:하나무라 타로
원안:사카이회리가
디렉션:나카무라 이사무오

프로젝트 임시 홈페이지 : http://scr.sc

트라이얼 버전 프로그램 :



    

설정

트랙백

댓글

[AS3] BitmapData.lock and unlock 기능

Programming/ActionScript 3.0 2007. 9. 3. 09:45
BitmapData에 있는 lock/unlock 메소드는 레퍼런스에 기능이 명시 되어 있지만 짧게 설명되어 있어서 지나치기 쉬운 것 같다. 아래는 레퍼런스에 나와 있는 내용이다.

public function lock():void
언어 버전 :     ActionScript 3.0
Player 버전 :     Flash Player 9
이 BitmapData 객체를 변경할 때 BitmapData 객체를 참조하는 어떤 객체(예: Bitmap 객체)도 업데이트되지 않도록 이미지를 잠급니다. 성능을 높이려면 setPixel() 또는 setPixel32() 메서드를 여러 차례 호출하기 전후에 이 메서드를 unlock() 메서드와 함께 사용합니다.

레퍼런스의 내용만으로는 정확히 어떠한 역할을 하는지 알기 쉽지 않다. lock 메소드는 BitmapData의 정보를 화면에 draw하는 처리과정을 일시적으로 사용하지 않도록 하여 불필요한 처리과정을 제거함으로써 퍼포먼스를 향상시킬 수 있다. 예를 들면

보통 BitmapData를 처리하기 위해 addChild(new Bitmap(bitmap))와 같이 addChild한 이후에 setPixel() 또는 setPixel32() 메소드를 사용하는 경우가 많은데, 이때 setPixel() 또는 setPixel32()와 같은 메소드는 그 메소드 자체 처리만으로도 addChild 되어 있는 경우 화면에 draw하는 기능을 함께 처리해 버린다. 따라서 addChild되어 있는 BitmapData에 setPixel() 또는 setPixel32() 메소드를 여러 번 사용하여 복잡한 처리를 할 경우에 setPixel() 또는 setPixel32() 메소드를 호출될 때마다 화면에 draw 하기 때문에 불필요한 CPU 처리를 하게 되는 것이다.

물론 setPixel() 또는 setPixel32()메소드의 처리 과정을 화면에 표시해야 하는 경우라면 별로 효력이 없겠으나 setPixel() 또는 setPixel32() 메소드를 여러 번 처리한 이후 결과만을 화면에 표시할 경우는 lock 메소드를 통해서 화면에 표시하는 기능을 잠그고 일련의 처리를 완료한 이후에 unlock 메소드를 통해서 잠근 기능을 풀어주면 불필요한 처리를 하지 않으면서 화면에 처리한 결과를 표시할 수 있다.

아래 예제를 돌려보면 lock/unlock를 사용하지 않았을 때와 사용했을 때의 차이를 확인 할 수 있다.

lockTest(700, 700);

function lockTest(w:uint, h:uint) {
var bm:BitmapData = new BitmapData(w,h);
addChild(new Bitmap(bm));

trace("lock/Unlock 사용 안함 : "+drawBitmap(bm) + "ms");

bm.lock();
trace("lock/Unlock 사용 : "+drawBitmap(bm) + "ms");
bm.unlock();
}
function drawBitmap(bm:BitmapData):uint {
var start:uint = getTimer();
var w:uint=bm.width;
var h:uint=bm.height;

for (var x:uint=0; x < w; x++) {
for (var y:uint=0; y < h; y++) {
bm.setPixel(x,y,Math.random()*0xFFFFFF);
}
}
return getTimer() - start;
}

// output
lock/Unlock 사용 안함 : 214ms
lock/Unlock 사용 : 157ms

output 결과는 시스템에 따라 다소 차이가 있을 수 있는데 테스트한 컴퓨터 스펙은 아래와 같다.

소니 바이오 노트북 VGN-SZ18LP
Genuine Intel® CPU T2400 @ 1.83GHz
메모리 1.50GB RAM

    

설정

트랙백

댓글

[AS3] SelectArea, DrawShape and Sewing

Project/Programming 2007. 8. 31. 18:30
예전에 http://www.tileui.com/ 사이트를 보면 스테이지 상에 있는 복수의 오브젝트를 선택할 때 직사각형으로 선택하는 것이 아닌 draw 형태를 이용하여 필요한 요소만 선택할 수 있다. 이 것을 보고 그려진 Shape를 통해서 선택할 수 있도록 하면 되겠다 싶어서 구현해 봤다.

일단은 클래스의 구조는 아래와 같이 작성했다.

DrawShape.as
이 클래스는 Point 요소를 가지고 있는 Array를 전달하고 그것을 통해 그려진 Shape를 돌려주는 클래스

Sewing.as
이 클래스는 Point 요소를 가지고 있는 Array를 전달하고 그것을 통해 외각선을 그려주는 클래스

SelectArea.as
이 클래스는 DrawShape와 Sewing클래스를 통해 그려진 Shape에 걸쳐진 오브젝트들을 Array로 반환하는 메소드를 가지고 있다. 여기에는 마우스를 UP을 했을 때 Event를 dispatch하게 되는데 이벤트를 받는 메소드에서 기존의 array 요소 중에서 선택된 오브젝트 요소를 가지고 있는 새로운 배열을 참조할 수 있게 하였다.

아래 예제에서는 랜덤한 위치에 생성한 오브젝트들을 마우스 down and drag, up을 통해서 선택을 하면 대각선 방향으로 정렬하게 해놨는데 대각선으로 정렬되는 것은 일정한 규칙이 있는 것은 아니고 디테일하게 하기 귀찮아서 그냥 되는대로 정렬해놨다…쿠쿠 목적이 없는 예제는 슬슬 힘이 빠진다는..;;

    

설정

트랙백

댓글

플래시 게임 Budapest defenders

Programming/Etc 2007. 8. 26. 19:15
게임 장르를 잘모르지만 이런 장르를 전략시물레이션 게임이라고 하지 않나 싶다. 간단한 스토리지만 플래시 전략 보드게임으로서는 매력적이다.













http://alt.tnt.tv/tntoriginals/thecompany/budapestdefenders/index.htm

사용자 삽입 이미지





    

설정

트랙백

댓글

[AS3] 지원하는 신기능 Best 10

Programming/ActionScript 3.0 2007. 8. 14. 13:03
1. 복수의 변수의 출력이 편하게:trace
인수에 변수를 복수 건네주면 자동적으로 공백으로 구분하여 출력한다. 3.0 이전에도 굳이 필요하다면 trace([a,b])와 같은 방법으로 사용하였었는데 뭐 자체 지원이니…
var a:int = 0;
var b:String = 'hgoe';
trace(a, b); // Output: 0 hoge




2. 요소의 순회가 간단히:for each
이전에는 배열의 요소를 순회하는 것은 다음과 같이 하는 것이 정석이었다.
var len:Number = list.length;
for (var i:Number = 0; i < len; ++i) {
trace(list[i]);
}

하지만 3.0에서는 다음과 같이 사용하면 이런 귀찮은 일이 많이 줄어든다. list 안의 요소가 하나씩 element에 대입되어 loop된다.
for each (var element:Object in list) {
trace(element);
}

3. 솔직하게 쓸 수 있게 되었다:default 인수
다음과 같이 인수를 생략 했을 경우의 default값을 간단하게 지정할 수 있다.
function f(arg1:int, arg2:int = 2):void
{
trace(arg1, arg2);
}
f(3, 4); // Output: 3 4
f(3); // Output: 3 2

4. arguments는 필요없다:가변 인수
trace와 같이 얼마든지 인수를 잡는 함수에서는 다음과 같이 쓸 수 있다. 지정한 인수(여기에서는rest )에 나머지의 인수를 배열로서 받을 수가 있다.
function output(separator:String, ...rest:Array):void
{
trace(rest.join(separator));
}
output(':', 1, 2, 3, 4); // Output: 1:2:3:4
output('.', 'a', 'b', 'c'); // Output: a.b.c

5. 모든 형태를 나타낸다:*
어떤 형태가 대입되는지 모르지만 형태를 지정하고 싶을 경우 기존에는 Object가 이용되고 있었지만 AS3에서는 보다 그 의미를 명확하게 하기 위해서, 「* 」(asterisk)라고 하는 형태 지정을 할 수 있다.
var element:* = list[0];

6. 변경되지 않는 상수:const
한 번 값을 설정하면 실행 중에는 변경할 수 없는 이른바 「상수」를 정의할 수 있다.
public class SelectedEvent extends Event
{
public static const SELECTED:String = 'selected';
}

7. 복수의 루프를 단번에 빠진다:label
다중 루프를 단번에 break 하거나 continue 하거나 할 수가 있게 되었다. switch case 에서 친숙한 라벨을 쓰고 break나 continue를 할 때에 그것을 지정하면 그 라벨에 대해서 동작을 한다.
loop: for (var i:int = 0; i < 2; i++) {
for (var j:int = 0; j < 3; j++) {
if ((i == 1) && (j == 0)) {
break loop;
}
trace(i, j);
}
}
/* Output:
0 0
0 1
0 2
*/
설명:「loop 」라는 라벨을 지정하고 그 안에 상자가 된 루프가 있다. 루프는 최초로 i=0 으로부터 1씩 증가하며 한번 증가할 때마다 j루프를 돌게 되는데 if문을 만나는 순간, break에 의해서loop 라벨로부터 탈출(?!)하여 두 루프를 빠져 버리므로 Output과 같은 결과가 된다. 보통 이러한 형태는 인터프리터언어(순차적 언어)에서 주로 사용되었던 방식이었는데 그 복잡한 흐름 때문에 순차적 언어에서도 꺼려하는 방법이었다. 하지만 간단한 내부 알고리즘에서 활용하면 편할 것 같기는 하다.


8. 프롭퍼티의 존재를 간단하게 확인:in

「a in b 」와 같이 쓰면 b의 안에 프롭퍼티 a가 들어가 있으면 true, 그렇지 않으면 false 반환한다.이것에 이용하면 프롭퍼티 존재를 간단하게 조사할 수가 있다.
var obj:Object = {abc: 1, def: 2};
trace('abc' in obj); // Output: true
trace('ghi' in obj); // Output: false

9. 오브젝트가 특정의 형태인가 간단하게 확인:is
「a is b 」와 같이 쓰면 a가 b와 형태가 같거나 b의 서브 클래스의 인스턴스이면 true, 그렇지 않으면 false를 반환한다. 이것에 이용하면 어느 형태인가를 간단하게 조사할 수가 있다.
var s:Sprite = new Sprite();
trace(s is Sprite); // Output: true
trace(s is DisplayObject); // Output: true
trace(s is String); // Output: false

*instanceof 는 직접적인 인스턴스가 아니면 true를 반환하지 않기 때문에 주의해야 한다.
var s:Sprite = new Sprite();
trace(s instanceof Sprite); // Output: true
trace(s instanceof DisplayObject); // Output: false

10. 예외 없이 캐스트:as

보통 다음과 같이 캐스트 하려고 했을 때 형태가 맞지 않으면 예외가 슬로우 된다.
var s:Sprite = Sprite(new Array());
그러나 as를 사용해 캐스트 하면 형태가 맞지 않는 경우, 예외는 슬로우 되지 않고 그 형태의 디폴트값을 돌려준다.
var s:Sprite = new Array() as Sprite;
trace(s); // Output: null ← 형태 지정으로 null을 반환한다.
var n:Number = new Array() as Number;
trace(n); // Output: 0 ← Number의 디폴트값은 0

    

설정

트랙백

댓글

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

설정

트랙백

댓글

[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));

    

설정

트랙백

댓글

[AS3] Create Number

Project/Programming 2007. 7. 28. 17:34
웹상에서 본 효과가 재미있어서 확장하여 숫자 DisplayObject를 만들어 보았다...

















    

설정

트랙백

댓글

[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] 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] 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] 변수 형태에 관한 이야기

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 라는 결과가 나오는지 개발자가 직감적으로는 이해 하기가 어려운 점이 있다.

    

설정

트랙백

댓글