콜린무크의 「지금부터 시작한다 ActionScript 3.0 - WORLD WIDE TOUR 」

Programming/Etc 2007. 11. 7. 00:54
일본 adobe에서는 세계적으로 저명한 콜린무크의 ActionScript 3.0을 위한 1일 집중 트레이닝(무료)에 참가자를 모집하고 있다고 한다. 이 1일간의 트레이닝에서는 무크의 베스트셀러인 ssential ActionScript 3.0(O'Reilly, 2007)에 근거하고 Flash Player및 Adobe AIR의 프로그래밍에 필요한 기본적인 스킬을 습득한다고 한다.
토픽은 객체지향프로그래밍, 클래스, 오브젝트, 변수, 메소드, 패키지, 조건 제어, 루프, 연산자, 함수, 이벤트 핸들링, 화면상에서의 표시, 프로그램의 컴파일 및 실행 등과 관련된 내용이다.

학습 내용
    * 오브젝트 프로그래밍의 모든 주요 개념
    * 클래스 및 오브젝트의 이해
    * ActionScript 3.0프로그램의 구축 및 기술 방법
    * Flex Builder 2의 개발 환경
    * ActionScript3.0주요 개념의 리뷰

일정 :
2008년1월15일(화)     9:30개장 10:00-19:00     300명
사용자 삽입 이미지

MAX 레퍼런스가 한국에서 개최되지 않았던 것도 아쉬운 마당에 이런 군침 도는 기회조차 일본에 빼앗긴 것 같아서 아쉽다. 하루 동안에 얼마나 많은 지식을 얻을 수 있겠냐고 이야기 할 수도있지만 그 느낌만으로도 충분한 가치가 있는 자리가 아닐까 싶다.

일본에 계시거나 일본에 가는 분들은 신청을 해보시길….

http://www.event-web.net/as3/
    

설정

트랙백

댓글

「Flash Performance Tips Part 1」의 한국어 번역

Programming/ActionScript 3.0 2007. 11. 4. 20:15
「BIG SPACESHIP LABS / Flash Performance Tips Part I」 에서 Flash의 최적화에 대한 이야기를 하고 있어서 포스팅한다. 내용은 번역 과정에서 잘 못된 부분이 있을 수 있으므로 이해가 필요하다. Flash사이트를 최적화를 위해 부드럽게 재생시키려면 93%의 노력과6%의 지식과4%의 땀과2%정도의 butterscotch(버터를 넣은 캔디)가 필요합니다.(영화 「Charlie & the Chocolate Factory」의 대사로부터의 인용 했다고 합니다)
농담은 접어두고, 많은 사람들이Flash Player의 퍼포먼스에 고민을 하고 있지만 사이트를 부드럽게 재생시키기 위해서 당신이 할 수 있는 것이 있습니다. 부드러운 재생을 위해서 우리(BIG SPACESHIP스탭)이 매일 사용하고 있는 수법을 몇 개 소개하겠습니다.

마스크는 안된다
모든 마스크를 사용해서는 안된다는 것은 아닙니다. 마스크가 매우 도움이 되는 것은 이미 아시는 바지요. 그렇지만, 마스크는 재생 퍼포먼스를 떨어뜨리는 원인의 주범입니다. 어떤 대상을 마스크 했을 때 Flash player는 매 프레임 마다 무엇을 표시 하고 무엇을 숨기는지를 계산하고 있습니다. 마스크와 능숙하게 친해지려면 어떻게 하면 좋을까요? 거기에는 조금의 인내와 트릭인 층 구조(예를 들면 표시시키고 싶은 영역 사이즈로 구멍을 뚫은 상위 층을 올려놓고 그것을 아래의 층에 씌운다든가)를 사용하면 퍼포먼스 저하를 막으면서 같은 표시 결과를 얻을 수 있겠지요.

알파 채널 첨부PNG와 비디오에 대해
마스크와 같이 이것도 사용하지 않을 수 없을 때도 있지만 이 때도Flash Player는 알파 아래 부분의 표시 계산 처리를 강요당하고 있습니다. 경우에 따라서 우리는 절반 사이즈의 알파 비디오를 Flash위에서 확대해 사용하기도 합니다.
그리고 알파 첨부의 동영상에 대해입니다만 알파 비디오 대신에 연속된 번호의PNG를 사용하는 방법도 시험하는 가치가 있을 거라고 생각합니다. 대부분의 경우는 비디오 형식이 약간 퍼포먼스가 좋은 듯 하지만 그 때 마다 실험해 볼 가치는 있습니다.

frame rate
여러 가지 논의가 있습니다만 세상에 말하는 「매직 frame rate」같은 것은 없습니다. 우리는25, 30fps로 만들고 있습니다.(내가 알기로는) 그것이 베스트라고 생각하고 있습니다. 우리는 그 때마다 어느 쪽이 보다 좋은가를 테스트해서 결정을 하고 있습니다. 그렇지만 일반적으로 말하면 frame rate가 사이트의 재생 스피드가 저하하는 주된 원인은 되지 않을 것입니다. 아무튼 통상의 사용에서는30fps이상은 별로 추천하지 않습니다. 그렇게 아주 대단한 스피드로 렌더링 시켜도…

cacheAsBitmap 과 BitmapData
cacheAsBitmap을 이용한 벡터의 아이템의 rasterize화는 상황을 선택해 사용하도록 해야 한다. 분명히Flash는 심볼을draw하는 것은 한 번으로  끝납니다. 하지만 심볼을 확대 축소나 회전시킬 때는 결코cacheAsBitmap하지 말아야 한다. 이 때 Flash는 매프레임 마다 렌더링과 캡쳐를 반복하므로 처리가 빨라야할 어딘가가 늦어져 버립니다.
Da Vinci CodeNike Air 의 사이트에서 우리는 보이는 부분의 screen shot를 찍어 그것을 하나의 무비 클립에draw시켜서 screen shot을 애니메이션 시키는 처리를 하고 있습니다. 이것은 많은 엘리먼트를 개별적으로 움직이거나 하는 것보다도 상당히 빠릅니다.이 수법은 꽤 추천합니다.

alpha보다 visible로 하는 편이 좋아

alpha = 0과 visible = false는 실은 전혀 별개입니다. alpha는 대상이 되는 클립의 투명도를 결정하는 것입니다. Visible는 FlashPlayer위에서 실제로 그 클립을 표시 할까, 하지 않을까를 결정하는 것입니다. 만약, 무언가를 비 표시로 설정하고 싶으면 visible프롭퍼티를 사용하도록 합시다.

onEnterFrame 과 setInterval
이러한 처리를 사용했을 때는 각각 onEnterFrame = null;이나 clearInterval(myInterval); 하고, 메모리로부터 클리어 해 두도록 합시다.그것을 하지 않는 채 방치하는 것은 전화의 통화 후에 수화기를 올린 채로 떠나는 것입니다.

수학 연산은 사전에 미리 해둡시다.
표시 직전의 단계에서 싸인 웨이브(※ -1~1를 취하는 파형)을 연산하고 있지 않습니까? 그것은 매회 같은 싸인 커브는 아닙니까? 그럴 때는 수치를 배열 안에 하드 코드 해 둡시다. 사전에 수학 연산을 해 두는 것으로, 직전에 복잡한 처리를 하지 않는 것이 좋습니다. 나는 트윈 시키고 싶을 때에 사전에 배열에 모든 트윈치를 배열에 넣어두고 nextFrame()으로 매 프레임 마다 이동시킨 적도 있습니다.

무음 사운드
우리도 마지막 수단으로서 사용하고 있습니다만 기억해 두는 가치가 있는 수법이라고 생각합니다. 타임 라인상의 독립된 층에 무음의 사운드 파일을 「스트리밍 재생•루프」로 설정해 놓아두면 FlashPlayer는 사운드에 동기 시키려고 하고 자동적으로 프레임을 솎아내 조정해 줍니다.

//////////////////////////////////////////////////////////////////////////////////

위 내용은 「BIG SPACESHIP LABS / Flash Performance Tips Part I」의 내용이다. 이 밖에서 작업자 입장에서 FlashPlayer를 웃을 수 있게 해주는 방법은 여러 가지가 있을 듯 싶다. 현재 생각나는 몇 가지만 추가하고 그 이후 자신이 알고 있는 방법이 있으면 코멘트로 소통했으면 좋겠다.

1.    위에서 visible = false; 로 하는 것은 화면상의 표시 오브젝트에서 제외 되지만 그 안에서 연산하고 있는 처리는 그래도 FlashPlayer의 몫이다. 따라서 visible = false를 적용한 오브젝트 안에서 이루어지는 연산도 멈춰 주는 것이 바람직하다.

2.    for(var i:int=0;i<m_arr.length;i++) 와 같이 for문의 비교연산에서 직접 m_arr.length 값을 취득하는 것 보다 상위에 var l_intLen:int = m_arr.length; 변수를 미리 정의하여 사용하는 것 이 좋다. 이는 for문이 비교연산을 처리할 때 매번 m_arr 배열의 개수를 취득하기 위해서 연산처리를 시도하기 때문이다.

3.    _mcParent._mcChild1._mcChild2; 와 같은 참조를 여러 번 사용할 때는 상위에 var _mcChild2:MovieClip = _mcParent._mcChild1._mcChild2; 변수를 미리 선언하여 _mcChild2를 사용하는 것이 좋다. 이는 .연산자를 통해서 매번 depth 탐색이 이루어 지기 때문이다.

4.    _mcParent[“_mcChild1”]와 같은 참조 보다는 _mcParent._mcChild1과 같은 참조가 빠르다. _mcParent[“_mcChild1”]와 같은 형태로 참조할 경우에는 해시테이블 탐색을 통해서 string의 값을 비교 연산을 하기 때문이다.

5.    onEnterFrame or Timer and Interval과 같은 빠른 속도로 처리되는 function 안에서는 특정 기능을 하기 위한 코드들을 외부 function을 호출하는 형태로 분리 하는 것 보다는 직접 function 안에 쓰는 것이 좋다.(이는 유지 보수와 재 사용상의 문제가 있을 수 있음)

6.    for문을 사용하여 연속된 연산처리를 수행하는 것 보다는 절차지향으로 라인으로 풀어 쓰는 것이 빠르다.(onEnterFrame이나 interval과 같은 function 안에서 for문을 사용하는 것은 치명적이다. 이럴 때는 라인에 풀어 쓰는 것이 좋다)

이 밖에도 많은 테스트들이 있었을 것으로 생각한다. 각자 가지고 있는 노하우가 있으면 댓글을 달아 주길 바란다.

    

설정

트랙백

댓글

ActionScript는 프로그래밍 언어가 아니다.

Programming/Etc 2007. 11. 4. 19:21
인터렉션 UI개발과 그 목적을 위해서 사용하고 있는 ActionScript는 프로그래밍 언어가 아니다. 내 천직으로 생각하고 지금 하고 있는 업무가 그것이지만 ActionScript를 프로그래밍 언어적 차원에서 접근 하는 것에는 한계가 있다고 생각한다.

플래시라는 것은 기술적인 환경이나 배경지식 보다는 아이디어가 중요하다. 이러한 아이디어는 다양한 결과물을 만들어 낼 수 있다. 물론 그 아이디어는 어느 정도의 배경 지식이 있어야 하겠지만 없어도 무방하다. 가령 내가 어떤 비주얼을 보고 머리 속에서 그린 인터렉션을 구현하기 위해 작업에 착수 했다고 하자, 내가 필요로 하는 편리한 기능이 플래시 안에 내제되어 있지 않더라도 자신이 가지고 있는 지식 범위 안에서 찾을 수 있는 길은 있을 것이다. 이것이 플래시를 즐기는 사람들의 즐거움이자 정석이다.

플래시로 작업을 하다 보면 자신도 이 방법이 정석인지 아닌지 알 수 없는 경우가 있다. 그래서 작업이 끝나고도 뒤 끝이 어수선한 경우가 종종 발생하게 되는데, 어찌보면 플래시 작업에서의 정석은 없을 수도 있다. 이미 플래시에 탑재 되어 있는 내장 클래스를 모르더라도 그와 유사한 기능을 하는 것을 만들어 낼 수도 있고 전혀 다른 방법으로 문제를 풀어 낼 수도 있다.

그 과정에서 파생된 또 다른 아이디어는 다시 싹을 틔우고 꽃이 피어나는 결과로 진행 될 수도 있다. 하지만 플래시를 프로그래밍 언어적 개발 마인드로 접근을 하다 보면 정석만이 있으며 그것이 유일한 방법이라는 확신에 사로잡혀서 크리에이티브한 창의를 발휘할 수 있는 여지를 묵살하게 된다.

나는 작업을 하면서 엉뚱하며, 디자인 표현에 맞지 않는 결과물들도 많이 만들어 낸다. 남들 보다 같은 결과물을 얻기 까지 시간이 많이 걸리지만 작업 과정에서 떼 묻은 코드들은 또 다른 나의 아이디어로 언젠가는 도움이 되는 것 같다.

현재 플래시를 공부하고 관심을 갖고 있는 분들은 이러한 즐거움을 느꼈으면 좋겠다. 설계, 개발이라는 단어보다는 디자인이라는 단어가 어울리는 플래시는 프로그래밍 언어가 아니라 크리에이티브 언어이다.

    

설정

트랙백

댓글

[AS3] 텍스트 넘버링....

Project/Programming 2007. 11. 4. 05:38
오랜만에 개인 작업물을 포스팅 하는 것 같다. 이번에는 3개의 클래스를 테스트하는 과정에서 만들어 진 것이다. 하나는 caurina Tweener를 통해 모션 효과를 주었고, 두 번째는 실무 작업에 쓰였던 DZeroNumber 넘버링 클래스, 그리고 세 번째는 이미지를 틀어서 사각 박스 모션을 적용하는 클래스를 사용했다.

화면에서 클릭을 하면 넘버링 효과와 함께 클릭한 위치로 텍스트필드가 이동을 한다. 이동 좌표 모션은 랜덤한 4 point 좌표에 해당하는 Bezier 곡선으로 이동을 하며,  DropShadow 필터의 blurY, blurX, distance, angle 속성 또한 랜덤으로 적용하였다.

텍스트필드가 위로 올라가는 느낌이 나도록 distance와 blurX, blurY속성은 같은 값이 되도록 하였다. 텍스트 모션이 끝나는 시점에서 화면을 BitmapData로 저장하여 사각 박스의 한 면이 떨어지는 효과를 넣었는데 up, down, right, left는 랜덤으로 그때마다 적용을 달리 해봤다.

별 의미 없는 작업이지만 재미있게 놀았던 것 같다…





    

설정

트랙백

댓글

[에디터] Eclipse 플러그인 FDT 3.0

Programming/Etc 2007. 10. 17. 00:14
Flash 5.0 이전에는 특별히 코딩을 위해 따로 에디터를 사용할 필요성을 느끼지 못했다. 하지만 7.0으로 넘어오면서 ActionScript가 강화되었고, 코딩하는데 있어서 플래시 툴 자체에서 지원하는 에디터 화면으로는 불편한 점이 많았다. 그래서 예전에는 플래시 액션스크립트를 코딩 할 때, 주로 sepy를 사용하다가 요즘은 FlashDevelop 프로그램을 사용하고 있다. 둘 모두 무료 소프트웨어 이기 때문에 사용하는 것도 있지만 플래시툴에서 지원하는 에디터보다 사용성에 있어서 편리한 점이 많기 때문이다.

오늘 블로그를 돌아다니다가 Powerflasher.com에서 FDT 3.0 이라는 아주 훌륭한 상용 Eclipse 플러그인이 3.0으로 릴리즈 되었다는 정보를 알게 되었다. FDT는 예전에 땡굴이님이 배타테스터로 블로그에 포스팅 한 글을 읽어보긴 했지만 사용성에 있어서 얼마나 많은 편의를 제공하는지는 잘 알지 못했다.

아래 경로로 접근하면 FDT 사용방법에 대한 동영상을 볼 수 있다.

FDT 3.0 Basic
http://fdt.powerflasher.com/uploads/Media/liveCodeGeneration.htm

FDT 3.0 Professional
http://fdt.powerflasher.com/uploads/Media/formatter.htm

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



    

설정

트랙백

댓글

[AS3] 다이나믹 넘버링...

Project/Programming 2007. 10. 14. 04:13
업무상 다이나믹하게 숫자가 바뀌는 형태가 필요해서 만들어 보았다. 이제 어느덧 내 나이 31살 이다 보니 예전처럼 머리가 잘 돌아가지 않는 것 같다. 정도를 밟아서 코드를 작성하면 될 것을, 에러나면 귀찮다는 핑계로 trace로 대충 찾아 헤매다 보니, 체크해야 할 시작 점과 끝 점을 제대로 파악하지 못하고 건성이다.














    

설정

트랙백

댓글

Flash Player 10 코드네임 Astro

Programming/Etc 2007. 10. 2. 18:28
Astro 코드네임으로 불리고 있는 Flash Player 10의 신기능 중에서 몇 개가 미국 시카고에서 개최한 MAX 컴퍼런스에서 공개되었다는 소개글이 있어서 포스팅한다. 공개된 내용은 아래와 같다.

1.새로운 텍스트 레이아웃 엔진
Astro에서는 향상된 새로운 기능의 텍스트 표현 엔진이 탑재될 예정이라고 한다. 이를 통해서 복수 컬럼의 레이아웃이나 이미지를 자동적으로 감싸는 레이아웃, 그리고 테이블 형식의 레이아웃 등이 가능하게 될 것 이라고 한다.

2. 3D 효과
Flash의 무비 클립을 3D 공간 내에서 취급할 수 있는 기능이 제공될 예정이라고 한다. PaperVision3D나 Away3D등과 같은 엔진이 탑재 되는 것은 아닌 것 같지만 표현의 폭이 다양해짐에 따라서 추가적인 3D엔진에 대한 기능 개선이 있을 것으로 기대되는 대목이다.

3.custom 필터, 브랜드, 효과
Flash Player 8 버전부터 추가되었던 필터기능에서 추가적으로 스스로 작성한 필터나 효과를 사용할 수 있게 될 예정이라고 한다. 필터등의 작성에는 Adobe Image Foundation (AIF) 툴킷을 사용하게 되는데 AIF 툴킷은 프리뷰판을 다운로드할 수 있게 되어 있다. 관심이 있는 분은 아래 경로에서 다운 받아서 사용해 보길 바란다.

(Adobe Image Foundation (AIF) Toolkit@Labs )



Flash Player 10의 릴리즈 시기는 아직 미정이라고 한다.


    

설정

트랙백

댓글

[AS3] Pen 클래스 테스트

Programming/ActionScript 3.0 2007. 9. 14. 12:52
Pen 클래스를 이용해서 드로잉 테스트겸 만들어 봤다. Graphics 객체는 드로잉을 하면 할수록 CPU를 많이 잡아먹는디 Graphics 객체 안에서 어떤 일이 벌어지길에 이런 현상이 발생하는지 모르겠다... 그리는 과정에서 비트맵데이타로 처리해버리면 될거 같은디 귀찮스러워서 그냥 올려 놓는다. 테스트 하시는 분들은 너무 많이 그리지 마셔용...쿠쿠











 
 
    

설정

트랙백

댓글

[AS3] 웹페이지에 코드를 이쁘게 보여주는 AScodeViewer

Project/Programming 2007. 9. 13. 06:43

AScodeViewer 1.0 Beta

개인적으로 플래시 코드를 웹상에 올릴 때 하이라이트를 적용하여 편하게 보기 위해서 만들었다. 만들다 보니 플래시 코드뿐만 아니라 다른 코드의 경우도 xml 파일을 수정하는 것으로 적용할 수 있다.

기능적인 요소
기능적인 요소로는 swf에 외부 변수값(코드파일url, 라이라이트 xml, 스타일 xml, selectable) 값을 전달하여 불러들인 xml과 코드, 그리고 코드를 선택 및 복사가 가능하도록 할 것인지를 지정하는 sable 값을 전달하게 된다. 이로서 AScodeViewer.swf 파일에서 코드 하이라이트 및 스타일이 적용된 AScodeViewer를 볼 수 있다.

외부 변수 값을 전달할 때 주의할 점은 크로스도메인 정책에 따라 도메인이 다른 url 경로에 있는 코드나 xml를 불러올 수 없다는 것이다. AScodeViewer.swf 파일이 있는 위치와 같은 도메인 상에 있는 파일을 불러들여야 한다.


사용성에 따른 기능적인 요소로는 오른쪽 하단에 보면 FullScreen mode로 전환할 수 있는 버튼이 있다. 클릭을 할 경우 전체 풀사이즈 화면으로 코드를 볼 수 있는 기능이다.

사용 방법
AScodeViewer을 사용하는 방법은 아래 제공하는 파일을 다운 받아서 사용하고자 하는 계정에 업로드를 하고 아래와 같이 코드를 웹페이지 html상에 넣어주면 된다.

<object width="700" height="400" >
<param name="bgcolor" value="#242424" />
<param name="allowFullScreen" value="true" />
<param name="FlashVars" value="code=TintColor.as&format=as3.xml&style=style_dark.xml&sable=true" />
<param name="movie" value="AScodeViewer.swf" />
<embed src=" AScodeViewer.swf"  flashvars="code=TintColor.as&format=as3.xml&style=style_dark.xml&sable=true" type="application/x-shockwave-flash" allowFullScreen="true" width="700" height="400" bgcolor="#242424" /></embed>
</object>

위에서 보이는 바와 같이 FlashVar에 해당하는 부분의 변수들에 각각의 파일 및 설정 값을 넣어주면 된다. 위 코드의 경우는 swf파일이 있는 같은 폴더 안에 code, format, style 에 해당하는 파일들이 있는 것으로 가정한 것이다.

하이라이트 및 스킨 적용 방법
코드 하이라이트는 플래시 스크립트 에디터로 많이 사용하고 있는 FlashDevelop 프로그램의 language폴더에 있는 xml 데이터를 그대로 사용하였다. FlashDevelop 프로그램을 사용하는 분은 아래 경로에서 사용하고 있는 하이라이트 xml 파일을 취득할 수 있다.

C:\Program Files\FlashDevelop\FirstRun\Settings\Languages

위 경로에서 보면 AS3.xml, AS2.xml, Jscript.xml 등을 볼 수 있는데 AScodeViewer 1.0 Beta에서 지원하는 xml 형태는 AS3.xml, AS2.xml, Jscript.xml, HaXe.xml 이다. 다른 C++ 이나 Java 등의 코드 하이라이트를 사용할 경우에는 위 4개의 파일 중에 아무 파일이나 열어서 해당 언어에서 사용하는 하이라이트 단어들을 등록하고 다른 이름으로 저장하여 사용하면 된다.

AScodeViewer의 스킨 적용은 제공하는 Style_dark.xml 파일이나 style_light.xml 파일을 열어서 해당 부분의 RGB 색상을 변경하여 스킨을 바꿀 수 있다. 아래 이미지를 보면 style.xml 파일에서 지정할 수 있는 부분들을 표시해 놓았다.

사용자 삽입 이미지


아래는 파일로 제공하는 두 가지 스킨을 적용한 예이다. Style_dark.xml 이나 style_light.xml 파일을 수정하여 원하는 색상을 만들어 낼 수 있기 때문에 적용하는 페이지상의 디자인에 맞게 수정하여 사용하면 된다.
왼쪽은 style_dark.xml을 적용한 예이고 오른쪽은 style_light.xml을 적용한 예이다. 왼쪽의 경우 코드 선택이 안되도록 sable = false 값을 적용하였다.


아래 파일을 다운로드 하여 위에서 설명한 대로 원하는 페이지에 적용하면 된다. 블로그 서비스에서는 “외부 멀티미디”어 등에서 youtube 동영상을 임베드 하는 형태로 적용하면 된다. 주의할 점은 위에서 언급한 바와 같이 AScodeViewer.swf 파일이 있는 곳과 불러오는 파일들의 도메인이 같아야 한다는 것이다(같은 도메인 내의 폴더 구분은 상관없다.)

앞으로 버전업의 경우도 FlashDevelop의 기능을 적용할 생각이다. 시간이 허락하는 대로 업데이트 버전을 올려 놓도록 하겠다. 사용하다가 문제점이 있거나 버그 발견 시에는 아래에 댓글로 남겨주시면 많은 도움이 될 것 같다.


AScodeViewer1_0Beta.zip

    

설정

트랙백

댓글

[FlashCS3] Auto Format 기능 주의...

Programming/ActionScript 3.0 2007. 9. 6. 03:16
코드 100줄 이상 넘어가는 것들은 대부분 FlashDevelop에서 작업을 하지만 그보다 적은 코딩 테스트를 할 경우에는 따로 열기 귀찮아서 FlashCS3에 내장된 스크립트 창을 사용하는데, Flash CS3의 Auto format 기능이 여러 가지로 문제가 좀 있다. CS3에서 ActionScript 3.0으로 버전업 하면서 스크립트 자체 기능은 강화되었다지만 FlashCS3 툴은 완성도는 다소 떨어지는 느낌이다. Sepy나 FlashDevelop 처럼 안되더라도 그에 부합하는 기능 보강은 필요할 듯싶다.

아래 코드의 경우 예상되는 결과값은 9가 되어야 하지만 스크립트 창에 있는 Auto Format 기능을 실행해서 코드를 정렬하고 퍼블리시를 해보면 결과는 엉뚱하게 7이 나온다.



trace(getResult());
function getResult(a:int=1, b:int=2, c:int=3):Number {
return (a + b) * c;
}

Auto Format 기능을 실행하게 되면 return 이후에 나타나는 ()는 리턴값으로 간주하여 ()를 제거해 버린다. 이 때문에 결과로 내보낼 사칙연산 순서가 b*c + a로 되어버린다. 실제로 Auto Format 기능을 실행하면 아래처럼 코드상에서 ()가 제거된 것을 확인 할 수 있다.
trace(getResult());
function getResult(a:int=1, b:int=2, c:int=3):Number {
return a + b * c;
}

간단한 코드의 경우에는 문제가 되는 부분을 찾을 수 있겠지만 덩치가 큰 코드의 경우에는 Auto Format 기능 한방으로 예상치 못한 에러 아닌 에러를 내는 곳을 찾기란 쉽지 않다. 그나저나 FlashDevelop은 왜 Auto Format 기능 안 넣는겨….


    

설정

트랙백

댓글

[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을 통해서 선택을 하면 대각선 방향으로 정렬하게 해놨는데 대각선으로 정렬되는 것은 일정한 규칙이 있는 것은 아니고 디테일하게 하기 귀찮아서 그냥 되는대로 정렬해놨다…쿠쿠 목적이 없는 예제는 슬슬 힘이 빠진다는..;;

    

설정

트랙백

댓글

[FlashPlayer] Adobe Flash Player v9.0.60.184 beta - H.264/HE-AAC지원

Miscellaneous/Etc 2007. 8. 27. 06:37
Adobe Systems는 지난 8월 21일 압축 규격 H.264와 HE-AAC (Hi Efficiency AAC)를 Flash Player에서 지원한다고 발표했다. 현재는 베타판 공개이고 이번 가을에 정식판을 발표할 예정이라고 한다.

베타판은 Flash Player 9 Update Downloads@Labs에서 다운로드 하여 인스톨 할 수 있는데 주의할 것은 기존에 있던 FlashPlayer를 언인스톨하고 설치 해야 한다. H.264가 FlashPlayer에 추가되면 iPod를 재생할 수 있다. H.264/HE-AAC 비디오 재생도 플래시플레이어에서 가능하게 되어 MPEG-4 표준을 따르고 있는 MP4, MOV, 3GP등을 재생할 수 있다고 한다.

현재는 단지 지원한다는 의미로 flv만큼의 퍼포먼스를 기대하기는 어려울 듯싶지만 지원한다는 자체의 의미는 매우 크다고 볼 수 있다. Adobe의 다이나믹 미디어 담당 Mark Randall에 의하면 최신판에서는 그래픽 카드의 하드웨어 가속을 이용할 수 있도록 설계되고 있어 듀얼 코어 프로세스에서 최적화 된다고 한다.

Microsoft는 Silverlight를 통해서 웹비디오계의 흐름에서 Flash의 독점에 도전할 의향인 듯 하다. Microsoft는 이미 MLB.com 등 대기업과 Silverlight 채용을 계약했다고 한다. Microsoft는 현시점에서 H.264의 지원을 이야기하고 있지 않지만 고객의 피드백에 근거해서 지원할 가능성이 있으면 지원할 방침이라고 전하고 있다.

웹비디오 기술의 흐름은 앞으로 웹의 발전 방향의 초석이 될 듯싶다. 메크로미디어가 어도비에 인수되었던 시점은 메크로미디어로서는 절호의 찬스였다는 생각이다. 하지만 어도비가 아니라 구글 쪽에서 메크로미디어를 인수 했다면 어떤 변화가 발생했을까 궁금하다. 간간히 구글이 flash만을 인수하거나 어도비를 인수할 수 있는 가능성에 대해서 조심스럽게 이야기를 하고 있는 듯하다. 어도비가 메크로미디어를 인수할 때 20%이상의 프리미엄이 있었던 것을 감안한다면 인수금이 대단할 것으로 예상된다. 만약 그렇게 된다면 엄청난 이슈가 될 것이지만 그러한 이야기는 구글 쪽에서 서비스 하고 있는 대부분이 FlashPlayer를 통해서 배포되고 있기 때문에 나오는 루머가 아닐까 싶다.

    

설정

트랙백

댓글

플래시 게임 Budapest defenders

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













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

사용자 삽입 이미지





    

설정

트랙백

댓글

[AS3] Head First - OOAD AS3로 변환 두번째

Programming/ActionScript 3.0 2007. 8. 26. 12:11
이전에 포스팅한 기타 검색 프로그램의 두 번째로 객체지향 원리를 살린 cohesive버전을 AS3로 변환하였다. 변환 과정에서 Java에서 제공하고 있는 HashMap의 경우는 AS3로 기본적인 기능만을 하는 HashMap class를 만들었다.

메인 document class에서 inventory. addInstrument() 메소드를 실행할 때, 마지막 파라미터 값으로 new InstrumentSpec(HashMap)을 전달하게 되는데, 이때 HashMap 클래스의 경우 Array을 이용하여 데이터를 테이블 형태로 저장하고 있기 때문에 put과 remove과정에서 하나의 Array를 참조하므로 마지막 데이터만을 저장하게 되어 검색이 제대로 되지 않는다.

이는 addInstrument 메소드를 실행하는 시점에서 참조 형태로 HashMap 데이터 Array를 전달하기 때문에 발생하는 문제다. 이를 해결하기 위해 HashMap에 있는 Array를 복제(clone)할 필요가 생겼다. 그래서 HashMap 클래스 내에 clone() 메소드를 만들어 사용되고 있는 Array를 byteArray로 변환하여 복제하였다.

이 프로그램을 변환하면서 다시 한번 느끼는 건 단순해 보이지만 단순하지 않은, 간결하고 함축적인, 사용자가 사용하기 편리한 것과 개발자의 정신분열 증상은 항상 반비례한다는 것이다. 
Java의 버전업을 통해 지원하고 있는 클래스들을 분석하는 것은 충분히 가치가 있는 일이다. 이미 입증된 알고리즘으로 제작되었기 때문에 AS3로 변환하면 충분히 사용성에서 좀더 나을 방법을 찾을 수 있을 듯싶다.

사용자 삽입 이미지

// FindInstrumentTester.as
package{
import flash.display.Sprite;
public class FindInstrumentTester extends Sprite{

public function FindInstrumentTester():void{
var inventory:Inventory = new Inventory();
initializeInventory(inventory);

var properties:HashMap = new HashMap();
properties.put("builder", Builder.GIBSON);
properties.put("backWood", Wood.MAPLE);
var whatBryanLikes:InstrumentSpec = new InstrumentSpec(properties);

var matchingInstruments:Array = inventory.search(whatBryanLikes);
if(matchingInstruments.length != 0){
trace("Bryan, you might like these instruments:");
var ilen:int = matchingInstruments.length;
for(var i:int=0;i<ilen;i++){
var instrument:Instrument = matchingInstruments[i];
var spec:InstrumentSpec = instrument.getSpec();

trace("We have a " + spec.getProperty("instrumentType") +
" with the following properties:");

var hashMap:HashMap = spec.getProperties();
var jlen:int = hashMap.length;
for(var j:int=0;j<jlen;j++){
var propertyName:String =
String(hashMap.getHashTable()[j].key);
trace(" " + propertyName + ": "
+spec.getProperty(propertyName));
}
trace(" You can have this " +
spec.getProperty("instrumentType") +
" for $" + instrument.getPrice() + "\n---");
}
}else{
trace("Sorry, Bryan, we have nothing for you.");
}
}
private function initializeInventory(inventory:Inventory):void {
var properties:HashMap = new HashMap();
properties.put("instrumentType", InstrumentType.GUITAR);
properties.put("builder", Builder.COLLINGS);
properties.put("model", "CJ");
properties.put("type", Type.ACOUSTIC);
properties.put("numStrings", 6);
properties.put("topWood", Wood.INDIAN_ROSEWOOD);
properties.put("backWood", Wood.SITKA);
inventory.addInstrument("11277", 3999.95,
new InstrumentSpec(properties.clone()));

properties.put("builder", Builder.MARTIN);
properties.put("model", "D-18");
properties.put("topWood", Wood.MAHOGANY);
properties.put("backWood", Wood.ADIRONDACK);
inventory.addInstrument("122784", 5495.95,
new InstrumentSpec(properties.clone()));

properties.put("builder", Builder.FENDER);
properties.put("model", "Stratocastor");
properties.put("type", Type.ELECTRIC);
properties.put("topWood", Wood.ALDER);
properties.put("backWood", Wood.ALDER);
inventory.addInstrument("V95693", 1499.95,
new InstrumentSpec(properties.clone()));
inventory.addInstrument("V9512", 1549.95,
new InstrumentSpec(properties.clone()));

properties.put("builder", Builder.GIBSON);
properties.put("model", "Les Paul");
properties.put("topWood", Wood.MAPLE);
properties.put("backWood", Wood.MAPLE);
inventory.addInstrument("70108276", 2295.95,
new InstrumentSpec(properties.clone()));

properties.put("model", "SG '61 Reissue");
properties.put("topWood", Wood.MAHOGANY);
properties.put("backWood", Wood.MAHOGANY);
inventory.addInstrument("82765501", 1890.95,
new InstrumentSpec(properties.clone()));

properties.put("instrumentType", InstrumentType.MANDOLIN);
properties.put("type", Type.ACOUSTIC);
properties.put("model", "F-5G");
properties.put("backWood", Wood.MAPLE);
properties.put("topWood", Wood.MAPLE);
properties.remove("numStrings");
inventory.addInstrument("9019920", 5495.99,
new InstrumentSpec(properties.clone()));

properties.put("instrumentType", InstrumentType.BANJO);
properties.put("model", "RB-3 Wreath");
properties.remove("topWood");
properties.put("numStrings", 5);
inventory.addInstrument("8900231", 2945.95,
new InstrumentSpec(properties.clone()));
}
}
}
//  Inventory.as
package{
        public class Inventory{
                private var inventory:Array;
                public function Inventory():void{
                        inventory = new Array();
                }
                public function addInstrument(serialNumber:String,
                price:Number,
                spec:InstrumentSpec):void{
                        var instrument:Instrument = new Instrument(serialNumber,
                        price,
                        spec);
                        inventory.push(instrument);
                }
                public function get(serialNumber:String):Instrument{
                        var len:int = inventory.length;
                        for(var i:int=0;i<len;i++){
                                if(inventory[i].getSerialNumber() == serialNumber){
                                        return inventory[i];
                                }
                        }
                        return null;
                }
                public function search(searchSpec:InstrumentSpec):Array{
                        var matchingInstruments = new Array();
                        var len:int = inventory.length;
                        for(var i:int=0;i<len;i++){
                                if(inventory[i].getSpec().matches(searchSpec)){
                                        matchingInstruments.push(inventory[i]);
                                }
                        }
                        return matchingInstruments;
                }
        }

}
// Instrument.as
package{
        public class Instrument{
                private var serialNumber:String;
                private var price:Number;
                private var spec:InstrumentSpec;
                public function Instrument(serialNumber:String,
                price:Number,
                spec:InstrumentSpec) {
                        this.serialNumber = serialNumber;
                        this.price = price;
                        this.spec = spec;
                }
                public function getSerialNumber():String {
                        return serialNumber;
                }
                public function getPrice():Number{
                        return price;
                }
                public function setPrice(newPrice:Number):void{
                        price = newPrice;
                }
                public function getSpec():InstrumentSpec{
                        return spec;
                }
        }
}
// InstrumentSpec.as
package{
        public class InstrumentSpec{
                private var properties:HashMap;
                public function InstrumentSpec(properties:HashMap=null):void{
                        if (properties == null) {
                                this.properties = new HashMap();
                        } else {
                                this.properties = new HashMap(properties);
                        }
                }
                public function getProperty(propertyName:String):*{
                        return properties.getValue(propertyName);
                }
                public function getProperties():HashMap{
                        return properties;
                }
                public function matches(otherSpec:InstrumentSpec):Boolean{
                        var otherHashMap:HashMap = otherSpec.getProperties();
                        var len:int = otherHashMap.length;

                        var hashTable:Array = otherHashMap.getHashTable();

                        for (var i:int=0; i<len; i++ ) {
                                var propertyName:String = String(hashTable[i].key);

                                if (String(properties.getValue(propertyName)) !=
                                String(otherHashMap.getValue(propertyName))) {
                                        return false;
                                }
                        }
                        return true;
                }
        }
}
// HashMap.as
package{
        import flash.utils.ByteArray;
        public class HashMap{
                private var hashTable:Array;
                public function HashMap(hm:HashMap=null):void{
                        if (hm == null) {
                                hashTable = new Array();
                        } else {
                                hashTable = hm.getHashTable();
                        }
                }
                public function put(k:*, v:*):*{
                        var len:int = length;
                        for(var i:int=0;i<len;i++){
                                if(hashTable[i].key == k){
                                        hashTable[i].key = k;
                                        hashTable[i].value = v;
                                        return v;
                                }
                        }
                        hashTable.push({key:k, value:v});
                        return v;
                }
                public function remove(k:*):Boolean{
                        var len:int = length;
                        for(var i:int=0;i<len;i++){
                                if(hashTable[i].key == k){
                                        hashTable.splice(i,1);
                                        return true;
                                }
                        }
                        return false;
                }
                public function getValue(k:*):*{
                        var len:int = length;
                        for(var i:int=0;i<len;i++){
                                if(hashTable[i].key == k){
                                        return hashTable[i].value;
                                }
                        }
                        return null;
                }
                // this function for test
                public function allTrace():void{
                        var len:int = length;
                        for(var i:int=0;i<len;i++){
                                trace(String(hashTable[i].key)+" : "+String(hashTable[i].value));
                        }
                }
                public function getHashTable():Array{
                        return hashTable;
                }
                public function setHashTable(hashTable:Array):void{
                        this.hashTable = hashTable;
                }
                public function get length():int{
                        return hashTable.length;
                }
                public function clone():HashMap{
                        var hm:HashMap = new HashMap();
                        var hashTableBA:ByteArray = new ByteArray();
                        hashTableBA.writeObject(hashTable);
                        hashTableBA.position = 0;
                        var ary:Array = hashTableBA.readObject() as Array;
                        hm.setHashTable(ary);
                        return hm;
                }
        }
}
// Builder.as
package{
        public class Builder{
                public static const FENDER = "Fender";
                public static const MARTIN = "Martin";
                public static const GIBSON = "Gibson";
                public static const COLLINGS = "Collings";
                public static const OLSON = "Olson";
                public static const RYAN = "Ryan";
                public static const PRS = "PRS";
        }
}

// InstrumentType.as

package{
        public class InstrumentType{
                public static const GUITAR = "Guitar";
                public static const BANJO = "Banjo";
                public static const DOBRO = "Dobro";
                public static const FIDDLE = "Fiddle";
                public static const BASS = "Bass";
                public static const MANDOLIN = "Mandolin";
        }
}

// Type.as

package{
        public class Type{
                public static const ACOUSTIC = "acoustic";
                public static const ELECTRIC = "Belectric";
        }
}

// Wood.as

package{
        public class Wood{
                public static const INDIAN_ROSEWOOD = "Indian Rosewood";
                public static const BRAZILIAN_ROSEWOOD = "Brazilian Rosewood";
                public static const MAHOGANY = "Mahogany";
                public static const MAPLE = "Maple";
                public static const COCOBOLO = "Cocobolo";
                public static const CEDAR = "Cedar";
                public static const ADIRONDACK = "Adirondack";
                public static const ALDER = "Alder";
                public static const SITKA = "Sitka";
        }
}



 

    

설정

트랙백

댓글

APE(Actionscript Physics Engine) Class Diagram

Project/Programming 2007. 8. 16. 10:05

기존에 만들었던 APE의 UML에서 Association 표기가 없었던 것을 추가하고 기존에 잘못 되었던 부분을 수정했다. 클래스 소스를 기준으로 작성된 class diagram이므로 정확하지 않을 수 있지만 대체적으로 package를 분석하는데 도움이 될 것 같다.

아래 풀사이즈 jpg이미지와 플래시로 만들어 놓은 파일을 올려놓는다.  






사용자 삽입 이미지





    

설정

트랙백

댓글

[AS3] TextField 길이를 벗어나는 글자는 ...으로

Programming/ActionScript 3.0 2007. 8. 16. 03:13
이 클래스는 인수로 지정한 TextField의 width길이보다 text 내용이 길어질 경우에 뒤에 임의로 "..."을 append 하는 클래스다. static 메소드 형태로 만들려다가 동적으로 TextField의 width 값을 변경할 경우에도 편하게 사용할 수 있도록 만들었다. 실제적으로 동적으로 사이즈를 변경해야 하는 경우가 많지는 않겠지만 브라우저의 사이즈에 따라 유동적으로 TextField의 길이를 변경해야 할 경우에는 유용하게 사용할 수 있을 듯싶다.

아래는 위 클래스를 이용하여 동적으로 TextField의 사이즈를 변경하는 예이다.









아래는 클래스 소스 원본
package jasu.display{
        import flash.text.TextField;
        public class CutTextField {
                private var _tf:TextField;
                private var _t:String;
                public function CutTextField(tf:TextField):void {
                        _tf = tf;
                        _t = tf.text;
                        cutText();
                }
                public function cutText():void {
                        if (_tf.maxScrollH > 0) {
                                _tf.appendText("...");
                                while (_tf.maxScrollH > 0) {
                                        var str:Array=_tf.text.split("");
                                        var len:int = str.length;
                                        str.splice(len - 4,1);
                                        _tf.text=str.join("");
                                }
                        }
                }
                public function setTextField(tf:TextField):void {
                        _tf = tf;
                        _t = tf.text;
                }
                public function getTextField():TextField {
                        return _tf;
                }
                public function set width(w:int):void {
                        _tf.width = w;
                        _tf.text = _t;
                }
                public function get width():int {
                        return _tf.width;
                }
                public function set text(t:String):void {
                        _tf.text = _t = t;

                }
                public function get text():String {
                        return _t;
                }
        }
}
    

설정

트랙백

댓글

[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

    

설정

트랙백

댓글

Flash Player 9 실시간 인스톨 상황

Programming/ActionScript 3.0 2007. 8. 10. 10:52




[Flash] http://www.onflex.org/FP9Counter/FP9Counter.swf



현재 Flash Player 9버전 install 상황, 이 숫자의 개념이 머리 속에 들어오지 않는다.





    

설정

트랙백

댓글

[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] Revive 테스트

Project/Programming 2007. 8. 8. 13:37
Circle 오브젝트를 클릭하여 드레그할 수 있다. 중앙 원은 ImmovableCircleInnerSegment(움직임이 없는 중력방향 Inner)이다.



 





 
 


 


    

설정

트랙백

댓글

[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] 무게 중심축과 질량

Project/Programming 2007. 8. 7. 03:08
검은 바탕화면에서 마우스를 Down하고 있으면 CircleParticle을 생성하게 되는데 갯수는 16개로 한정하였다. 중력에 의해서 아래로 하강할 때 스테이지 밖으로 밀려나는 것들에 대해서는 삭제하였다. 
















    

설정

트랙백

댓글

[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/
    

설정

트랙백

댓글

[AS3] SelectRectangleExample

Project/Programming 2007. 8. 2. 11:47
예전에 마리오클링거만이 만들었던 Marching Ants Rectangle을 AS3 버전으로 수정하고 Object select 기능을 추가하여 MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE,MouseEvent.MOUSE_UP 이벤트를 통해서 오브젝트를 선택할 수 있도록 만들어 보았다. 윈도우 바탕화면에서 처럼 아이콘들을 선택하고 선택한 아이콘들을 이동하는 기능으로 확장 가능할 것으로 생각된다. 오늘은 여기까지만...;;













    

설정

트랙백

댓글

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

설정

트랙백

댓글