Diary2010.06.06 19:52



바쁜 일도 끝나고, 휴가도 다녀 오고 읽고 싶은 책도 읽고 

오랜만에 여유로운 시간을 보내고 있습니다. 공부도 하면서 즐겁게 지내고 있지요.


요즘 Apple 이다, Google 이다,. Adobe 다 여러 가지 이슈들로 재미 있는 상황들이 많이 생기고 있어서 그 덕에 Twitter에 푹 빠져 있습니다. TweetDeck 이란 트위터 클라이언트를 깔아서 컴퓨터에 항상 켜 놓을 정도니.. 그 만큼 재미 있는 이야기 거리가 많이 나오고 있습니다. 


언제 부터인가, 바쁘다는 핑계로 블로그에 대한 관리를 소홀히 하기 시작했습니다. 얼마전에 있었던 "플래시 액션스크립트 컨퍼런스" 에 다녀와서 제 블로그에 의외로 많은 분들이 방문 하고 있다는 사실을 알고 적지 않게 놀라서 잠시 다시 열의를 불태운 적이 있었는데요. 그래서 인지 요즘엔 블로그에 글 쓰는게 많이 조심스러워 집니다. 잘못 된 내용을 전달하는 것에 대한 두려움 때문 일까요? 아니 그 보단 귀찮음 때문인것 같습니다. 


3년전에 공부한 내용을 정리 하려고 작성했던 내용들이 많은 사람들에게 도움이 된다는 기분 때문에 더 열심히 썼던 기억이 있었는데, 요즘엔 제대로 된 내용을 써야 된다는 생각이 앞서 글을 쓰는 것 마져 잊어 버리고 있지 않나 하는 생각이 드네요. 


이렇게 생각만 하면 이 블로그도 오랜 동안 유지 할 수 없을것 같아. 생각이 드는데로, 쓰고 싶은데로 무작정 다시 써 보기로 했습니다. 요즘엔 통 "읽기" 는 많이 하는데 "쓰기"는 업무 메일 빼고는 써본적이 없네요. 지금 생각하면서 타자를 치는것도 영~ 어색하게 느껴 집니다. 그래도 쓰다 보면 뭔가 얻는게 있을 거라는 생각이 드네요.


제 블로그에 공부를 위해, 자료를 찾으려고 방문하시는 분들이 많다. 라고 하더군요. 보시다 궁금한 점이나, 잘못된 점이 있다고 알려 주세요. 그리고 여러 이야기 나눠 보아요~~~



Posted by Flash 동강
Portfolio2010.05.19 23:42

 정말 오랜만에 블로그에 글을 쓰는것 같네요.


 한 동안 애착을 가지고 작업했던 "다음 뮤직 플레이어"가 오픈 했습니다. 기존에 ActiveX 플레이어 기반을 새롭게 플래시 기반으로 바뀌었답니다. 







오픈한지 몇일 안되서 묘~ 한 기분이 들지만, 애착이 가는 녀석이니 만큼 앞으로도 쭉 사랑해 줄 예정 입니다.


플레이어를 만드느라 고생하신 모든 분들 너무너무 수고 하셨습니다.!!


플레이어 도움말 바로가기

다음 뮤직 바로 가기


'Portfolio' 카테고리의 다른 글

새 옷을 입은 "Daum 뮤직 플레이어" !  (0) 2010.05.19
fish  (0) 2008.12.11
i tree  (0) 2008.12.11
Yahweh mini bible  (0) 2008.12.11
Posted by Flash 동강
Actionscript3.02009.02.06 01:14

문서 원본 : AdobeRIA 기술문서


작성된 날짜 : 2009-02
저자 : 강동혁
저자 소개 : Daum communications에서 UI 개발 업무를 하고 있으며, Flash 커뮤니티에서 ‘동강’ 이라는 닉네임으로 활동 중이다. 뭐든지 사용하기 편해야 한다는 생각으로 개발을 하고 있으며, RIA와 HCI에 관심이 많다. 

Blog : www.ddongkang.com

목차
1. 서론 : 왜 Actionscript 3.0 인가? 

2. 본론 : Actionscript3.0을 배워야 하는 이유
  - 향상된 연산속도                          
  - 보다 엄격한 디버깅 기능
  - 크로스 스크립팅
  - OOP를 위한 지원
  - Flashplatform의 언어
  - Flash API와 Display 및 Event

3. 결론 : 다음 편 예고


 Actionscript 3.0 사용해야만 하는가?

 Actionscript 3.0(이하 AS3.0) 소개되고, Flash CS3 나와서 우리에게 정식으로  모습을보여   2 가까이 되었다. 이미 웹에는 AS3.0으로 만든 많은 결과물이 우리의 욕구를 충족해 주고 있다. 웹뿐만 아니라 AIR 이용한 데스크톱 애플리케이션과  밖에 여러 디바이스에서 AS3.0 기술을 느낄  있다. AS3.0 소개되고 나서, 많은 개발자와 디자이너는 코드의 유연함과 AVM2 강력함을 직접 체험하고 더욱  멋진 결과물을 만들  있는 무기를갖게 되었다. 반면에, 여러 가지 이유가 있지만 AS3.0 배우기를 꺼리거나, 어려워하는 사람이 많이 있음을 커뮤니티에서 느낄  있었다. 그래서  기술 문서는 AS3.0으로 Flash 플랫폼 개발을 시작하고 싶거나, AS2.0 사용하고 있지만 AS3.0 배우기를 원하는 디자이너와 개발자를 대상으로 하고, AS2.0 비해 달라진 점과, 강력해진 점을 중점적으로 다루고 Flash CS4 AS3.0 이야기할 것이다.

 

-   AS3.0인가?

 

 커뮤니티에 많이 올라오는   이런 질문이 있다.

Flash 시작하려고 하는데, AS1.0부터 순서대로 공부해야 하나요?

 무수히 많은 댓글이 달리고, 댓글 대부분은 AS3.0으로 시작해도 무방하다는 의견이다. 물론 나도  의견에 전적으로 동의한다. 물론 AS1.0 AS3.0까지 순서대로 공부하면, Actionscript 원리를 습득하고, AS3.0 배우는 것이라  수월해지기는 하겠지만, 시간 투자에 비해 얻는 것은 적다. 그리고 AS1.0, 2.0 비해 AS3.0 달라진 개념이 많아 AS2.0 주로 사용하는 디자이너나 개발자가 AS3.0으로 넘어오지 못하는 이유가 되기도 한다. AS3.0 배우라고 권장하는 사람들은 Java 공부를 하라고 권유하기도 한다.  이유가 AS3.0 컴파일하는 AVM2 JVM(Java Virtual Machine) 기반으로 하기 때문에, 문법 면에서 아주 비슷하다. 더구나 많은 양질의 Java 서적을 시중에서 쉽게 구해   있으니, 아직 국내에 뚜렷하게 AS3.0 대한 기초 개념서가 나오지 않은 상태에는 Java 서적을 보는  현명한 선택일지도 모른다. 물론 Java 대해  안다면 필요 없는 일이다.

AVM

Actionscript Virtual Machine(액션스크립트 가상 머신) Flash player 포함된 Actionscript 만들어진 SWF 재생하는 엔진이다. Java 실행되려면 JVM 있어야 하듯, Actionscript Java 실행되는 원리와 같다. Flash player(AVM) 설치되어 있다면 어느 디바이스라도 SWF 실행할  있다.


    Actionscript
에는 버전이 있다. 다른 언어에도 분명 버전은 존재하지만, 다른 언어에서보다Actionscript에서  부분을 중요하게 봐야 하는 이유는, AS1.0 2.0 같은 런타임(AVM1)에서 실행되지만 AS3.0 AVM2에서 실행되기 때문이다. 또한 AS2.0에서 AS3.0으로 넘어오면서 완전 다른 언어라고 착각할 정도로 문법 구조에서 많은 부분이 바뀌었다. 그래서 AS1.02.0 배우지 않아도 AS3.0    있다. AS3.0 공개된   2년이 지났지만, 아직 많은 사람이 AS1.0 2.0 사용 중이고  상에는 AS1.0, 2.0 시절에 만들어진 SWF 비율이  높은 비율을 차지하고 있다. 하지만  추세는 금방 뒤집어질 정도의 차이다.


 AS3.0 연산 속도가 이전 버전에 비해 최대   빨라졌다는 평가를 받는다. AS1.0 2.0 프로그래머에게 외면 아닌 외면을 받았던 이유도 C Java 비해 연산이 느렸기 때문이다. 하지만 AS3.0 들어와서는  문제가 어느 정도 해소되었다. 속도뿐만 아니라 더욱 강력한 Flash API 기능을 가지고 있다. 하지만  아직까지 AS2.0 사용하는 것일까?  물음에 대한 다양한 이슈가 존재한다.


1.
       
Flash player 호환성에 따른 문제

많은 사용자가 이용하는 서비스는, 모든 사람에게 똑같이 보여야 한다는 점이 최우선고려사항이다. AS3.0 재생할  있는 Flash player 9 보급률이 이미 98% 넘었지만, 아직 Flash player 8 설치된 나머지를 위해 AS2.0으로 작업하는 경우가 있다. 간단한 코딩이나 모션 작업 같은 경우에는 AVM2 컴파일했을  약간의 이익을   있겠지만 익숙하지 않은 AS3.0 사용으로 작업 능률이 떨어질 수도 있다는  단점이다.  보급률 문제는 점점 많은 사람이 Flash player 9 이상을 설치함에 따라 빠르게 해결될  있는 문제다. 

그림1. Flash player 보급률

2.       AS3.0을 다룰 수 있는 사람 부족

AS3.0이 나오고 난 직후에는 Flash 프로젝트에 AS3.0을 도입하길 꺼려했다결과물이 나와도 유지 보수할 인력이 없다는 이유였다하지만 2년이 지난 후 상황은 점점 나아지고 있다여러 책과 커뮤니티 기술 문서 덕에 AS3.0을 사용하는 사람도 많이 늘어났으며덩달아 상당수 프로젝트가 AS3.0으로 진행되고 있다.


3.       AS3.0은 어렵다

AS3.0은 분명 이전 버전보다시작하기 어렵다하지만 원리를 익히고 나면 이전 버전에 비해 휠씬 편리함을 느낄 수 있을 것이다왜 어렵게 느껴질까간단하게 컴퓨터에 있는 부품을 비유해 보겠다. AS2.0까지 객체를 다루고 구현하는 방법은 주로 이미 만들어진 기능을 사용하는 방식이었다예를 들어 이미 만들어져 있는 사운드 카드를 컴퓨터에 설치하는 것처럼, AS2.0는 많은 기능을 손 쉽게 가져다 쓸 수 있었다하지만 AS2.0에서 사운드 카드 자체를 만들 수는 없었다. AS2.0의 기본 기능들을 사운드 카드라 비유했다면 AS3.0의 기본 기능들은 사운드 카드 안에 들어 있는 각각의 부품이다(저항이나다이오드 같은 사운드 카드를 구성하는 부품들). 각각의 부품들로 이미 만들어져 있는 것이 아니라(AS3.0에서 제공되는 Flash API에서는 휠씬 많은 기능을 구현하여 제공한다), 자신만의 독창적인 것을 만들 수 있다. AS3.0을 시작하기 어려운 이유가 바로 여기에 있다부품 종류가 너무 많아 다 외워야 할 것 같은 느낌이 들기 때문이다하지만 뭐든 처음 시작할 때 가장 고생하는 법이다조금만 인내하면서 원리를 파악해 보자그럼 AS3.0이 어느 순간 다르게 보일 것이다 

AS2.0 사용자가 AS3.0으로 넘어오지 못하는(필요성을 느끼지 않아 AS2.0을 사용하는 것은 제외가장 큰 이유는 자신이 잘 하는 AS2.0으로는 간단히 만들 수 있는데문법도 제대로 알지 못하는 AS3.0으로 구현하기가 답답하고 힘들어서일 것이다이 글을 쓰는 나 자신도, AS2.0을 주로 사용하다 AS3.0을 사용했을 때 답답함을 많이 느꼈기 때문에 그 마음을 잘 안다하지만 조금만 고생한다면 몇 종류 안 되는 만들어진 기능이 아니라,마음대로 조절할 수 있는 자신만의 기능을 만드는 즐거움과 더욱 강력해진 Flash API(이미 구현되어 있어서제공되는 객체들)를 직접 느낄 수 있을 것이다.


 AS3.0의 좋은 점을 설명한다고 해서, AS1.0 2.0이 나쁘다는 말은 아니다그 자체로 충분히 좋은 언어다. AS3.0에 비해 구조가 더 직관적이고 이해하기 쉽다는 장점을 가지고 있다세계적인 Flash 아티스트인 Koshua Davis나 Erik Natzke도 작업을 할 때 AS1.0 2.0을 사용한다고 한다그만큼 비교적 쉽고구현이 간편하다하지만 AS3.0은 이러한 AS2.0의 장점을 다 커버하고도 남을 만한 장점을 가지고 있다지금부터  AS3.0  써야만 하는가? 대해 구체적으로 이야기  보겠다.

 

-AS3.0을 배워야 하는 이유

AS3.0이 완성도 있는 스펙으로 나온 계기는 Adobe Macromedia를 인수하면서 유능한 개발자가 많이 Flash 개발에 투입되었기 때문일 것이다. Flash 8 AS2.0 기반의 향상된 언어 스펙으로 런칭되고곧 바로 Adobe 개발자들은 Flash 9에 대한 준비를 하면서 AVM1 스펙으로 갈 수 없다고 생각하였다고 한다. AVM1 스펙으로는 사용자들에게 만족할 만한 속도와 메모리 관리를 제공하지 못하기 때문이었다그리고 결과적으로 AVM2라는 높은 성능을 내는 가상 머신을 만든다.


1.      향상된 연산 속도

기존 Flash 사용자들이 AS3.0이 나오고 난 뒤 가장 기뻐했던 것은 AS3.0의 속도가 놀라울 정도로 향상되었단 소식을 들었기 때문이다. Adobe AS3.0 도움말에는 속도 향상을 다음과 같이 기술하고 있다.

While Actionscript3.0 is not required for content that runs in Adobe Flash Player 9, it allows performance improvements that are available only with the new Actionscript Virtual Machine. Actionscript3.0 code can execute up to ten times faster than legacy Actionscript code

AS3.0만을 가지고 있는 코드(외부 데이터를 가지고 있지 않는 경우)를 실행할 경우 이전 버전에 비해 열 배의 속도 향상이 된다. Flash CS4에서의 AS2.0 AS3.0의 연산속도 비교는 그림 2와 같다.


그림2.

 

그림3 Flash CS4에서의 AS2.0(AVM1)과 AS3.0(AVM2) 수행 시간

 그림 2, 3을 보아 알 수 있듯이 같은 코드를 실행하였을 때, Flash CS4에서 AS2.0 AS3.0은 엄청난 수행 시간 차이가 났다위의 예제를 수십 번 반복했을 때도 결과는 같게 나왔다또한 수행 시간 격차를 줄일 의도로 for문의 수행 횟수를 1000에서 100000으로 올려 보았다. AVM2(AS3.0)에서는 제대로 수행되었지만 AVM1(AS2.0)에서는 그림 4와 같은 경고 팝업 메시지가 떴다.

그림 4 연산이 많은 코드를 실행했을 때 나타나는 경고 메시지

물론 코드와 컴퓨터 상태에 따라 수행 시간 차이는 줄어 들 수 있겠지만, AVM2가 AVM1에 비해 월등히 빠른 속도를 낸다는 것은 의심한 여지가 없는 사실이다또한 AVM2의 향상된 기능을 사용하려면 AS3.0을 사용해야 한다이러한 차이는 AS3.0이 내부적으로 새로운 바이트 코드 명령어를 도입해 객체 추적 시스템 개선자료구조 시스템 개선 작업을 함으로써 가능해졌다.

 

-         객체 추적 시스템 개선

AS2.0에서는 prototype을 사용하여이미 정의되어 있는 MovieClip이나 기타 객체들에 속성 메서드를 추가할 수 있었다코드를 짤 때 아무 곳이나, prototype을 사용하면 뭐든 기존 객체에 메서드를 추가할 수 있어 편리했다하지만 이렇게 동적으로 객체를 정의하는 방법은 굉장히 비효율적이었다. Flash player prototype을 사용했기 때문에 컴파일할 때 알아야 하는 객체 정보를 다시 추적해야 하는 문제가 있었다또한 AVM1에서는 prototype을 사용하든사용하지 않든 모든 객체의 정보 추적을 위한 테이블을 만들어 놓기 때문에 상당한 메모리를 쓰고 수행 속도를 떨어뜨리는 요인이 되기도 하였다그래서 AVM2에서는 기본적인 객체 선언은 정적(뒤에 다루는 봉인 클래스를 참고)으로 하게 했고객체를 선언할 때 dynamic 키워드를 사용해 동적으로 객체를 조작할 수 있는 기능을 남겨 두었다하지만 dynamic 키워드를 사용하는 것은 성능을 저하시키는 요인이 될 수 있다.

 

-         객체의 타입 선언

위에서 언급했듯이 AS2.0에서는 객체가 동적으로 생성되었기 때문에 객체의 타입 유형(런타임 유형)을 선언할 필요가 없었다. AS3.0에서 객체가 정적으로 생각되는 방식으로 바뀜에 따라 런타임 유형을 선언해줘야만 하고이렇게 객체 타입을 선언해 객체의 정보를 AVM에 미리 알려주는 방식은 시스템의 유형 안전성을 높이고메모리를 좀 더 효율적으로 관리하는 데 도움이 된다(AS2.0의 경우 내부적으로동적으로 만들어진 객체의 추적을 위한 메모리 테이블이 필요하다).


2.      더 엄격한 디버깅 기능

 AS3.0에서는 이전 버전보다 엄격한 디버깅 기능 및 런타임 오류 상황을 알려 준다. AS2.0을 사용하면 런타임 오류 상황을 알려주지 않는 경우가 많아서 어떤 이유인지 모르고 SWF가 다운되어 버리거나 메모리가 새는 경우가 있었다하지만 AS3.0의 더 엄격한 디버깅 기능은 어디에서 어떤 오류가 발생했는지 자세히 알려주므로 프로그램의 완성도를 높이는 데 기여하고 있다그리고 Flash player 9부터는 Debug 버전의 Flash player가 제공되어 브라우저에서 실행되는 SWF 파일의 에러를 실시간으로 확인할 수 있다.            


3.      크로스 스크립팅

 크로스 스크립팅이란, A.swf B.swf가 있을 경우 A에서 B를 로드한 후(B A 객체의 자식 객체가 된다) A에서 B.swf 파일의 변수객체속성메서드에 접근할 수 있는 기능을 말한다. AS3.0에서 크로스 스크립팅이 가능해지고 난 후에야 비로소 Flash 프로그래밍의 디자인 부분과 개발 부분을 확실하게 나눠서 처리할 수 있는 기반이 만들어졌다. Flash 콘텐츠를 만들기 위해 디자이너들은 여러 가지 도구를 이용하여 나온 작업 소스를 Flash로 객체화한 후 B.swf라는 파일을 Flash 개발자에게 넘겨 준다디자이너가 넘겨준 B.swf에는 디자이너가 작업한 무수히 많은 객체가 Flash CS3부터 제공된 ‘Linkage’라는 기능을 통해 객체화되어 있다. B.swf를 받은 개발자들은 디자이너들이 만들어 놓은 시안과 네이밍(객체의 이름즉 클래스 이름이다)대로 작업을 하면 된다디자인이 바뀌면 개발자가 fla 파일을 넘겨 줘야 한다거나포토샵으로 만든 디자인 파일을 fla 파일에 임포트할 필요 없이디자이너가 수정한 B.swf를 넘겨 주면 된다개발자들은 Loader로 B.swf를 로드한 후에 약간의 보안 처리만 해 준다면 손 쉽게 디자이너가 만든 객체를 불러와 사용할 수 있다이렇게 각각의 역할을 확실하게 구분해 줄 수 있게 도움을 주는 기능이 크로스 스크립팅 이다또한 중복 데이터 등 라이브러리의 관리 소홀로 인한 SWF의 용량 문제를 피하는 방법이기도 하다또한 따로 작업한 SWF를 하나의 부모 SWF로 로드하여자식 객체처럼 사용할 수 있는 방법을 제공한다.


그림 5. 크로스 스크립팅

 4.      객체 지향 프로그래밍(OOP)을 위한 지원


-  봉인 클래스

 AS3.0을 처음 접한 Java 개발자는 즐거웠을 것이다. Java와 굉장히 구조가 비슷하기 때문이다혹자는 AS3.0에 와서야 비로소 프로그램 언어다운 모습을 갖췄다고 말한다그 이유는 객체 지향 프로그래밍을 위한 다양한 지원을 하기 때문이다우선 AS3.0에서는 봉인 클래스 개념이 도입되었다. MovieClip으로 모든 것을 처리했던 AS2.0에서는 MovieClip이 동적으로 생성되기 때문에 이를 위한 메모리가 추가로 필요했다하지만 봉인 클래스 개념이 도입되면서 dynamic 클래스로 지정하지 않는 한 속성과 메서드를 동적으로 추가할 수 없었다하지만 이 덕에 불필요한 수정에 대해 객체를 보호하고덩달아 메모리 효율을 높일 수 있게 되었다.

- override

  override란 상위 클래스를 상속 받은 하위 클래스에서 상위 클래스의 함수를 변경하여 사용하는 것을 말한다그림 6에서, Parent를 상속 받은 Child override를 이용해 Parent init() 메서드를 재정의하고 있다이렇게 상속에 의한 확장을 할 때에 override를 이용하여 코드의 유연성을 더해주고객체 지향 프로그래밍을 도와 주는 기능이 AS3.0부터 도입됐다. 




그림 6. override  쓰임


-         Package


AS3.0에서는 클래스를 package 안에 정의하여 package로 클래스 경로를 지정한다이 경로는 클래스를 import로 로드할 때 위치 값으로 참조된다. Package 안에는 한 개 이상의 클래스가 존재할 수 없지만 package 밖에는 package 안에 있는 클래스 외의 클래스가 존재할 수 있다하지만 package 밖에 정의된 클래스는 외부에서 접근이 불가능하다그러므로 이러한 특성을 이용해 Singleton(디자인 패턴)을 구현하기도 한다.



5.       Flash, Flex, AIR  모든 Flash 플랫폼의 언어

 AS3.0 Flash Flex 그리고 AIR뿐만 아니라 앞으로 나올 모든 Flash 플랫폼의 기본이 되는 언어가  것이다최소한  언어를 기반으로 하여새롭게 업그레이드되어  것이다언어하나를 배워서 서너 가지를 동시에   있다는 것은 Flash 처음 배우는 사람이나 전부터Flash 플랫폼을 접해 왔던 사람이나욕심이 가는 장점 중에 장점일 것이다.


6.      강력한 Flash API, 달라진 Display 시각 표현 방법 및 이벤트

 AS3.0으로 풀어 낼 수 있는 Flash player API는 정말 다양해졌고이러한 객체들을 화면에 보여 주는 기능을 관장하는 Display 시각표현 방법이 바뀌었다또한 이벤트 핸들링 방식도 더욱 많은 것을 표현하고 조작할 수 있게 바뀌었다이 새로운 기능에 대한 것은 다음 편에 더욱 자세히 다루겠다.


글을 마치면서

지금까지 AS3.0 어떤 점이 달라졌고 이전 버전에 비해 업그레이드된 스펙이 우리에게 영향을 미칠  있는 좋은 점을 중심으로 이야기해 보았다분명 AS3.0 AS2.0 길들어진 사람에게는  나라 언어처럼 보일지도 모른다특히 AS2.0 현란하게 구사 하는 사람일수록 AS3.0 써야 하는 필요성을  느낄 것이다하지만, Flash 도구가 간단한 애니메이션을 만들  있는 도구에서 애플리케이션을 구축할  있을 정도로 발전한 것처럼새로운 것을 익혀서 우리에게 돌아 오는 것은 스트레스가 아니라 좋은 작품과 무한한 상상력일 것이다.

다음 편에서는 AS2.0에서 AS3.0으로 버전이 올라가면서 어떤 점이 달라졌는지 구체적으로 살펴볼 것이다. AS2.0 사용하는 사람들이라면다음 편이 AS3.0 이해하는  도움이 많이  것이다.




Posted by Flash 동강
Actionscript3.02009.01.20 23:49

 커뮤니티의 질문들 중에서 단연 1위를 달리고 있는 "Actionscript 학습법" 에 대해, 오직 제 견해와 경험을 통해 작성해 보려고 합니다.

- Flash MX , Flash 8, Flash CS3, Flash CS4 먼놈의 버젼이 이렇게 많은 건지 많이 혼동 됩니다.
 
시중에 나와 있는 책들을 보면 벌써 CS4가 출시 되었음에도 불구 하고, MX 버젼과 그 이하 버젼의 책들을 종종 보게 됩니다. 당연히 Flash를 처음 시작 해야 겠다고, 다짐하고 서점에 간 분들은 혼동 될 수 밖에 없지요. 보통 액션 스크립트 책은 Flash 라는 제목을 작게 표기 하고 Actionscript를 크게 표기 하기 때문에(?) Flash 8 이라 크게 적혀 있는 책을 고르게 됩니다. 그리고 카페에 와서 물어 봅니다. " Flash 8 책 샀는데, 이걸로 공부 시작 해도 될까요? " 많은 분들이 처음 시작 할때 혼동이 많았을 거라 생각 됩니다. 

 
Flash MX : AS1.0 과 AS2.0 지원
Flash 8 : AS1.0 과 AS2.0 지원 , AS2.0의 스펙이 향상 되었습니다.

Flash CS3 : AS3.0 지원, AS1.0 및 2.0 으로 작업 할 수 있으나, AS3.0 과는 같이 사용할 수 없다.
Flash CS4 : AS3.0 지원, AS3.0의 스펙이 향상 되었습니다.
 

버젼 별로 제공 하고 있는 언어 스펙은 위와 같습니다. 책을 고를 떄는 CS3 이나 CS4 라고 써 있는 것이나, Actionscript3.0 이라고 써 있는 책을 골라야 합니다. 중요한 점은 AS2.0 과 AS3.0 은 완전 다른 문법을 가지고 있는 언어 라는 점 입니다. (비슷한 부분이 많이 존재 하지만 ) AS2.0 에서 업그레이드 한 언어라고 보기엔 Java 와 더 닮아 있는 언어 입니다. 

-무슨 버젼으로 공부를 시작 해야 되나요?
 
 현재 Flash 최신 버젼은 Flash CS4 입니다. 스크립트는 AS1.0, 2.0, 3.0 모두 지원 합니다. Flash는 배우고 싶은데, 어떤 툴 버젼으로 어떤 언어 버젼을 공부 해야 해야 할까요. 

 회사에서 흥쾌히 Flash CS4를 제공해 준다면 Flash CS4로 시작 하는 것이 좋습니다. 언어야 뭐든 다 지원을 하고 있고, 무엇보다 Flash player10 을 지원 하므로 해서 Flash CS4에서만 구현 할 수 있는 다양한 스펙들을 비교적 손 쉽게 사용이 가능 합니다. 여건이 안된다면 Flash CS3를 사용해도 무관 합니다. Flash CS4에 대한 문서 라든지 책이 부족하고, 거의 대부분이 Flash CS3 의 Actionscript3.0 스펙을 기본으로 하고 있기 때문에 Flash CS3후에 추가로 Flash CS4에서 제공 하는 기능을 배우면 됩니다. 
 
 어떤 버젼으로 시작 해야 할까요. 많은 입문자들이 가장 혼동을 일으키고 있는 부분 입니다. Actionscript면 똑같은 Actionscript라고 생각하고 아무 책이나 덜컥 샀다가는 후회 합니다. 
Actionscript는 현재 3.0 버젼 까지 나와 있습니다. AS1.0 , 2.0, 3.0 모두 기본적인 프로그래밍 문법을 따르고 있지만, AS1.0 . 2.0 과 AS3.0 은 큰 차이가 있습니다. AS1.0 과 AS2.0 은 하나의 fla 에서 두 버젼을 동시에 사용가능 합니다. 하지만 AS3.0은 오직 AS3.0 단일로만 사용 가능 합니다. 그 이유는 Actionscript Virtual machine 이라 불리는 엔진이 다르기 때문입니다. AS1.0, 2.0 은 AVM1 을 사용하고 AS3.0 은 AVM2 를 사용 합니다. 

 어떤 언어가 좋다고는 견해 차이가 많지만, 분명한 것은 AS3.0 이 AS1.0,2.0 으로 구현한 것에 비해 훨씬 빠르다는 것 입니다. Actionscript3.0 설명서에서는 순수하게 Actionscript만 실행 시켰을때 AS3.0이 이전 버젼보다 최대 10배 빠른 연산 속도를 가진다고 합니다. 또한 AS3.0 은 Flash CS3 와 CS4 에서만 쓰이는 언어가 아닙니다. 현재 Flex 3, AIR 등에서도 같은 언어 스펙을 가지고 사용 되고 있으며 앞으로 나올 모든 Flash playform에서 쓰이는 언어들은 모두 AS3.0을 기반으로 하여 만들어 질 것 입니다. 하지만, 비교적 스크립트를 공부 하는 초기에 어렵게 느껴지는 부분이 존재 합니다. 하지만 그걸 극복 하면 쉽고, 더 많은 것을 구현하고 만들 수 있는 언어가 AS3.0 입니다.


- Actionscript 를 공부 하려고 하는데 무엇 부터 해야 하나요?
 
많은 분들이 AS3.0, 을 공부 하면서 고생을 많이 하셨을 꺼라 생각 됩니다. 저 또한 AS2.0 을 하다가 AS3.0이 나오고 왕성한 배움에 욕구로 무작정 달려들었지만 완전 "GG" 를 친 적이 하루 이틀이 아니었습니다. 그럼 무엇 부터 해야 하나, 저는 이렇게 하였습니다. 

 
1. Flash CS3 나 CS4 관련 무작정 따라 하기 책을 보고, Flash 툴을 무작정 따라해 보세요. Actionscript를 배우고 싶다고 해서 Flash 와 Actionscript를 따로 쓰는건 아닙니다. 어쩔 때는 툴로 해결 해야 하는 부분도 있고 스크립트로 해결 해야 하는 부분도 있기 때문에 툴에 대한 이해는 필수 입니다. 감이 않오는 분은 2권 3권 계속 따라해 보세요. 
 

2. 툴에 대한 충분히 되었다고 생각 되면 인터넷을 활용하여 AS3.0 에 대한 공부를 시작해 보세요. 인터넷에는 좋은 분들이 아주 쉽게(?) AS3.0 에 대한 강의를 진행 하고 있습니다. 
3. 위의 3 강좌들의 모두 보았고, 이해 했을 정도라면 AS의 기초는 되는 수준이 되었을 것 입니다. 이때 책을 구입 하세요. 책은 언노운님이 친절하게 리뷰를 해 놓으셨으니 참고 하세요. 
Actionscript 책 추천

동강의 AS3.0 기초 강좌
- 쎈님의 Actionscript 강좌 모음 
- 윤훈남님의 AS 동영상 강좌

 

 전 Essential Actionscript3.0 과 Actionscript3.0 Cookbook , 그리고 새롭게 시작하는 플래시 CS3 Actionscript3.0을 추천 합니다. 앞의 두 책은 Flash 를 하는 동안 계속 봐야 할 정도로 방대한 내용을 다루고 있습니다. 그리고 새롭게 시작하는 플래시 CS3 Actionscript3.0 로 그동안 인터넷 강좌로 봤던 개념을 리뷰 하세요. 전체적인 틀을 잡기 딱 좋은 책 입니다. 책은 보는 동안 모르는 부분이 생길 수 밖에 없습니다. 그럴때 마다 Flash 단축키 F1 을 눌러 설명서를 틈틈히 확인 하세요. F1은 없는게 없을 정도로 Actionscript에 대한 모든것을 설명 하고 있습니다. 그리고 검색을 생활화 하세요.

 

4. 책까지 봤겠다. 이제 무서울게 없는 이론을 갖췄다고, 착각의 늪에 빠져 있을 것 입니다. 하지만 지금 부터가 시작 입니다. 지금 까지의 강좌나 책은 혼자서 공부 할 수 있는 체력을 갖게 해 준 것 입니다. 이제 자신만의 프로젝트를 계획해 보세요. 그리고 시작 하세요. 그리고 삽질 하세요. 시행 착오를 겪고, 혼자 힘으로 생각해서 만들고, 시행 착오를 하면 할 수록 실력은 급격히 상승 하는 것을 느낄 수 있을 것 입니다. 그리고 항상 F1 을 살펴보는 습관을 가지세요.

 

Actionscript3.0 은 어렵다고들 많은 분들이 말 합니다. 하지만 어려운 만큼 재미 있습니다. 제가 AS3.0 을 공부 했던 방법이 정답은 아니지만, 새롭게 Flash를 시작하시는 분들이 더욱 많아 졌으면 하는 바람 입니다.

 
 

posted by 동강


  

Posted by Flash 동강
Mashup.OpenAPI2008.12.11 13:18

우선 발급 받은 APIKEY 는 요청을 보낼 때 같이 보내게 됩니다. 

예를 들어 

http://openapi.naver.com/search?key=***&query=go&target=image&start=1&display=10   

위의 URL 에서 전달 하는 변수와 같이 image 검색을 위해서는 꼭 전달해야 되는 변수들이 존재 합니다.

 (출처 : http://openapi.naver.com/page.nhn?PageId=1_15 )
 
1. 요청 URL (request url)
   http://openapi.naver.com/search
2. 요청 변수 (request parameter)
요청 변수 설명
key string (필수) 이용 등록을 통해 받은 key 스트링을 입력합니다.
target string (필수) : image 서비스를 위해서는 무조건 지정해야 합니다. (image 검색 지정)
query string (필수) 검색을 원하는 질의, UTF-8 인코딩 입니다. (검색어)
display integer : 기본값 10, 최대 100

검색결과 출력건수를 지정합니다. 최대 100까지 가능합니다.

한번에 검색을 원하는 양 지정

start integer : 기본값 1, 최대 1000

검색의 시작위치를 지정할 수 있습니다. 최대 1000까지 가능합니다.

'플래시 를 검색 했다면 그 양은 엄청 많은 것입니다. 그때 검색한 양에서 어느부분 부터 출력을 해 줄것인가를 나타 냅니다.

sort string : sim (기본값), date 정렬 옵션입니다.
sim : 유사도순(기본값)
date : 날짜순
filter string : all (기본값), large,
midium, small
사이즈에 따른 필터 옵션입니다.
all : 전체 이미지(기본값)
large : 큰 이미지만 제공
medium : 중간 이미지만 제공
small : 작은 이미지만 제공

샘플 URL
   http://openapi.naver.com/search?key=test&query=go&target=image&start=1&display=10
 

우선 fla 파일을 만들고 Componnent 창에서 TextInput 을 Stage 에 올려 놓습니다. 그리고 name 을 input_txt 라 합니다. 그리고 난 후에 main 이라는 Document class 를 만들고, NaverImageApi 라는 as 파일을 만듭니다. 그냥 생성만 해 놓으시면 됩니다.  

그리고 main.as 와 fla 파일을 연결 합니다. (fla 파일의 Document class 를 main.as 로 지정 합니다. 이 과정을 모르신다면 이글을 참고 하세요. http://blog.naver.com/dongkang0626/130027969217  

이렇게 생성이 끝나고 TextInput 에 검색을 하면 해당 질의를 서버 측에 보내는 작업을 하기 위해 main.as 를 정리 하겠습니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {
  8.                 public function main()
  9.                 {
  10.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  11.                 }
  12.                 private function onInputEnterhandler(ev:ComponentEvent):void
  13.                 {
  14.                         trace("엔터");
  15.                        
  16.                 }
  17.                
  18.         }
  19.        
  20. }
  21.  

 ComponentEvent.ENTER 은 Component 에서 Enter 가 발생 하는지 감시해 주는 이벤트 입니다. KeyboardEvent 를 쓰는거에 비해 코드가 줄어 들지요.ㅎ 위와 같은 작업을 하면 input_txt 에 커서를 올려 놓고 Enter 를 쳤을때 "엔터" 가 출력 되는걸 확인할 수 있습니다.  

추가로 해 줘야 하는 부분은 이미지를 검색할 객체를 만들어 주는 부분 입니다. 위에서 만든 NaverImageAPI.as 를 가지고 검색 쿼리를  보낼 것 입니다. 그러기 위해서는 NaverImageAPI 객체를 생성합니다.

 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {      
  8.                 private var imageloader:NaverImageApi;
  9.                 public function main()
  10.                 {
  11.                         imageloader = new NaverImageApi();
  12.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  13.                 }
  14.                 private function onInputEnterhandler(ev:ComponentEvent):void
  15.                 {
  16.                         trace("엔터");
  17.                 }
  18.                                
  19.         }
  20.        
  21. }

 main.as 에 대한 준비가 끝났습니다. 이제 검색 쿼리를 보내기 위해 NaverImageApi 클래스에 public function 을 선언하여 그 함수를 main.as 에서 사용하는 방식으로 코딩을 해 보겠습니 다.  

 NaverImageApi.as
 
  1. package
  2. {
  3.         import flash.display.*;
  4.         import flash.events.*;
  5.         import flash.net.*;
  6.         import flash.xml.*;
  7.        
  8.                
  9.         public class NaverImageApi extends EventDispatcher{
  10.                 private var mInfo:Object;// OpenAPI 를 쓰기 위한 준비 내용이 들어 있다.
  11.                                     
  12.                 // constructor
  13.                 public function NaverImageApi():void {// 초기화 시킨다.
  14.                                        
  15.                         mInfo={apiURL:"http://openapi.naver.com/search?target=image",
  16.                                         apiKey:"7ad7237d57e7290e8a136d05bfdda2dc",
  17.                                         query:"",
  18.                                         displayNum:10};
  19.                        
  20.                 }
  21.                
  22.                 // main function
  23.                 public function main_loadPage(_page:Number,_query:String):void {// 메인 페이지가 로드 될때 불러와 진다.
  24.                 }
  25.          }
  26. }

우선 mInfo Object 를 정의한 후 쿼리를 날리는데 필요한 변수들을 모아서 저장 합니다. 이때 query 는 input_txt 에서 불러서 쓸 것이기 때문에 빈칸으로 저장 합니다. 그리고 검색 쿼리를 날리기 위한 함수 main_loadPage 를 선언합니다. 여기에서 _page 를 선언 하는 이유 는 이미지 페이지 순서에 따라 다음 이미지나 이전의 이미지를 검색 하기 위한 변수 입니다.  

  1.                 public function main_loadPage(_page:Number,_query:String):void {
    // 메인 페이지가 로드 될때 불러와 진다.
  2.                         var page = _page + 1;
  3.                         api_load(_query,page,mInfo.displayNum);
  4.  
  5.                 }
  6.                
  7.                 // API load function
  8.                 private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  9.                        
  10.                 }

main_loadPage 에 api_load 라는 함수를 콜하고 (검색어, 페이지, 검색갯수) 를 넘겨 줍니다. api_load 함수에서는 이들 변수를 받아와서 URLLoader 를 이용하여 쿼리를 서버측에 보내게 됩니다. 

  1. private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  2.                        
  3.                         var page = _page*_displayNum;
  4.                         var loader:URLLoader=new URLLoader  ;
  5.                         loader.addEventListener(Event.COMPLETE,api_loadComplete);
  6.                         loader.addEventListener(IOErrorEvent.IO_ERROR,api_loadError);
  7.                         var requestURL=mInfo.apiURL + "&key=" + mInfo.apiKey + "&query=" +encodeURI(_query) + "&start=" + page + "&display=" + _displayNum;
  8.                        
  9.                         var request:URLRequest=new URLRequest(requestURL);
  10.                         loader.load(request);
  11.                         //
  12.  
  13.                 }

 URLLoader 와 Loader 의 사용법은 비슷하니 URLLoader 를 모르시는 분은 Loader 라고 생각하셔도 무방 합니다. 
로드가 끝났을때의 이벤트와 api_loadComplete , 에러가 났을때의 이벤트 api_loadError 를 설정한 뒤에 requestURL 으로 위에서 보았던 image 쿼리를 보내는 방식에 맞게  ( http://openapi.naver.com/search?key=test&query=go&target=image&start=1&display=10 )

load 합니다 위에서 mInfo 를 정의한 이유는 requestURL 때문 이었습니다. 

load 가 끝나면

  1. private function api_loadComplete(event:Event):void {
  2.                        
  3.                         trace("api load complete");
  4.                         var loader:URLLoader=URLLoader(event.target);
  5.                         outXMLdata = new XML(loader.data);
  6.                         trace(outXMLdata);              
  7.                         dispatchEvent(new Event(Event.COMPLETE));
  8.                         // 컨테이너에 연결 시킨다.
  9.                        
  10.                 }

이 함수가 실행 되어 보낸 퀴리에 해당 하는 xml 데이터를 받아 오게 됩니다. 그리고 main 함수에 쿼리전송에 대한 응답이 완료 되었다는 것을 알리기 위해  dispatchEvent(new Event(Event.COMPLETE)); 를 사용하여 main 에서 접근 할 수 있도록 정의해 줍니다.

dispatchEvent 를 통해 main 에서 NaverImageApi class 의 이벤트에 대한 접근이 가능해 졌습니다. dispatcherEvent 를 모르시면

이 글을 참고 하세요 http://blog.naver.com/dongkang0626/130031128965 

main.as 는 조금만 수정 하면 됩니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {      
  8.                 private var imageloader:NaverImageApi;
  9.                 public function main()
  10.                 {
  11.                         imageloader = new NaverImageApi();
  12.                         imageloader.addEventListener(Event.COMPLETE, onLoaderComplete);
  13.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  14.                 }
  15.                 private function onInputEnterhandler(ev:ComponentEvent):void
  16.                 {
  17.                         trace("엔터");
  18.                 }
  19.                 private function onLoaderComplete(ev:Event):void
  20.                 {
  21.                         trace("로드끝");
  22.                        
  23.                 }
  24.                
  25.         }
  26.        
  27. }

 imageloader 에 dispatchEvent 를 걸었으니 addEventListener(Event.COMPLETE, function ) 으로 이벤트를 받아 올 수 있습니다.  

이제 xml 을 받아 오는 모든 작업이 완료 되었습니다. main.as 에 대한 완성 코드는 위와 같고, NaverImageApi.as 에 대한 완성 코드는 다음과 같습니다.

 NaverImageApi.as
 
  1. package
  2. {
  3.         import flash.system.System;
  4.         import flash.display.*;
  5.         import flash.events.*;
  6.         import flash.net.*;
  7.         import flash.xml.*;
  8.        
  9.                
  10.         public class NaverImageApi extends EventDispatcher{
  11.                 private var mInfo:Object;// OpenAPI 를 쓰기 위한 준비 내용이 들어 있다.
  12.                 public var outXMLdata:XML;
  13.                        
  14.                 // constructor
  15.                 public function NaverImageApi():void {// 초기화 시킨다.
  16.                                        
  17.                         mInfo={apiURL:"http://openapi.naver.com/search?target=image",
  18.                                         apiKey:"7ad7237d57e7290e8a136d05bfdda2dc",
  19.                                         query:"",
  20.                                         displayNum:30};
  21.                        
  22.                 }
  23.                
  24.                 // main function
  25.                 public function main_loadPage(_page:Number,_query:String):void {// 메인 페이지가 로드 될때 불러와 진다.
  26.                         var page = _page + 1;
  27.                         api_load(_query,page,mInfo.displayNum);
  28.  
  29.                 }
  30.                
  31.                 // API load function
  32.                 private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  33.                        
  34.                         var page = _page*_displayNum;
  35.                         var loader:URLLoader=new URLLoader  ;
  36.                         loader.addEventListener(Event.COMPLETE,api_loadComplete);
  37.                         loader.addEventListener(IOErrorEvent.IO_ERROR,api_loadError);
  38.                         var requestURL=mInfo.apiURL + "&key=" + mInfo.apiKey + "&query=" +encodeURI(_query) + "&start=" + page + "&display=" + _displayNum;
  39.                        
  40.                         var request:URLRequest=new URLRequest(requestURL);
  41.                         loader.load(request);
  42.                         //
  43.  
  44.                 }
  45.                 private function api_loadComplete(event:Event):void {
  46.                        
  47.                         trace("api load complete");
  48.                         var loader:URLLoader=URLLoader(event.target);
  49.                         var dataXML = new XML(loader.data);
  50.                         outXMLdata = dataXML;
  51.                        
  52.                         dispatchEvent(new Event(Event.COMPLETE));
  53.                         // 컨테이너에 연결 시킨다.
  54.                        
  55.                 }
  56.                 public function get xml():XML
  57.                 {
  58.                         return outXMLdata;
  59.                        
  60.                 }
  61.                 private function api_loadError(error:IOErrorEvent):void {
  62.                         trace("api load error");
  63.                                                
  64.                 }
  65.                                
  66.         }// End Class
  67. }

추가된 사항은 get xml() 을 이용하여 받아온 xml 을 접근 하기 위해 함수를 만들었다는 점입니다. 아차! main.as 에서 검색 했을때 NaverImageApi 에 있는 함수를 출력해 주는 부분을 깜박 했네요.  

  1. private function onInputEnterhandler(ev:ComponentEvent):void
  2.                 {
  3.                         trace("엔터");
  4.                         imageloader.main_loadPage(1,input_txt.text);
  5.                 }

검색의 1page 에 해당하는 부분을 로드해 줍니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import flash.events.Event;
  5.         import fl.events.ComponentEvent;
  6.        
  7.         public class main extends Sprite
  8.         {      
  9.                 private var imageloader:NaverImageApi;
  10.                 public function main()
  11.                 {
  12.                         imageloader = new NaverImageApi();
  13.                         imageloader.addEventListener(Event.COMPLETE, onLoaderComplete);
  14.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  15.                 }
  16.                 private function onInputEnterhandler(ev:ComponentEvent):void
  17.                 {
  18.                         trace("엔터");
  19.                         imageloader.main_loadPage(1,input_txt.text);
  20.  
  21.                 }
  22.                 private function onLoaderComplete(ev:Event):void
  23.                 {
  24.                         trace("로드끝");
  25.                        
  26.                 }
  27.                
  28.         }
  29.        
  30. }

 그럼 검색을 해 볼까요? 

위와 같이 이미지 정보를 포함한 xml 이 로드 됩니다. 이 정보들을 이용해서 Loader 를 통해 이미지를 불러 올 수도 있고 여러 가지 재미난 작업들을 할 수 있습니다. 

flickr 이미지 api 를 이용한 예 http://www.pimpampum.net/phrasr/?id=10772

 

Papervision3D 를 이용한 이미지 검색 ( 검색어를 입력 하세요. )

매쉬업에 관심을 가지게 된 계기는 얼마 안되었지만, 하면 할 수록 재미있고 신기 한것들을 만들 수 있는것 같습니다. 물론 직접 서비스가 되는 것도 가능 합니다. 앞으로 여러 매쉬업 하는 방법에 대해 소개 하면서 Flash 를 이용한 매쉬업 관련 컨텐츠가  많이 나왔으면 하는 바램입니다.

Posted by Flash 동강
Portfolio2008.12.11 12:43

Who is 'dongkang'?

 
 

AS3.0 을 처음 접하면서 수업시간에 만들었던 

자기 홍보 배너 입니다.ㅎ

오랜만에 보니깐 기분이 이상하네요.

로컬로 돌리던거라서 사운드와 사진은 나오지 않습니다.

'Portfolio' 카테고리의 다른 글

i tree  (0) 2008.12.11
Yahweh mini bible  (0) 2008.12.11
Who is 'dongkang'?  (0) 2008.12.11
BookSearch  (0) 2008.12.11
Posted by Flash 동강
Portfolio2008.12.11 12:14

 

BookSearch . Mashup
2007.11

  

책 검색 OpenAPI 를 이용한 d_s BookSearch

Flash 를 기반으로 해서 책 검색을 도와 주는 air 어플리케이션 입니다. 네이버의 실시간 책 검색 순위와, 다음의 책검색 API 교보문고의 다음 책 검색과 연계된 쇼핑 api 를 사용하여 Flash 특유의 UI와 다이나믹한 검색 환경을 고려 하여 제작 하였습니다.  

 

 

 

 

Actionscript 3.0 을 배우고 처음으로 제작해 본 어플리케이션이라, 제작 도중 시행 착오도 많이 하였고, SSU-NHN Web professional 과정을 이수 하면서 그전에는 신경을 덜 썼던 UI 부분에 좀더 비중을 두어 제작을 하였습니다. 이미지 로드 시 크로스 브라우징 처리와, Flash 자체의 보안 샌드 박스에서 문제가 발생하여, Flash 보안 처리가 굉장히 불편하다고 투덜투덜 거린게 생각 나네요.

 

 

기능

기본적인 책 검색 기능과, 실시간 인기 도서를 바로 접근할수 있는 기능, 자신이 찾아봤던 책에 대한 History 기능, 고른 책들에 대해 교보문고로 접근하여 구매 하는 기능 등이 있습니다. 
 

제작 하면서

Actionscript 2.0 을 사용하다 새롭게 3.0 이라는 녀석을 사용해 보고 놀랐던 때가 어그제 같은데, 벌써 1년이라는 시간이 지났습니다. 이제 와서 이 소스를 보면 부끄럽기 짝이 없는 코드들 투성이지만, Actionscript 3.0 에 재미를 붙이고, 밤을 새면서 버그를 잡던게 생각이 남니다. Flash 의 화려함에만 현혹되어, 그 동안 사용자 편의성을 무시 하고 있었다는 것을 알게 되었습니다. 화려함과 기능 이전에 존재 해야 하는 것이 바로 사용자 편의 성인데, 이 프로젝트를 개기로 UI 에 대한 생각이 바뀌었습니다. 기술이 있고 사람이 있는 것이 아니라 , 사람이 있어야 기술이 있는 것이고, 아무리 멋지고 좋은 기능을 가지고 있어도, 정작 사용하지 못하면 없는거나 다름 없다는 것을 깨닫게 해 준 프로젝트 였습니다.  

다운 로드

http://mfiles.naver.net/9746a27f6c305ae9c19e/data26/2008/1/24/70/bookload.air

'Portfolio' 카테고리의 다른 글

i tree  (0) 2008.12.11
Yahweh mini bible  (0) 2008.12.11
Who is 'dongkang'?  (0) 2008.12.11
BookSearch  (0) 2008.12.11
Posted by Flash 동강
TAG Air, Flash, RIA, 동강
Mashup.OpenAPI2008.12.11 12:04

매쉬업 경진 대회에 이어 다음 Dev Day 를 갔다 왔습니다. 구현의 목적이 아니라, 여러 사람이 자신의 생각을 공유 할수 있는 장이 된거 같아서 좋았습니다. 푸짐한 아웃백 점심식사와, 푸짐한 경품들,, 코딩하는 동안 삽질만 한거 같지만 즐거운 토요일 이었습니다. 6월에 있을 Dev day 가 또 기다려 지네요.ㅎ  

오늘 다음 Dev Day 2008 에 가서 팀들과 함께 만든 다음 블로그 어플리케이션 입니다. 기존의 다음 블로그를 사용하시는 분이 브라우져를 거치지 않고 자신의 블로그의 정보를 메신져 형태로 알수 있게 해 주는 프로그램입니다. 싸이를 하시는 분이라면 네이트온 메신져의 "새글 알림이" 라고 생각하시면 되겠네요. 아직 구현 단계라 스샷과 메인 소스만 첨부 합니다.ㅎ
Flex ㅋㅋ 하면 할수록 매력 적인데, 쉽지 않네요;;; Flash 하던데로 하면 되겠지 하면서 진행했는데 곳곳에서 삽질 ...

5시간 동안 삽질만 한거 같습니다;; 

 

자신의 블로그 정보를 알려 줍니다. 댓글이 달렷을 경우 위와 같은 창으로 표시해 줍니다.

자신의 블로그에 Posting 하는 창 


 글을 읽어 보는 부분 

 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" width="420" height="541" xmlns:component="component.*" borderColor="#FBFBFB" themeColor="#F7F9FB" horizontalScrollPolicy="off" verticalScrollPolicy="off">
  3.         <mx:Script>
  4.                 <![CDATA[
  5.                 import mx.controls.List;
  6.                 import mx.events.FlexEvent;
  7.                 import mx.collections.ArrayCollection;
  8.                 import mx.containers.VBox;
  9.                 import mx.controls.Text;
  10.                 import mx.core.Container;       
  11.                 import flash.display.Sprite;
  12.                 import flash.events.Event;
  13.                 import data.db.SettingManager
  14.                 import blog.read.ReadList;
  15.                 import blog.read.ReadContents;
  16.                 import blog.read.ReadComment;
  17.                
  18.                 import mx.controls.Alert;
  19.                 import component.LoginPanel;
  20.                 import blog.write.WriteContents;
  21.                 import component.CompleteButton;
  22.                 import blog.login.BlogLogin;
  23.                 import com.adobe.air.notification.NotificationClickedEvent;
  24.                 import com.adobe.air.notification.Purr;
  25.                 import com.adobe.air.notification.AbstractNotification;
  26.                 import com.adobe.air.notification.Notification;
  27.                        
  28.                 public var resultList:XML;
  29.                 public var resultContents:XML;
  30.                 public var resultComments:XML;
  31.                        
  32.                 private var Postwrite:WriteContents = new WriteContents();
  33.                 private var settingManager:SettingManager;
  34.                
  35.                 public var tmpObj:Object;
  36.                 private const iconURL: String = "128_128.png";
  37.                 private var bmp: Bitmap = null;
  38.                 private var count:uint;
  39.                 private var timer:Timer;
  40.                 private var purr:Purr = new Purr(1);
  41.  
  42.                
  43.                 private function init():void
  44.                 {
  45.                         settingManager = new SettingManager();
  46.                        
  47.                         tmpObj = new Object();
  48.                        
  49.                                
  50.                         login_mc.addEventListener(MouseEvent.CLICK, onLoginhandler);
  51.                        
  52.                        
  53.        
  54.                
  55.                        
  56.                 }
  57.                 private function completeHandler(evt:Event):void{
  58.                                
  59.                                 bmp = Bitmap(Loader(evt.target.loader).content);
  60.                                 purr.setIcons([bmp.bitmapData], "This is tooltip");
  61.                                 var m: NativeMenu = new NativeMenu();
  62.                                 m.addItem(new NativeMenuItem('Show'));
  63.                                 m.addItem(new NativeMenuItem('Close'));
  64.                                 purr.setMenu(m);
  65.                                 showNoti("새글이 올라왔습니다.");
  66.                         }
  67.                        
  68.                         private function ioErrorHandler(evt:Event):void{
  69.                                
  70.                         }
  71.  
  72.                
  73.                         private function showNoti(str:String):void{
  74.                                 var icon:Bitmap = bmp;
  75.                                 purr.addTextNotificationByParams("DaumDesktop for DevDay", str, AbstractNotification.BOTTOM_RIGHT, 5, icon);
  76.                                
  77.                         }
  78.                
  79.                 private function onSendhandler(evt:MouseEvent):void
  80.                 {
  81.                         Postwrite.contentsWrite(post_mc.title_txt.text,post_mc.contents_txt.text,"tag");
  82.                
  83.                 }
  84.                 private function onLoginhandler(evt:MouseEvent):void
  85.                 {
  86.                         var popLogin:LoginPanel = new LoginPanel();
  87.                         popLogin.x = 90;
  88.                         popLogin.y = 100;
  89.                         addChild(popLogin);
  90.                        
  91.                 }
  92.                 public function onCompleteHandler(event : Event) : void {
  93.                                 var loader:Loader = new Loader();
  94.                                 loader.load(new URLRequest(iconURL));
  95.                                 loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
  96.                         loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
  97.                            
  98.                         timer = new Timer(3000, 1);
  99.                                 timer.addEventListener(TimerEvent.TIMER,
  100.                                         function(e:TimerEvent):void{
  101.                                         purr.alert(NotificationType.INFORMATIONAL, NativeApplication.nativeApplication.activeWindow);
  102.                                         });
  103.                                
  104.                                
  105.                                 resultList = event.target.respond_list;
  106.                                 drawList();
  107.                                 event.target.removeEventListener(Event.COMPLETE, onCompleteHandler);
  108.                         }
  109.                        
  110.                         private function drawList():void{
  111.                                 var kItem:XML = new XML();
  112.                                 for(var i:int = 0;i < resultList.item.length();i++){                                   
  113.                                         var kVBox:VBox = new VBox();
  114.                                         kItem = resultList.item[i];
  115.                                         kVBox.label = kItem.date + " : " + kItem.title + " [" + kItem.commentCnt + "]";
  116.                                         kVBox.width = 400;
  117.                                         kVBox.name = kItem.link;
  118.                                         kVBox.addEventListener(FlexEvent.SHOW,viewPostHandler);                                        
  119.                                         listAccordion.addChild(kVBox);
  120.                                        
  121.                                         if(i == 0){
  122.                                                 getPost(kItem.link);
  123.                                         }                                      
  124.                                 }                                                              
  125.                         }
  126.                        
  127.                         private function viewPostHandler(evt:FlexEvent):void{                          
  128.                                 getPost(evt.target.name);                              
  129.                         }
  130.                        
  131.                         private function getPost(_link:String):void{
  132.                                 if(tmpObj[_link]) return;
  133.                                
  134.                                 var rc:ReadContents = new ReadContents();
  135.                                 settingManager.loadData();     
  136.                                 rc.contentsread(settingManager.name, _link.split("/")[4]);
  137.                                 rc.addEventListener(Event.COMPLETE, onCompleteGetPostHandler);
  138.                                 //trace(_link);
  139.                                 tmpObj[_link] = true;                          
  140.                         }
  141.  
  142.                         private function onCompleteGetPostHandler(event : Event):void {
  143.                                 //trace(event.target.respond_contents);
  144.                                 resultContents = event.target.respond_contents;
  145.                                 var kText:Text = new Text();
  146.                                 kText.text = resultContents.elements('description');
  147.                                 listAccordion.selectedChild.addChild(kText);
  148.                                 event.target.removeEventListener(Event.COMPLETE, onCompleteGetPostHandler);
  149.                                 showNoti(kText.text);
  150.                         }
  151.                
  152.                        
  153.                 ]]>
  154.         </mx:Script>
  155.         <mx:TabNavigator id="tab_mc" x="10" y="34" width="400" height="500">
  156.                 <mx:Canvas id="read_mc" label="Post" width="100%" height="100%">
  157.                         <mx:Accordion id="listAccordion" x="10" y="10" width="379" height="446">
  158.                                
  159.                         </mx:Accordion>
  160.                
  161.                 </mx:Canvas>
  162.                
  163.                 <mx:Canvas id="write_mc" label="Write" width="100%" height="100%">
  164.                         <component:PostEditor id="post_mc"  x="10" y="9"/>
  165.                 </mx:Canvas>
  166.         </mx:TabNavigator>
  167.         <mx:Button id="login_mc" x="354" y="29" label="Login"/>
  168.         <mx:Label x="10" y="8" text="Daum bloger assistence on AIR" fontWeight="bold"/>
  169.        
  170. </mx:WindowedApplication>

 여러 사람이 단시간에 코딩한거라 지져분 하네요.ㅎ 우선은 메인 mxml 만 올림니다.ㅎ
코딩 뿐만 아니라, 여러 가지로 정말 도움이 되는 말씀을 해 주신 GS eshop 의 "오창훈" 님께 감사 인사 드리고 싶습니다. 꾸벅 



Posted by Flash 동강
Mashup.OpenAPI2008.12.11 11:56

여러분들이 생각하시기에 매쉬업 하면 뭐를 생각하십니까? 검색 API ? 지도 API 나사진 API를 조합해서 만든 사이트? 보통 이런 생각을 많이 하고 계실 겁니다. 하지만, 매쉬업이란 것은 이런 좁은 콘텐츠에 한정되지 않은 하나의 흐름입니다. 포털 사이트나, API를 제공하는 사이트에서 제공 되는 API를 쓰지 않았다고 매쉬업이 아니라고 말할 수는 없습니다. 이와 같이 어떤 방법이라고 정의할 수 없는 “매쉬업” 이란 단어는 기존에 이미 존재하는 서비스 및 컨텐츠들간의 조합을 통해 전혀 다른, 새로운 서비스 및 콘텐츠를 생산하는 작업 모두를 말합니다. 그럼 왜 매쉬업을 하는 걸까요? 최근 매쉬업을 이용한 사이트가 점점 늘어 가고 있고, 이러한 추세는 하나의 트렌드로 자리 잡아 가고 있습니다. 왜? 매쉬업의 정의를 다시 보면, 기존의 서비스를 조합하는 행위입니다. 현재 로서는 웹상에 없는 콘텐츠가 없을 정도로 엄청나게 많은 콘텐츠가 존재 하고 있습니다. 어떻게 새로운 것을 창조 할 수 있을까요? 그 길은 매쉬업에 있습니다.

1 + 1 = 2 가 맞지만, 매쉬업을 함으로서 얻어 지는 이익은 2가 되는 것이 아니라, 엄청난 시너지 효과를 나타나게 합니다. 한 가지 예를 들면, 예전에는 대략적인 위치만 나타내고 있었던, 인터넷 부동산 사이트가 최근에는 구글맵이나, 네이버 맵을 이용하여, 사용자에게 더욱 편안한 서비스를 제공하고 있습니다. 또, 개인 블로그의 경우에도, 개인이 만든 매쉬업을 자신의 블로그에 삽입함으로서 많은 홍보 효과를 보이고 있습니다. 이처럼, 일반 사용자들도, API를 제공하는 회사의 거대한 DB를 사용할 수 있고, 그 방대한 자료들을 이용하여 새로운 콘텐츠가 창조 되는 것입니다.

RIA 라고 들어 보셨습니까? 먼 생뚱맞게 RIA 가 매쉬업이랑 먼 상관있냐? 라고 말하시는 분들도 있겠지만, 우선 RIA 란 무엇인가부터 소개 하겠습니다. RIA 란 ( Rich Internet Application ) 부자 인터넷 프로그램입니다. 90년대 말까지만 해도 “웹 브라우징”은 온라인에 접속하여 텍스트를 읽고 정적인 이미지를 보는 것을 의미했습니다. 하지만 이 모델은 한계가 있었습니다. 더 많은 사람과 비즈니스가 웹에 접속하게 되면서 사용자 들은 편한 것을 원했으며 빠른 것을 원했습니다. 그래서 나온 것이 RIA환경입니다. RIA 는 사용자 인터랙션 디자인에서 모범 사례를 추려 내어 Adobe 의 Macromedia® Flash®, HTML 및 JavaScript 와 같은 웹 기반 기술과 결합함으로써 보다 편안한 인터넷 환경을 제공 합니다. 이 RIA 안에 AIR 가 있습니다. RIA를 거꾸로 읽으면 AIR 가 되지요? 의도한 건지는 모르겠지만, AIR 는 이러한 RIA를 개발 할 수 있고, 배포 할 수 있는 런타임 환경입니다. 어떤 의미일까요? 지금까지의 어플리케이션은 java 나 c 등의 언어로 제작되고, 그것을 기반으로 하고 있습니다. 하지만 air의 기반은 웹에서 사용되고 있는 언어 그 자체입니다. HTML Javascript에서부터 Actionscript3.0, 드림위버로도 간단한 에어 어플리케이션을 만들 수 있습니다. 이러한 air 어플리케이션을 이용하여, 매쉬업을 한다면 얼마나 멋진 매쉬업이 나올까요? 브라우저를 열고, 사이트 주소를 치고, 로그인하는 번거로움을 없앨 뿐만 아니라, 로컬 DB의 사용으로 훨씬 빠른 환경을 제공해 줍니다. 또한

우리가 알고 있고, 제공 되고 있는 OpenAPI 는 모두 air 환경에서 구현이 가능합니다. 

 

 

 1. AOL mashup : Top 100 Videos
사용된 오픈 API : AOL OpenAIM
AOL 의 뮤직 비디오를 air 어플리케이션에서 볼수 있다.

참고 사이트 :  http://www.adobe.com/cfusion/showcase/index.cfm?event=casestudydetail&casestudyid=383991&loc=en_us&promoid=BTLNO

 링크가 짤린 뮤직 비디오가 좀 많은게 안타깝다.  

 2. ebay desktop
사용된 오픈 API :  eBay openapi
참고 사이트 : http://www.adobe.com/cfusion/showcase/index.cfm?event=casestudydetail&casestudyid=383833&loc=en_us&promoid=BTLNW 

ebay 에서의 쇼핑을 air 로 즐길수 있다. 깔끔한 ui 와 편한안
사용자 처리로 정말 물건을 사고 싶게 만든다.

 

 

 

3. twitter

OpenAPI : https://twitter.com/help/api

Flash / Actionscript Developers 를 위하여 as 로 제작된 라이브러리를 제공하고 있다.트위터라는 블로그 서비스를 하는 사이트에서 사용자들의 편안한 블로그 사용을 위해 만들어 졌다. 사이트에 접속할 필요도 없이 포스팅 하기, 리플 확인하기, 등록된 친구들 확인 등 뭐든 할수 있고,
실시간으로 내가 올린 포스트에 달리는 댓글 들을 확인할수 있다.

 

 

 

4. yahweh desktop ( 2008 매쉬업 경진대회 특별상 ) 사용된 openapi : 다음 블로그 api, 다음 인증 api, 네이버 맵 api, 네이버 동영상, 사진 api 로컬 db 로 만들어 진 성경과 블로그를 결합하여 쉽게 성경에 대한 생각을 공유

할수 있도록 만든 air 어플리케이션이다.  

http://dongkang.ivyro.net/yahweh/yahweh.zip

 

더 이상 매쉬업이 브라우저 많을 위한 전유물이 아니 라는 말입니다. 브라우저의 불편한 점을 거치지 않고, 어플리케이션으로 바로 자신이 원하는 콘텐츠를 즐길 수 있고, 브라우저에 한정된 콘텐츠가 아니라, 가능성을 가진 콘텐츠가 만들어 지는 것입니다.  

다시 한 번 강조 하면 매쉬업이란 검색 API를 가지고 하는 것이다. 라는 생각을 가진 분들이 많은데, 위에서 보여 드렸던 것과 같이, 모든 콘텐츠가 API 가 될 수 있고, 검색 API 는 그중 하나일 뿐입니다.

또한 air 기반의 매쉬업을 만드는 건 그렇게 어려운 일이 아닙니다. 기존에 존재 하고 있는 사이트에 air 포장지는 덮는다고 생각하세요. 그럼 air 가 완성 됩니다. 사용해 보세요. 지금 제공되고 있는 수많은 API를 이용해서 자신만의 매쉬업을 만들어 보세요. 



Posted by Flash 동강
Actionscript3.02008.12.11 11:51

전에 만들어 놓았던 웹캡에서 받은 영상을 차(-) 연산하여 동작을 인식 하는 클래스를 (말이 동작인식이지 단순 차연산;;;)  컴포넌트 형태로 제공되는 CustomTextMotion 에 적용해 보았습니다.


주온이 생각나는 안습 캡쳐 사진;;;

 

 
  1. package motioncap {
  2.         import flash.media.Video;       
  3.         import flash.events.StatusEvent;       
  4.         import flash.media.Camera;     
  5.         import flash.display.MovieClip;
  6.         import flash.display.BitmapData;
  7.         import flash.geom.Matrix;
  8.         import flash.utils.Timer;
  9.         import flash.events.TimerEvent;
  10.         import flash.geom.Point;       
  11.        
  12.         /**
  13.          * @author dongkang 2008-02-25
  14.          */
  15.         public class MotionCapture extends MovieClip {
  16.                
  17.                 private var w:uint;
  18.                 private var h:uint;
  19.                 private var tolerance : Number;
  20.                 private var pixel:int;
  21.                 private var startbool:Boolean;
  22.                 private var cam : Camera;
  23.                 private var vid : Video;
  24.                 private var now:BitmapData;
  25.                 private var before:BitmapData;
  26.                 private var snaptimer:Timer;
  27.                 private var motiontimer:Timer;
  28.                 private var snapmat : Matrix;
  29.                 private var mainStage:Object;
  30.                 private var hit_arr:Array;
  31.                 private var fl_arr:Array;// 동작인식된 점의 저장 장소
  32.                 private var bbo:Boolean;
  33.                
  34.                
  35.                
  36.                 public function MotionCapture(_root:Object,_hit_arr:Array) {
  37.                         bbo = false;
  38.                         mainStage = _root;
  39.                         hit_arr = _hit_arr;                                    
  40.                         w = 480;
  41.                         h = 320;
  42.                         tolerance = 50;
  43.                         pixel  = 10;
  44.                        
  45.                         startbool = false;
  46.                        
  47.                         cam = Camera.getCamera();
  48.                         cam.addEventListener(StatusEvent.STATUS, statushandler);
  49.                        
  50.                         vid = new Video();
  51.                         vid.attachCamera(cam);
  52.                         vid.visible = false;
  53.                         fl_arr = new Array();
  54.                         snaptimer = new Timer(100);
  55.                         motiontimer = new Timer(3000);
  56.                        
  57.                 }
  58.                 private function statushandler(e:StatusEvent):void
  59.                 {
  60.                        
  61.                        
  62.                         if(cam.muted){return;}
  63.                        
  64.                         cam.setMode(320,240,26,false);
  65.                         mainStage.addChild(vid);
  66.                         initialize();   
  67.                        
  68.                         cam.removeEventListener(StatusEvent.STATUS, statushandler);
  69.                 }
  70.                 private function initialize():void
  71.                 {
  72.                         snaptimer.addEventListener("timer", timerhandler);
  73.                         snaptimer.start();
  74.                                        
  75.                                        
  76.                         motiontimer.addEventListener(TimerEvent.TIMER, onMotionCapture);
  77.                         motiontimer.start();
  78.                        
  79.                        
  80.                         snapmat = new Matrix();
  81.                         snapmat.scale(1.5,1.5);                        
  82.                         now = new BitmapData(w,h);             
  83.                        
  84.                         var tim:Timer = new Timer(3000,10);
  85.                         tim.start();
  86.                         tim.addEventListener("timer",timhandler);
  87.                         tim.addEventListener(TimerEvent.TIMER_COMPLETE, timCompletehandler);
  88.                                        
  89.                        
  90.                 }
  91.                 private function timCompletehandler(e:TimerEvent):void{
  92.                         //bbo = false;
  93.                        
  94.                 }
  95.                
  96.                 private function timhandler(e:TimerEvent):void
  97.                 {
  98.                         bbo = true;
  99.                                
  100.  
  101.                 }
  102.                  
  103.                        
  104.                 private function timerhandler(evt:TimerEvent):void
  105.                 {
  106.                         try{
  107.                
  108.                                
  109.                                 before = now.clone();
  110.                                 now.draw(vid,snapmat);
  111.                                
  112.                                
  113.                                 // 현재 snapshot 에 대한 픽셀을 저장한다.
  114.                                 var nc:uint = new uint();
  115.                        
  116.                                 // 색깔 채널값을 설정한다.
  117.                                 var nr:Number = new Number();
  118.                                 var ng:Number = new Number();
  119.                                 var nb:Number = new Number();
  120.                                 var nl:Number = new Number();
  121.                                 // 각 채널에 대한 똑같은 값 지정
  122.                                 var bc:uint = new uint();
  123.                                
  124.                                 var br:Number = new Number();
  125.                                 var bg:Number = new Number();
  126.                                 var bb:Number = new Number();
  127.                                 var bl:Number = new Number();
  128.                                
  129.                                 // 두 밝기에 대한 차이를 저장한다.
  130.                                 var d:Number = new Number();
  131.                                
  132.                                 for(var xR:int=w; xR > 0;xR-=pixel)
  133.                                 {
  134.                                         for(var yR:int=1;yR<h;yR+=pixel)
  135.                                         {
  136.                                                
  137.                                                
  138.                                                 nc=now.getPixel(xR,yR);
  139.                                                 //trace(nc.toString(16));
  140.                                                 nr=nc>>16&0xff;
  141.                                                 ng=nc>>8&0xff;
  142.                                                 nb=nc&0xff;
  143.                                                 nl=Math.sqrt(nr*nr + ng*ng + nb*nb);
  144.                                                 bc=before.getPixel(xR,yR);
  145.                                                 br=bc>>16&0xff;
  146.                                                 bg=bc>>8&0xff;
  147.                                                 bb=bc&0xff;
  148.                                                 bl=Math.sqrt(br*br + bg*bg + bb*bb);
  149.                                                 d=Math.round(Math.abs(bl-nl));
  150.                                                                
  151.                                                 if(d > tolerance)
  152.                                                 {
  153.                                                        
  154.                                                        
  155.                                                         if(bbo)
  156.                                                         {
  157.                                                                 if(fl_arr.length < 2000)
  158.                                                                 {
  159.                                                                         var te:Ctext = new Ctext();
  160.                                                                         te.x = xR;
  161.                                                                         te.y = yR;
  162.                                                                         addChild(te);
  163.                                                                         fl_arr.push(te);
  164.                                                                 }
  165.                                                         }       
  166.                                                        
  167.                                                        
  168.                                                        
  169.                                                        
  170.                                                        
  171.                                                 }
  172.                                                
  173.                                         }
  174.                                        
  175.                                        
  176.                                 }
  177.                                 evt.updateAfterEvent();
  178.                                 before = now.clone();
  179.                         }
  180.                         catch(e:TypeError)
  181.                         {
  182.                
  183.                
  184.                         }                      
  185.                 }       
  186.                 private function onMotionCapture(e:TimerEvent):void {
  187.                         trace("전 점의 갯수 : "+fl_arr.length);
  188.                         var len:int = fl_arr.length *2;
  189.                         for (var q:int = 0; q < fl_arr.length; q++) {
  190.                                 try{
  191.                                         removeChild(fl_arr.pop());
  192.                                 }
  193.                                 catch(e:Error)
  194.                                 {
  195.                                        
  196.                                 }
  197.                         }
  198.                         trace("후 점의 갯수 : "+fl_arr.length);
  199.  
  200.                 }
  201.                
  202.         }
  203. }

 이걸 비트맵이랑 연동하면 재미 있는게 나올꺼 같은데;; 아직 시도도 못해 보고 있는중;;; 


Posted by Flash 동강
Actionscript3.02008.12.11 11:46

SoundMixer.computeSpectrum() 
SoundMixer.computeSpectrum() 를 이용하면 현재 재생하고 있는 사운드에 대한 원시 데이터를 불러올수 있습니다. 

다음 그림에서는 FFTMode 매개 변수가 true로 설정되었을 때와 false로 설정되었을 때 computeSpectrum() 메서드로부터 반환된 데이터를 비교합니다. 이 그림에 사용된 사운드 데이터는 왼쪽 채널은 큰 베이스 사운드, 오른쪽 채널은 드럼 사운드에 대한 것입니다.

 

 // 드로잉 API 를 이용한 간단한 사운드 스트리밍
  1. import flash.display.Graphics;
  2. import flash.events.Event;
  3. import flash.media.Sound;
  4. import flash.media.SoundChannel;
  5. import flash.media.SoundMixer;
  6. import flash.net.URLRequest;
  7.  
  8. const PLOT_HEIGHT:int = 200;
  9. const CHANNEL_LENGTH:int = 256;
  10.  
  11. var snd:Sound = new Sound();
  12. var req:URLRequest = new URLRequest("mystory.mp3");
  13. snd.load(req);
  14.  
  15. var channel:SoundChannel;
  16. channel = snd.play();
  17. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  18. snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
  19.  
  20. var bytes:ByteArray = new ByteArray();
  21.  
  22. function onEnterFrame(event:Event):void
  23. {
  24.     SoundMixer.computeSpectrum(bytes, false, 0);
  25.    
  26.     var g:Graphics = this.graphics;
  27.    
  28.     g.clear();
  29.     g.lineStyle(0, 0x6600CC);
  30.     g.beginFill(0x6600CC);
  31.     g.moveTo(0, PLOT_HEIGHT);
  32.    
  33.     var n:Number = 0;
  34.        
  35.     // 왼쪽 채널
  36.     for (var i:int = 0; i < CHANNEL_LENGTH; i++)
  37.     {
  38.         n = (bytes.readFloat() * PLOT_HEIGHT);
  39.         g.lineTo(i * 2, PLOT_HEIGHT - n);
  40.     }
  41.     g.lineTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
  42.     g.endFill();
  43.    
  44.     // 오른쪽 채널
  45.     g.lineStyle(0, 0xCC0066);
  46.     g.beginFill(0xCC0066, 0.5);
  47.     g.moveTo(CHANNEL_LENGTH * 2, PLOT_HEIGHT);
  48.    
  49.     for (i = CHANNEL_LENGTH; i > 0; i--)
  50.     {
  51.         n = (bytes.readFloat() * PLOT_HEIGHT);
  52.         g.lineTo(i * 2, PLOT_HEIGHT - n);
  53.     }
  54.     g.lineTo(0, PLOT_HEIGHT);
  55.     g.endFill();
  56. }
  57.  
  58. function onPlaybackComplete(event:Event)
  59. {
  60.     removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  61. }

 사운드 데이터는 512바이트의 데이터가 포함된 ByteArray 객체로 반환되며 각 개체는 -1과 1 사이의 부동 소수점 값을 포함합니다. 이러한 값은 재생 중인 사운드 파형의 위치 진폭을 나타냅니다. 값은 두 개의 256바이트 그룹으로 제공됩니다. 첫 번째 그룹은 왼쪽 스테레오 채널용이고 두 번째 그룹은 오른쪽 스테레오 채널용입니다.
FFTMode 매개 변수가 true로 설정된 경우, SoundMixer.computeSpectrum() 메서드는 파형 데이터가 아니라 주파수 스펙트럼 데이터를 반환합니다. 주파수 스펙트럼은 가장 낮은 주파수에서 가장 높은 주파수까지 사운드 주파수에 따라 배열된 진폭을 표시합니다. FFT(Fast Fourier Transform)는 파형 데이터를 주파수 스펙트럼 데이터로 변환하는 데 사용됩니다. 결과 주파수 스펙트럼 값은 0에서 약 1.414(2의 제곱근)까지입니다.

Posted by Flash 동강
Actionscript3.02008.12.11 11:44

Actionscript 3.0 에서의 사운드 작업 

ActionScript 3.0을 사용하여 사운드를 재생할 경우 다음 작업을 수행할 수 있습니다.

  • 특정 시작 위치에서 사운드 재생
  • 사운드를 일시 정지하고 나중에 같은 위치에서 다시 재생 시작
  • 사운드 재생이 끝나는 정확한 시간 알아보기
  • 사운드의 재생 진행률 추적
  • 사운드 재생 중에 볼륨 변경 및 패닝

위의 기능은 Sound 클래스로만 이룰 수 있는게 아니라 SoundChannel 이나 SoundMixer SoundTransform 클래스를 이용해야 가능합니다.  

기본적으로 Sound 클래스의 재생과 정지는 다음과 같습니다.

 

// 재생

var snd:Sound = new Sound(new URLRequest("bigSound.mp3"));
var channel:SoundChannel = snd.play();

//정지

var pausePosition:int = channel.position;
channel.stop();

 

//특정 위치에서의 사운드 시작

channel = snd.play(pausePosition);

 

// mp3 파일의 로드 처리시 기본 사용.

//재생 진행률을 표시하는 데 Event.ENTER_FRAME 이벤트를 시간 메커니즘으로 사용합니다. 그리고 현재 위치 값을 사운드 데이터의 전체 길이로 나누어 계산되는 재생 백분율을 정기적으로 보고합니다.

 

import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;

var snd:Sound = new Sound();
var req:URLRequest = new
    URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3");
snd.load(req);

var channel:SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
snd.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);

function onEnterFrame(event:Event):void
{
    var estimatedLength:int =
        Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
    var playbackPercent:uint =
        Math.round(100 * (channel.position / estimatedLength));
    trace("Sound playback is " + playbackPercent + "% complete.");
}

function onPlaybackComplete(event:Event)
{
    trace("The sound has finished playing.");
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}

 사운드를 스트리밍 중 중단했을시 발생하는 문제

스트리밍되는 사운드 즉, 재생하는 동안 계속 로드되는 사운드의 경우 재생 프로세스에 이상 현상이 발생하기도 합니다. 스트리밍 사운드를 재생 중인 SoundChannel 인스턴스에서 응용 프로그램이 SoundChannel.stop() 메서드를 호출하면 한 프레임에 대한 사운드 재생이 중지되고 다음 프레임에서 사운드를 처음부터 다시 재생합니다. 이러한 현상이 나타나는 이유는 사운드 로드 프로세스가 아직 진행 중이기 때문입니다. 스트리밍 사운드의 로드와 재생을 모두 중단하려면 Sound.close() 메서드를 호출합니다. 

역시 고려 되야 하는 사운드 로드시 보안문제

사운드 파일의 원본 도메인은 내용 샌드박스의 보안 제한 사항을 정의합니다. 일반적으로 사운드 파일을 로드하는 응용 프로그램 또는 객체의 SWF 파일과 동일한 도메인 또는 폴더에 사운드 파일이 있으면 응용 프로그램 또는 객체는 해당 사운드 파일에 액세스할 수 있습니다. 응용 프로그램과는 다른 도메인에서 사운드가 제공되는 경우에도 크로스 도메인 정책 파일을 사용하여 내용 샌드박스에서 사운드를 가져올 수 있습니다.

응용 프로그램은 checkPolicyFile 속성을 사용하여 SoundLoaderContext 객체를 Sound.load() 메서드에 매개 변수로 전달할 수 있습니다. checkPolicyFile 속성을 true로 설정하면 Flash Player는 사운드가 로드된 서버에서 크로스 도메인 정책 파일을 찾습니다. 크로스 도메인 정책 파일이 존재하고 로드하는 SWF 파일의 도메인에 액세스 권한이 부여되면 SWF 파일은 사운드 파일을 로드하고 Sound 객체의 id3 속성에 액세스한 다음 로드된 사운드에 대한 SoundMixer.computeSpectrum() 메서드를 호출합니다.

소유자 샌드박스는 사운드의 로컬 재생을 제어합니다. 사운드 재생을 시작하는 응용 프로그램 또는 객체가 소유자 샌드박스를 정의합니다.

다음 조건에 맞는 경우 SoundMixer.stopAll() 메서드는 현재 재생 중인 모든 SoundChannel 객체의 사운드를 중지합니다.

  • 동일한 소유자 샌드박스 내의 객체에 의해 시작된 사운드
  • SoundMixer.stopAll() 메서드를 호출하는 응용 프로그램 또는 객체의 도메인에 대한 액세스를 허용하는 크로스 도메인 정책 파일을 가진 소스에서 제공되는 사운드

SoundMixer.stopAll() 메서드가 모든 재생 사운드를 실제로 중지하는지 알아보기 위해 응용 프로그램이 SoundMixer.areSoundsInaccessible() 메서드를 호출할 수 있습니다. 해당 메서드가 true 값을 반환하면 재생 중인 일부 사운드는 현재 소유자 샌드박스의 제어 범위를 벗어나므로 SoundMixer.stopAll() 메서드에 의해 중지되지 않습니다.

또한 SoundMixer.stopAll() 메서드는 외부 파일로부터 로드된 모든 사운드에 대해 재생 헤드가 계속 진행되지 않도록 중지합니다. 하지만 Flash 제작 도구를 사용하여 FLA 파일에 포함된 사운드 및 타임라인 내 프레임에 연결된 사운드는애니메이션이 새 프레임으로 이동하면 다시 재생되기 시작합니다.  

스피커 마다의 패닝 제어 

SoundChannel 객체의 팬 속성은 재생 중에 왼쪽 및 오른쪽 채널 각각에 다른 볼륨 수준을 지정하는 데 사용될 수 있습니다. 팬 속성은 -1 ~ 1 범위의 값을 가질 수 있습니다. 여기서 -1은 오른쪽 채널 음을 소거한 상태에서 왼쪽 채널을 최고 볼륨으로 재생한다는 의미이며, 1은 왼쪽 채널 음을 소거한 상태에서 오른쪽 채널을 최고 볼륨으로 재생한다는 의미입니다. -1과 1 사이의 숫자 값은 왼쪽과 오른쪽 채널 값에 대한 비례 값을 설정하며, 0은 양쪽 채널이 균형 있는 중간 볼륨 수준으로 재생된다는 의미입니다. 

 // Enterframe 을 이용하여 스피커의 양쪽 볼륨을 왔다 갔다 하는 코드 입니다.
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;

var snd:Sound = new Sound();         
var req:URLRequest = new URLRequest("bigSound.mp3");
snd.load(req);

var panCounter:Number = 0;

var trans:SoundTransform;
trans = new SoundTransform(1, 0);
var channel:SoundChannel = snd.play(0, 1, trans);
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);

addEventListener(Event.ENTER_FRAME, onEnterFrame);

function onEnterFrame(event:Event):void
{
    trans.pan = Math.sin(panCounter);
    channel.soundTransform = trans; // 또는 SoundMixer.soundTransform = trans;
    panCounter += 0.05;
}

function onPlaybackComplete(event:Event):void
{
    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
 본 내용은 Flash CS3 설명서를 정리한 내용 입니다.

Posted by Flash 동강
Actionscript3.02008.12.11 11:42

동적으로 라이브러리에 있는 무비 클립이나 bitmap 파일을 어떻게 불러 올수 있을까요? 

as3.0 에서 class 개념이 좀더 확장 되면서 Linkage 에서 identifial 지정 뿐만 아니라 class 및 base 클래스를 지정 할수 있습니다. 라이브러리에 있는 객체들을 동적으로 불러 오기 위해서는 Linkage 와 class 와 new 와 addChild 이 필요 합니다.   

우선 Linkage 창을 보면 (라이브러리에서 우클릭 Linkage)


Export for Actionscript 를 클릭하면

 무비 클립을 Linkage 하셨다면 flash.display.MovieClip 가 Base로 지정되게 되고 자신이 이름 붙일수 있는 Class 창이 활성화 됩니다 ( 여기서는 cursor ) 원하는 class 이름을 써 놓고 ok 를 누르게 되면 이제 해당 객체가 클래스로 정의가 된 것입니다. (매우 간단히 클래스를 만들수 있다는 ) ( 아마 내부적으로  fla 파일에 매여 있는 class 가 생성됩니다. )

만약 아래와 같은 무비 클립을 Linkage 하셨다면.

 

var cur:cursor = new cursor(); <-- var mc:MovieClip = new MovieClip();
addChild(cur);

하게 되면 좌표 0,0 값에 cur 가 보여 지게 됩니다.

 

동적으로 다른 위치에 5개 생성 

for(var i:int= 0; i < 5; i++){

     var cur:cursor = new cursor();
     cur.x = i*5;
     addChild(cur);

}

 이런식으로 연결하여 사용하시면 되고요, 이것 이용해서 우리가 지금까지 토의 했던 상속이라는 개념을 적용할수 있습니다. 위의 cursor는 단지 화살표 모양의 무비 클립일 뿐 속성이 정의가 안되어 있는데 여기서 속성을 추가해 보겠습니다. 같은 폴더에 Ccursor.as 를 생성하시고 아래 코드 입력. 


  1. // 테스트를 위한 Ccursor 생성
  2.  
  3. package{
  4.  import flash.display.*;
  5.  import flash.events.*;
  6.  
  7.  public class Ccursor extends cursor           //fla 파일에서 정의한 cursor class 를 상속 받는다.
  8.  {
  9.   public function Ccursor():void
  10.   {
  11.    addEventListener(MouseEvent.MOUSE_OVER, Overhandler);
  12.    addEventListener(MouseEvent.MOUSE_OUT, Outhandler);
  13.      
  14.   }
  15.   private function Overhandler(ev:MouseEvent):void
  16.   {
  17.    trace("오버");
  18.   }
  19.   private function Outhandler(ev:MouseEvent):void
  20.   {
  21.    trace("아웃");
  22.    
  23.   }
  24.  
  25.  }
  26.  
  27. }

 
  1. //fla 파일 두가지 종류의 클래스 생성
  2.  
  3. var cur:cursor = new cursor();
  4. cur.x = 200;
  5. cur.y = 200;
  6. addChild(cur);
  7.  
  8.  
  9.  
  10. var cur2:Ccursor = new Ccursor();
  11. cur2.x = 300;
  12. cur2.y = 200;
  13. addChild(cur2);

 

 Ccursor class 로 addChild 된 왼쪽 객체 만이 마우스 이벤트에 반응하게 됩니다. 이와 같이 Flash 는 라이브러리에 있는 사용자 정의 객체들을 자유 롭게 사용할수 있는 편안한 인터페이스를 제공합니다.

 



Posted by Flash 동강
Actionscript3.02008.12.11 11:31

플래시를 시작 하고 나서 처음으로 만들어 보고 싶은 것을 꼽으라면 내 사진첩 이라는 말을 제일 많이 들어보았습니다. 

저 또한 플래시를 접하게 되고 처음으로 "내가 만든 것" 이라고 사람들에게 보여 준것도 사진첩이었습니다. 사진첩이라는 말이 거창하게 들릴지 모르겠지만, 사진첩이난 MP3 플레이어를 만들때 핵심이라 할수 있는 Loader Class 에 대해 끄적여 볼까 합니다.

Loader

Loader DisplayObjectContainer InteractiveObject DisplayObject EventDispatcher Object

Loader 클래스는 SWF 파일이나 이미지(JPG, PNG 또는 GIF) 파일을 로드하는 데 사용됩니다. load() 메서드를 사용하여 로드를 시작합니다. 로드된 표시 객체는 Loader 객체의 자식으로 추가됩니다.

텍스트 또는 이진 데이터를 로드하려면 URLLoader 클래스를 사용합니다. Loader 객체는 자식 표시 객체(Loader 객체가 로드하는 표시 객체)를 하나만 가질 수 있기 때문에 Loader 클래스는 자신이 상속하는 다음 메서드를 무시합니다. 따라서 addChild(), addChildAt(), removeChild(), removeChildAt()setChildIndex() 메서드를 호출하면 예외가 발생합니다. 로드된 표시 객체를 제거하려면 해당 부모 DisplayObjectContainer 자식 배열에서 Loader 객체를 제거해야 합니다.

레퍼런스에 적혀 있는 말이 어렵게만 느껴지는 군요;;  위의 말대로 Loader 는 파일을 로드 하기 위해 사용 됩니다.   

var testloader:Loader = new Loader();
testloader.load(new URLRequest("image.jpg");
addChild(testloader);   

로더 클래스에서 경로를 설정해 주기 위해서는 URLRequest 라는 클래스를 사용하게 되는데 URLRequest 클래스는 하나의 HTTP 요청에 포함된 모든 정보를 캡처합니다.

 

가장 기본이 되는 뼈대 입니다. 그렇다면 Loader 는 불러 오기만 하면 그 기능을 다 하는 것인가? Loader Class 에서는 그 해당 로더로 불러와 지는 데이터의 접근 기능을 가지고 있습니다. 이 기능으로 인해 예를 들어 사진을 로드 한다면 width 값이나 height 값을 바꿀수 있는 것이지요.  


testloader.contentLoaderInfo.addEventListener(Event.COMPLETE, fComplete);
function fComplete(ev:Event):void
{
    var mObject:DisplayObject = ev.target.content;
    mObject.width=100;
    mObject.height=100;

}


// ev.target.content 로 해당 로더로 불러와 지는 데이터에 대한 접근을 할수 있습니다. 그 후에 width 값과 height 를 바꿔주는 것이지요. 위의 예는 이미지 로드 뿐만 아니라 xml 로드 swf 로드 때에도 동일하게 적용이 됩니다.  


function  fComplete(ev:Event){
   var loader:URLLoader=URLLoader(ev.target);             
// URLLoader 에 대한 내용은 레퍼런스를 참고하세요

   var dataXML=new XML(loader.data);
   trace(dataXML);
  
  }

 LoaderEvent 에서는 load 가 끝났을때의 이벤트 뿐만 아니라 로드가 진행 될때의 이벤트도 제공 하고 있습니다.  


testloader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, fProcess);
function fProcess(ev:ProgressEvent):void
{
    var mPercent:Number =int( e.bytesLoaded/e.bytesTotal*100.0);
    trace(mPercent);
}

 위의 기능으로 이미지 로드시 로딩바를 만들수 있게 되는 것입니다. ( progressEvent 가 진행되고 있을때는 로딩 무비 클립을 addChild 해 주고 끝나면 그 무비 클립을 제거 해 주는 방식으로)  

이러한 이벤트들로 이미지를 불러오고 불러온 이미지를 조작하고 interaction 을 추가 하여 기본적인 겔러리를 구현할수 있습니다. 이 로드하는 방식을 간단하게 쓸수 있게 만들어 놓은 Class 를 소개 합니다.

( 새롭게 시작하는 Actionscript 3.0 -윤훈남 의 예제 소스 ) - 문제가 생기면 삭제 하겠습니다.  

 

  1. package {
  2.  
  3.  import flash.display.Loader;
  4.  import flash.display.DisplayObjectContainer;
  5.  import flash.events.ProgressEvent;
  6.  import flash.events.Event;
  7.  import flash.net.URLRequest;
  8.  import flash.display.DisplayObject;
  9.  
  10.  public class CLoaderUI extends CLoadAni {
  11.   var pLoader:Loader = new Loader();
  12.   var pRequest:URLRequest = new URLRequest();
  13.   var pContainer:DisplayObjectContainer;
  14.  
  15.  
  16.   var pWidth:Number,pHeight:Number;
  17.   var pX:Number,pY:Number;
  18.  
  19.   function CLoaderUI(mStage:DisplayObjectContainer,mURL:String,mWidth:Number,mHeight:Number,mX:Number=0, mY:Number=0):void {
  20.    pContainer = mStage;                      // mStage 는 어느 객체에 load 를 할지를 지정할수 있게 해 준다.
  21.    pX=mX;                                         // 위치 지정
  22.    pY=mY;                                          // 크기 지정
  23.    pWidth=mWidth;
  24.    pHeight=mHeight;  
  25.          
  26.    pRequest.url =mURL;                       // 해당 이미지 경로 지정
  27.    if(pRequest.url != "")
  28.     pLoader.load(pRequest);
  29.    else
  30.     pLoader.load(new URLRequest("noImage.jpg"));          // 이미지가 없을때는 정해진 이미지 로드
  31.    
  32.    pLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, fProcess);       // 진행중
  33.             pLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, fComplete)           // 완료
  34.    
  35.  }
  36.      function fProcess(e:ProgressEvent):void {
  37.      var mPercent:Number =int( e.bytesLoaded/e.bytesTotal*100.0);
  38.  
  39.      trace(mPercent);
  40.   }
  41.  
  42.   function fComplete(e:Event):void
  43.   {  
  44.     var mObject:DisplayObject = e.target.content;        //load 된 내용을 불러 와서
  45.     mObject.width=pWidth;                                       // 조작한다.
  46.     mObject.height=pHeight;
  47.     mObject.x=pX;
  48.     mObject.y=pY;
  49.     pContainer.addChild(mObject);
  50.     pContainer.removeChild(this);                  // 해제 시켜 준다.
  51.     pLoader =null;
  52.     pContainer=null;
  53.     pRequest=null;
  54.   }
  55.  }
  56. }

 위의 클래스를 사용하면 로드시에 겪는 불편을 조금 덜어 줍니다. 처음 사진첩 만들때 이미지 크기 조작을 어떻게 해야 할지 몰라 고생했던거 생각을 하면서 썼습니다.
조금이라도 도움이 되셨다면 좋겠네요.

Posted by Flash 동강
동강의AS3.0 강좌2008.12.11 01:52

디자인을 하다가 Flash 를 시작하시는 분이나, 일반 프로그래밍을 하다가 시작하는 분이나, Actionscript 의 이벤트라는 개념은 생소하게 다가 옵니다. 그래서 시작하는 분들이 조금이라도 빨리 이해를 돕고자 Event... 에 대해 이야기를 해 보겠습니다.  

Actionscript 3.0 을 시작하고 적응하기 어려웠던 점은 2.0 과 다르게 브로드 케스팅으로 이벤트를 호출하고 호출 받는 다는 점이었습니다. 2.0 에서도 그러한 개념이 있긴 했지만, 3.0 에 와서는 완전 바뀌었습니다.  

가장 많이 사용하는 flash.events.Event  = Event
flash.events.MouseEvent = MouseEvent  

초기에 Event 는 ENTER_FRAME 을 돌리기 위한 이벤트로 많이 사용되고 MouseEvent 는 마우스의 각기 반응들에 이벤트를 걸어 주기 위해 사용 됩니다. 그렇다면 어떠한 원리로 이벤트가 걸리게 되는 걸까요? ( 개념을 정리 하기 위한 추상적인 클래스이니, 고칠 부분을 알려 주시기 바람니다. )  

우선 Mouse 라는 Class 가 존재 합니다.

Mouse 라는 클래스 안에는 마우스의 상태가 MOUSE_OVER ,MOUSE_OUT, CLICK 되었을때의 호출되는 함수(여기에서는 각각의 문을 함수라고 생각하시면 됩니다 ) 가 정의 되어 있습니다. 이 세개의 문들은 마우스 이벤트가 일어날때를 대비 해서 항상 기다리고 있지요. (addEventLister 로 이벤트가 걸렸을 경우에만 기다리고 있습니다. )

이 문이 열리는 것이 마우스 이벤트가 실행 되었다는 의미 입니다. Actionscript 에서는 이 문들을 대기 시키기 위해서  

addEventListener(MouseEvent...)
의 방법으로 이벤트를 대기 목록에 하나하나씩 추가 하게 됩니다. 이벤트를 대기 하는 메모리 공간에 자신이 추가 하고 싶은 이벤트 를 추가(add) 하는 것이지요. 반대로 이 이벤트 대기 목록에서 빼기 위한 방법으로  removeEventLister(MouseEvent...) 의 방법을 사용함니다. 더이상 이벤트가 발생하는걸 기다리지 않아도 된다는 의미 입니다.  

하지만 위의 Mouse class 에 있는 각각의 문들이 열렸다는 것은 어떻게 알수 있을까요? 내부적으로 마우스가 클릭되거나 Over 되거나 했을때 자동적으로 문이 열리기 되는 것일까요? 내부적으로 그렇게 구현되었을 수도 있겠지만, Actionscript 에서는 이벤트를 발생시키고 생성하는 매소드를 제공합니다.  이때 사용 하는 것이 dispatchEvent 입니다.  

 
dispatchEvent () 메서드  
public override function dispatchEvent(event:Event):Boolean

언어 버전 :  ActionScript 3.0
Player 버전 :  Flash Player 9

이벤트를 이벤트 흐름으로 전달합니다. 이벤트 대상은 dispatchEvent() 메서드가 호출된 EventDispatcher 객체입니다.

매개 변수

event:Event — 이벤트 흐름으로 전달된 Event 객체입니다. 이벤트를 다시 전달하는 경우, 해당 이벤트의 복제본이 자동으로 만들어집니다. 이벤트가 전달된 뒤에는 이벤트의 target 속성을 변경할 수 없으므로, 재전달에 성공하려면 이벤트의 복사본을 새로 만들어야 합니다.

반환값
Boolean — 이벤트가 성공적으로 전달된 경우 값은 true입니다. false 값은 실패를 나타내거나 해당 이벤트에서 preventDefault()가 호출되었음을 나타냅니다.

오류
SecurityError — Stage 객체의 dispatchEvent() 메서드를 호출하면 스테이지 소유자(기본 SWF 파일)와 다른 보안 샌드박스에 있는 호출자에 대해 예외가 발생합니다. 스테이지 소유자는 이와 같은 상황을 피하기 위해 Security.allowDomain() 메서드 또는 Security.allowInsecureDomain() 메서드를 호출하여 호출자 도메인에 권한을 부여할 수 있습니다. 자세한 내용은 ActionScript 3.0 프로그래밍의 "보안" 장을 참조하십시오.

 중요한건 알겠는데 어떻게 사용 되는 것인가? Actionscript 에서는 내부적으로 Mouse 가 CLICK 되었을때 발생하는 함수가 구현되어 있을것입니다. 만약 MouseCLICK 이 발생할때 실행 되는 함수가 Class Mouse 의 function CLICK ():void {} 이라면 dispatchEvent 를 사용해서 연결 시킬수 있습니다.

 

 flash.events.MouseEvent
 
  1. package flash.events{
  2.        
  3.         public class MouseEvent
  4.         {
  5.                 public static const MOUSE_OVER:String = "mouseover";
  6.                 public static const MOUSE_OUT:String = "mouseout";
  7.                 public static const CLICK:String = "click";
  8.                
  9.                 etc....
  10.                
  11.                 public function MouseEvent(type : String, bubbles : Boolean = false, cancelable : Boolean = false)
  12.                 {
  13.                         ........
  14.                        
  15.                 }
  16.                
  17.                
  18.         }
  19. }
  20.  

 

Mouse Class 안에 존재 하는 CLICK 매소드 , 이 매소드는 마우스가 클릭되면 호출된다. 하지만 이벤트를 발생 시키는

담당은 dispatchEvent 가 맡게 된다. 

 

public function CLICK():void
{

  ........................

  .......................... dispatchEvent 로 이벤트와 함수를 연결시켜주는 것 외에 다른것들도 구현되어 있을것 같습니다.
 dispatchEvent(new MouseEvent(MouseEvent.CLICK));

}

 

dispatchEvent 로 인해 CLICK 이라는 함수와 MouseEvent 의 CLICK 이라는 이벤트는 동기화가 되게 됩니다. CLICK 함수가 실행되면 '아 MouseEvent.CLICK 이벤트가 실행 되었구나 ' 하고 리스너들이 알게 되는 것입니다.

 Flash 에서의 이벤트 전달과 캐취는 이런식으로 발생하게 됩니다. 이러한 것들은 이미 Actionscript 에서 내부적으로 구현 되어 있는 것들이고, 이 원리를 이용하여 CustomEvent 를 만들수 있고, 이벤트를 좀더 유도리 있게 사용할수 있게 되는 것입니다.   

간단한 예로 마이크에서 나오는 소리를 1초 단위로 받기 위한 이벤트를 만들어 보겠습니다. 우선 SoundEvent 란 CustomEvent 를 생성하고, flash.events.Event 를 상속 받았습니다.

 

  1. package customEvent {
  2.  import flash.events.Event;
  3.  
  4.  /**
  5.   * @author dongkang
  6.  
  7.   */
  8.  public class SoundEvent extends Event {
  9.  
  10.   public static const CATCH:String = "catching";
  11.  
  12.   public function SoundEvent(type : String, bubbles : Boolean = false, cancelable : Boolean = false) {
  13.    super(type, bubbles, cancelable);
  14.   }
  15.  }
  16. }

 

이렇게 하는 것 만으로도 자신만의 커스텀 이벤트가 생성됩니다. FDT 나 Flex Builder 를 사용하시는 분들은 Event 를 상속 받는 클래스를 생성했을때 자동으로 인자값이 들어 가는것을 확인할수 있을 것입니다. 그리고 SoundEvent 의 속성으로 사용될 public static const CATCH:String = "catching"; 를 생성하였습니다. CATCH 는 SoundEvent.CATCH 와 같이 사용될 수 있는 것이고 catching 은 addEventListener("catching',함수); 와 같이 사용할수 있게 합니다. 하지만 위의 SoundEvent Class 만으로는 동작이 불가능합니다. 어떠한 일을 하는지도 모를 뿐더러 SoundEvent 라는 이름만 정의 되어 있는 Class 이기 때문입니다. 그렇다면 어떻게 ? 이 클래스에 생명을 불어 넣을수 있을까요?   

dispatchEvent 를 사용 하면 됩니다.  

  1. /* dongkang . 2008-02-23
  2. SoundGauge Class  : checking sound 0 ~ 100 */
  3.  
  4. package interactive.sound{
  5.  
  6.  import flash.events.ActivityEvent;
  7.  import flash.events.StatusEvent;
  8.  import flash.events.Event;
  9.  import flash.events.TimerEvent;
  10.  
  11.  import flash.media.Microphone;
  12.  
  13.  import flash.display.Sprite;
  14.  import flash.display.MovieClip;
  15.  
  16.  import flash.utils.Timer;
  17.  
  18.  import customEvent.SoundEvent;
  19.  
  20.  public class SoundGauge extends Sprite {
  21.   private var device_arr:Array;
  22.   public var mic:Microphone;
  23.   private var gauge:MovieClip;
  24.   private var soundtimer:Timer;
  25.  
  26.   public function SoundGauge(_gauge:MovieClip):void {
  27.    gauge = _gauge;
  28.    device_arr = Microphone.names;
  29.    mic = Microphone.getMicrophone();
  30.    mic.gain = 40;
  31.    mic.rate = 11;
  32.    mic.setUseEchoSuppression(true);
  33.    mic.setLoopBack(true);
  34.    mic.setSilenceLevel(0,10);
  35.  
  36.  
  37.    for (var i:int =0; i < device_arr.length; i++) {
  38.     trace("   " + device_arr[i]);
  39.    }
  40.    
  41.    soundtimer = new Timer(1000);
  42.    soundtimer.start();
  43.    soundtimer.addEventListener("timer",onSoundhandler);
  44.   }
  45.  
  46.   private function onSoundhandler(e:TimerEvent) : void {
  47.    dispatchEvent(new SoundEvent(SoundEvent.CATCH));
  48.   }

 

 위의 클래스는 마이크에서 받은 소리를 1초 단위로 확인하기 위한 클래스 입니다. soundtimer 는 1초 단위로 onSoundhandler를 실행 시킬 것이고, 이 함수안에는 dispatchEvent 가 있어 SoundEvent.CATCH 가 호출되었다는 사실을 1초 단위로 계속 알려주게 됩니다. 그런데 누구 한테 알려 주는 걸까요? dispatchEvent 란 의미는 자기 자신이 해당되는 Class 에 SoundEvent.CATCH 를 걸어 주겠다는 의미 입니다. 다시 말해서 SoundGauge 에 SoundEvent.CATCH 이벤트가 걸리게 됩니다. 우리는 이 이벤트를 받아 오기 위해 SoundGauge 를 생성한 함수 내부에서 받아 올수 있습니다.  

 

var sg:SoundGauge = new SoundGauge();

sg.addEventListener(SoundEvent.CATCH, onCatch);

 

function onCatch(e:SoundEvent):void

{

 이함수는 어떻게 호출 되는 걸까요?

           SoundGauge 가 생성되자 마자 내부에 있는 soundtimer가 시작되기 때문에

         이 함수 또한 1초 마다 실행 되게 됩니다.

}

 

 

이처럼 dispatchEvent 는 정말 다양하게 중요하게 사용되는 메서드 입니다.
"이벤트를 이벤트 흐름으로 전달하고, 이벤트 대상은 dispatchEvent() 매서드가 호출된 EventDispatcher 객체 입니다. 쉬운 개념이 아닌 만큼 알게 되면 그동안 힘들게 했던 이벤트 전달을 손쉽게 적용할수 있으니, 그야 말로 최강 무기 라고 할수 있습니다. Actionscript 는 이벤트가 전부다 라고 말해도 될 만큼 이벤트중심으로 코드가 짜여 있습니다. 특히 이벤트를 전달하는 개념인 dispatchEvent 를 모르고 넘어 가신다면, 좋은 아이템을 버리고 싸우러 가는 것을 의미 할 정도로 중요합니다. 

 저도 알아 가고 있는 상태라 설명이 제대로 된지 모르겠습니다. 역시 잘못된 부분은 거침없이 태클 달아 주시고요, 잘 이해 안가는 부분은 알려 주시면 더 보충하도록 하겠습니다. 금요일 입니다. 주말 잘 보내시고 곧 있을 컨퍼런스가 기대가 되네요. 



Posted by Flash 동강
동강의AS3.0 강좌2008.12.11 01:43

지난 번 강좌에 이어서 해 보겠습니다. 다들 iMac navigation 이라면 아시지요? 맥을 쓰는 사람들은 항상 모니터 아랫쪽에 위치 시켜 두고 쓰는 편리 한(?) 네비게이션 입니다. 이미 많은 분들이 구현을 해 놓으셨고 윤용호 님이 쓰신 플래시 네비게이션 패턴 18 에서도 다루고 있습니다.  

1단계에서 만들 네비게이션은 아래와 같습니다.


stage 에 자신의 icon 을 디자인 하고, 그 icon 을 무비 클립으로 등록합니다.


저는 5개의 icon 을 만들었고, icon0 ~ icon4 로 이름을 붙였습니다. 이 5개의 무비 클립을 배열에 저장하고 그 배열의 순서로 icon 들을 조정할 것 입니다.  Document class 를 만들고 위의 icon 들을 저장할 배열을 만듭니다.   

 
  1. public function Main() {
  2.                        
  3.                         bit_arr = new Array();
  4.                         bit_arr = [icon0,icon1,icon2,icon3,icon4];
  5.                         
  6.                                
  7.                         for (var i:int=0; i< bit_arr.length; i++) {
  8.                                
  9.                                
  10.                                 bit_arr[i].trgScale = 1.0;
  11.                                 bit_arr[i].num = i;
  12.                                 bit_arr[i].addEventListener(MouseEvent.MOUSE_OVER, iconOverhandler);
  13.                                 bit_arr[i].addEventListener(MouseEvent.MOUSE_OUT, iconOuthandler);
  14.                                
  15.                                
  16.                                
  17.  
  18.                                 addChild(bit_arr[i]);
  19.                                
  20.                                
  21.                         }
  22.                        
  23.                         this.addEventListener(Event.ENTER_FRAME, onEnterframehandler);         
  24.                         mid =  Math.floor(bit_arr.length/2);
  25.                         overIcon = mid;
  26.                         overbool = false;
  27.                         center = bit_arr[mid].x;
  28.                 }

  for 문을 돌려서 만들었던 icon 들의 위치를 정해 주고, addEventListener 를 해 줍니다. 여기에서 각 icon 들 마다 num 과 trgScale 을 지정하였는데, num 은 icon 이 몇번째에 위치해 있나를 알려 주는 변수 이고, trgScale 은 icon 들의 크기를 조정할때 원래 크기로 돌아 가기 위한 기준을 저장하는 변수 입니다. enterframe 으로 돌리기 위한 이벤트로 등록을 하고, icon 들 사이에서 가운데에 존재 하는 icon 을 알기 위한 overIcon 을 지정해 줍니다. 그리고 그 x 위치를 저장해 줍니다. 위의 결과물에서도 알수 있듯이, icon 의 크기와 위치가 변하고, icon 에서 RollOut 되면 다시 원래의 자리로 돌아와야 합니다.  mid 값과 overIcon, center 값을 몰랐을 경우, 신경쓰지 않았을 경우에는 다음과 같은 일이 발생합니다. 무비 클립은 dynamic class 이기 때문에 직접적인 변수 생성이 가능합니다.
참고 : http://cafe.naver.com/flashactionscript/11367


마우스 롤 오버 & 아웃

 
  1. private function iconOverhandler(event : MouseEvent) : void {
  2.                         overbool = true;
  3.                         overIcon = event.target.num;
  4.                        
  5.  }

 

 

  1. private function iconOuthandler(event : MouseEvent) : void {
  2.                        
  3.                         iconReset();
  4.                                
  5.                         overbool = false;
  6.                        
  7. }

 마우스를 icon 에 오버 하면 enterframe 에서 if 문 처리를 판단하는 overbool 변수를 true 로 해 줍니다. 초기값은 false 로 되어있었지요. 그리고 어떤 icon이 오버 되었다는것을 알려 주는 overIcon 에 event.target.num 으로 숫자를 전달해 줍니다.  

지금 부터 산수 입니다;;;;;;;

 
  1. private function onEnterframehandler(event : Event) : void {
  2.                        
  3.                                        
  4.                         for (i=overIcon+1; i < bit_arr.length; i++) {
  5.                                 bit_arr[i].x = bit_arr[i-1].x + bit_arr[i-1].width/2 + bit_arr[i].width/2;
  6.                         }
  7.                         for (i=overIcon-1; i > -1; i--) {
  8.                                                                
  9.                                 bit_arr[i].x = bit_arr[i+1].x - bit_arr[i+1].width/2 - bit_arr[i].width/2;
  10.                         }
  11.                 }   

 

 

 

위에서

  1.   overbool = true;
  2.   overIcon = event.target.num;

한 이유가 여기서 나오게 됩니다. RollOver 하는 icon 이 바뀔때 마다 계속 Enterframe 을 돌려 주고 계속 위치를 변경해 줍니다.

 
  1. private function onEnterframehandler(event : Event) : void {
  2.                        
  3.                         for (var i:int=0; i<bit_arr.length; i++) {
  4.                                
  5.                                 if (overbool)
  6.                                 {
  7.                                         var distance:int = Math.abs(bit_arr[i].x- mouseX)/2;
  8.                                         bit_arr[i].trgScale = (200-distance)/100;
  9.                                         if (bit_arr[i].trgScale < 1.0)
  10.                                         {
  11.                                                 bit_arr[i].trgScale = 1.0;
  12.                                         }
  13.                                 }
  14.                                
  15.                                 bit_arr[i].scaleX = bit_arr[i].scaleY += (bit_arr[i].trgScale-bit_arr[i].scaleX)*0.4;                          
  16.                         }                              
  17.                         for (i=overIcon+1; i < bit_arr.length; i++) {
  18.                                 bit_arr[i].x = bit_arr[i-1].x + bit_arr[i-1].width/2 + bit_arr[i].width/2;
  19.                         }
  20.                         for (i=overIcon-1; i > -1; i--) {
  21.                                                                
  22.                                 bit_arr[i].x = bit_arr[i+1].x - bit_arr[i+1].width/2 - bit_arr[i].width/2;
  23.                         }
  24.                 }       
  25.  

 

마우스의 X 위치 값과 icon 의 x 위치 값을 이용하여 distance 를 구합니다. 마우스가 멀리 있을 수록 distance 는 커지게 되고 icon 에 영향을 주게 되는 trgScale 값이 작아 지게 됩니다.  

  1. if (bit_arr[i].trgScale < 1.0)
  2. {
  3.        bit_arr[i].trgScale = 1.0;
  • }

    if 문을 이용해서 trgScale 이 원래의 scale 크기인 1.0 보다 작아 지는것을 막아 줍니다. if 문을 빼고 돌려 보세요.

    bit_arr[i].scaleX = bit_arr[i].scaleY += (bit_arr[i].trgScale-bit_arr[i].scaleX)*0.4;   

    그런후 가속도 공식을 이용하여, 크기를 변화 시켜 줍니다.
    가속도 공식 :   

    변화시키고 싶은 속성 += (원래 속성값 - 변화후 속성값)*변위(?)( 갑자기 단어가 생각이 안남 )
    ex ) this.x += ( this.x - targetX ) *0.1;   x 의 위치를 targetX 까지 변화 시킴  

    여기까지 오버 하였을때 icon 들을 변화 시켜 보았습니다. 그럼 롤 아웃 하면 ? 위에서 나왔던 iconReset() 함수를 구현해 보면

     
    1. private function iconReset():void
    2.                 {
    3.                         for (var i:int=0; i<bit_arr.length; i++) {      -------------- 1)
    4.                                 bit_arr[i].trgScale = 1.0;
    5.                         }
    6.                         overIcon = mid;                                     -------------- 2)
    7.                        
    8.                        
    9.                         bit_arr[mid].addEventListener(Event.ENTER_FRAME,mcEnterframe);            -------- 3)
    10.                 }
    11.                
    12.                 private function mcEnterframe(event : Event) : void { ----------------- 4)
    13.                         var speed:int = (center-event.target.x)*0.1;
    14.                         event.target.x += speed;
    15.                         if (Math.abs(speed)<0.01) {
    16.                                 bit_arr[mid].removeEventListener(Event.ENTER_FRAME,mcEnterframe);
    17.                         }
    18.                 }

     

    1) 모든 icon 의 scale 을 1.0 로 조절함니다. ( onEnterframe 에서 계속 돌아 가고 있기 때문에 trgScale 만 바꿔주면 됩니다 )

    2) 다시 mid 값을 가운데 위치한 icon 으로 초기화 합니다.

    3) 원래 위치로 돌아 가기 위한 mcEnterframe 를 등록합니다.  

    4) 롤 아웃이 되면 전에 있었던 center 로 가운데 있던 icon 이 이동합니다. 이 icon 만 이동 시켜도 되는 이유는 onEnterframe 에서 계속 아래 for 문이 돌아 가고 있기 때문입니다. 그리고 어느 정도 오차가 생기겠지만 speed 값이 0.01 보다 작아 지면 removeEventListener 를 해 줍니다. ( enterframe 을 계속 돌리는 것은 낭비 0.01 정도 되면 거의 변화가 느껴지지 않습니다 )

    1. private function onEnterframehandler(event : Event) : void {
    2.                        
    3.                                        
    4.                         for (i=overIcon+1; i < bit_arr.length; i++) {
    5.                                 bit_arr[i].x = bit_arr[i-1].x + bit_arr[i-1].width/2 + bit_arr[i].width/2;
    6.                         }
    7.                         for (i=overIcon-1; i > -1; i--) {
    8.                                                                
    9.                                 bit_arr[i].x = bit_arr[i+1].x - bit_arr[i+1].width/2 - bit_arr[i].width/2;
    10.                         }
    11.                 }   

    사용된 전체 코드.

     
    1. package {
    2.         import flash.display.MovieClip;
    3.         import flash.events.Event;
    4.         import flash.events.MouseEvent;
    5.         import flash.utils.Timer;
    6.         import com.pixelfumes.reflect.*;
    7.        
    8.         import icon.Cicon;     
    9.  
    10.         /**
    11.          * @author navi main
    12.          */
    13.         public class Main extends MovieClip {
    14.                
    15.                 private var overbool:Boolean;
    16.                 private var overIcon:int;
    17.                 
    18.                 private var center:int;
    19.                 private var mid:int;
    20.                 private var frametime:Timer;
    21.                 private var bit_arr:Array;
    22.                        
    23.                 public function Main() {
    24.                        
    25.                         bit_arr = new Array();
    26.                         bit_arr = [icon0,icon1,icon2,icon3,icon4];
    27.                       
    28.                                
    29.                         for (var i:int=0; i< bit_arr.length; i++) {
    30.                                
    31.                                
    32.                                 bit_arr[i].trgScale = 1.0;
    33.                                 bit_arr[i].num = i;
    34.                                 bit_arr[i].addEventListener(MouseEvent.MOUSE_OVER, iconOverhandler);
    35.                                 bit_arr[i].addEventListener(MouseEvent.MOUSE_OUT, iconOuthandler);
    36.                                
    37.                                
    38.                                 addChild(bit_arr[i]);
    39.                                
    40.                                
    41.                         }
    42.                        
    43.                         this.addEventListener(Event.ENTER_FRAME, onEnterframehandler);         
    44.                         mid =  Math.floor(bit_arr.length/2);
    45.                         overIcon = mid;
    46.                         overbool = false;
    47.                         center = bit_arr[mid].x;
    48.                 }
    49.        
    50.  
    51.                 private function iconReset():void
    52.                 {
    53.                         for (var i:int=0; i<bit_arr.length; i++) {
    54.                                 bit_arr[i].trgScale = 1.0;
    55.                         }
    56.                         overIcon = mid;
    57.                        
    58.                        
    59.                         bit_arr[mid].addEventListener(Event.ENTER_FRAME,mcEnterframe);
    60.                 }
    61.                
    62.                 private function mcEnterframe(event : Event) : void {
    63.                         var speed:int = (center-event.target.x)*0.1;
    64.                         event.target.x += speed;
    65.                         if (Math.abs(speed)<0.01) {
    66.                                 bit_arr[mid].removeEventListener(Event.ENTER_FRAME,mcEnterframe);
    67.                         }
    68.                 }
    69.  
    70.                 private function iconOuthandler(event : MouseEvent) : void {
    71.                        
    72.                         iconReset();
    73.                                
    74.                         overbool = false;
    75.                        
    76.                 }
    77.  
    78.                 private function iconOverhandler(event : MouseEvent) : void {
    79.                         overbool = true;
    80.                         overIcon = event.target.num;
    81.                        
    82.                 }
    83.                        
    84.                
    85.                 private function onEnterframehandler(event : Event) : void {
    86.                        
    87.                         for (var i:int=0; i<bit_arr.length; i++) {
    88.                                
    89.                                 if (overbool)
    90.                                 {
    91.                                         var distance:int = Math.abs(bit_arr[i].x- mouseX)/2;
    92.                                         bit_arr[i].trgScale = (200-distance)/100;
    93.                                         if (bit_arr[i].trgScale < 1.0)
    94.                                         {
    95.                                                 bit_arr[i].trgScale = 1.0;
    96.                                         }
    97.                                 }
    98.                                
    99.                                 bit_arr[i].scaleX = bit_arr[i].scaleY += (bit_arr[i].trgScale-bit_arr[i].scaleX)*0.4;                          
    100.                         }                              
    101.                         for (i=overIcon+1; i < bit_arr.length; i++) {
    102.                                 bit_arr[i].x = bit_arr[i-1].x + bit_arr[i-1].width/2 + bit_arr[i].width/2;
    103.                         }
    104.                         for (i=overIcon-1; i > -1; i--) {
    105.                                                                
    106.                                 bit_arr[i].x = bit_arr[i+1].x - bit_arr[i+1].width/2 - bit_arr[i].width/2;
    107.                         }
    108.                 }       
    109.         }
    110. }

     

    네비게이션의 경우에는 수학적인 이해가 들어 가는 부분이 많은것 같습니다. 하지만 공식처럼 쓸줄만 알면 되니깐 걱정 하진 마세요. 이번에는 한 Document class 에 다 때려 박았는데, 다음 강 부터 네비게이션을 보완하면서 2단계로 만들어 보겠습니다. 그러기 위해서는 이 하나의 클래스를 잘 이해 하고 계시는게, 2단계를 나가는데 지장이 없을꺼라 생각 됩니다.  

    다음 강에서는 클래스를 분리 하고, 좀더 이것 저것 붙여 보겠습니다. 휙휙 지나간 면이 없지 않아 있네요;; ㅋ 잘못된 점이나, 질문이 있으시면 거침 없는 댓글이나, 답글 부탁 드립니다. !! 수고하셨습니다.

     - 완료 파일 다운 받기-



  • Posted by Flash 동강
    동강의AS3.0 강좌2008.12.11 01:41

    10강을 시작으로 다룰 내용은 Flash Navigation 입니다. 플래시 메뉴라고 하면 되겠네요. 아주 간단한 메뉴에서 시작해서 xml 을 이용한 메뉴 구성 까지 계획을 하고 있습니다. 우선 적으로 알아야 할것이 Array Class 와  caurina Tweener 의 사용법을 알아야 합니다.  

     

      Array 

      Package    :loadClassListFrame('class-list.html')" href="file:///C:/Documents%20and%20Settings/All%20Users/Application%20Data/Adobe/Flash%20CS3/en/Configuration/HelpPanel/Help/ActionScriptLangRefV3/package-detail.html">Top Level
      Class            public dynamic class Array
      Inheritance  : Array -> Object

     Array 는 배열 입니다. ( 기본 속성은 레퍼런스를 참조하세요 )

     
    1. var twoArray:Array = ["z"]; 
    2.  twoArray[0] = "z";            
    3.  trace(oneArray);              
    4.  

     여기서 알고 넘어 갈 부분은 push, pop , Array 속성의 함수 입니다. push 는 배열에 넣어 주는 역할 pop 은 배열의 가장 끝에 있는 객체를 반환에 주는 함수 입니다.

      

      push 예제  a,b,c String 을 letters 에 넣어 주고 toString 으로 확인해 봅니다.

    1. var letters:Array = new Array();
    2.  
    3. letters.push("a");
    4. letters.push("b");
    5. letters.push("c");
    6.  
    7. trace(letters.toString()); // a,b,c

     

     

     pop 예제  // 자료구조에서 pop 과 의미가 같다. 배열의 가장 뒤에 있는 객체를 반환한다. (반환된 객체를 받지 않으면

     소멸 된다 )

    1. var letters:Array = new Array("a", "b", "c");
    2. trace(letters); // a,b,c
    3. var letter:String = letters.pop();
    4. trace(letters); // a,b
    5. trace(letter);     // c

     

     
    1. var mc:MovieClip = new MovieClip();
    2. var a_arr:Array = new Array();
    3. var b_arr:Array = new Array();
    4.  
    5. a_arr[0] = mc;
    6. b_arr[0] = mc;
    7.  
    8. trace("a_arr[0] : "+a_arr[0].name);
    9. trace("b_arr[0] : "+b_arr[0].name);
    10.  

    1. a_arr[0] = mc;
    2. b_arr[0] = mc;

    이 부분을 a_arr.push(mc);  b_arr.push(mc) 로 해도 같은 결과가 출력됩니다. 요지는, Array 의 사용에 있어서 push 와 pop 을 잘 활용 해야 된다는 점 입니다. push 와 [0] = mc 로 인해 배열에 저장되는 값은 실체 그 객체가 아니라, 그 객체가 저장되어 있는 주소 값이 라고 생각하시면 될것 같습니다. 지금까지는 언급하지 않았지만 , 배열을 사용할때 Actionscript 에서의 메모리 문제를 잘 이해 하시고 사용하셔야 됩니다. 우선 Actionscript 에서의 메모리 참조 해제 방식은 Flash Player 에 있는 가비지 콜렉션  이 관장을 하고 있습니다. 가비지 콜렉션이란, 뜻 그대로 쓰레기 값들을 모아 준다는 말입니다. 일반적으로 Java 에서는 객체 = null 하면 메모리가 바로 해제 되는 경우였지만 플레시 에서는 조금 다름이다. 예제를 보면

     
    1. var mc:MovieClip = new MovieClip();
    2. mc = null;
    3.  

     mc 라는 무비 클립의 메모리가 바로 해제 되는 것이 아니라, 가비지 콜렉션의 수집 대상이 되는 것입니다. ( 수집이 완료된 후에 메모리 해제가 일어 나는 것이지요 ) 이 경우는 addEventListener 의 경우에서도 똑같이 적용 됩니다.   

    addEventListener () 메서드  

    public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
     
    마지막 파라미터 값인 useWeakReference 로 인해  리스너에 대한 참조가 강한지 아니면 약한지를 결정합니다. 강한 참조(기본값)는 해당 리스너의 가비지 수집을 막습니다. 약한 참조는 이를 막지 못합니다.
     
    addEventListener 을 하고 removeEventListener 를 해 줬다고 해서 메모리가 바로 해제 되는 것은 아니라는 점입니다. 일반 적으로 addEventListener 를 사용할때 두 가지 파라 미터만 쓰는 경우가 많은데 이 경우도 알아 놓으시기 바람니다.
     
    한가지의 예제를 더 보면
     
    1. var mc:MovieClip = new MovieClip();
    2. addChild(mc);
    3. var a_arr:Array = new Array();
    4. var b_arr:Array = new Array();
    5.  
    6. a_arr[0] = mc;
    7. b_arr[0] = mc;
    8.  
    9. mc = null;
    10.  
    11. trace("a_arr[0] : "+a_arr[0].name);
    12. trace("b_arr[0] : "+b_arr[0].name);
    13.  
    14. output
    15. a_arr[0] : instance1
      b_arr[0] : instance1
    16.  
     
    1. var mc:MovieClip = new MovieClip();
    2. addChild(mc);
    3. var a_arr:Array = new Array();
    4. var b_arr:Array = new Array();
    5.  
    6. a_arr[0] = mc;
    7. b_arr[0] = mc;
    8.  
    9. mc = null;
    10. a_arr[0] = null;
    11. b_arr[0] = null;
    12. trace("a_arr[0] : "+a_arr[0].name);
    13. trace("b_arr[0] : "+b_arr[0].name);
    14.  
    15. output
    16. TypeError: Error #1009: null 객체 참조의 속성이나 메서드에 액세스할 수 없습니다.
       at Untitled_fla::MainTimeline/frame1()

     mc = null 로 객체의 주소 값에 대한 참조를 삭제 하긴 했지만

    1. a_arr[0] = mc;
    2. b_arr[0] = mc;

    여기에서 새로운 참조가 생겨 가비지 콜렉션의 수집을 막게 됩니다. 수집대상으로 만들기 위해서는 모든 연결을 없애 주어야 겠지요?

    요지는 쓸대 없는 객체의  = null 을 생활화 하자 입니다. 어려운 내용이니 계속 반복해서 보세요.  

    가비지 콜렉션의 자세한 내용은 : http://memolog.blog.naver.com/dongkang0626/38
     
    Caurina Tweener
    caurina 트위너는 Google code 에 업댓 되고 있는 AS2.0, AS3.0 트윈 클래스 입니다.    

    클래스원본위치

    http://code.google.com/p/tweener/  

    사용을 위해서는 우선 caurina 패치지를 다운 받으시고, (첨부 파일) fla 나 as 파일이 있는 곳에 압축을 풀어 놓으심니다. 그후

    import caurina.transitions.Tweener;               // 클래스를 사용하기 위한 import

    여기에서 import 를 잘못해서 헤매시는 분이 있는데, fla 이 만들어져 있는 폴더에 caurina 폴더가 함께 있으면 됩니다.  

     

    아주 간단한 사용법

    Tweener.addTween(myMovieClip, {속성이 들어감});

    myMovieClip 은 무비 클립 이름입니다 (지금까지 무비 클립의 이름을 지정해서 사용했던 방법으로 입력하면 됨)

    그리고 트위너 자체에서 제공 하고 있는 엄청난 종류의 속성들

    x , y , width ,height , scaleX, scaleY , alpha , _bezier:[],time, onComplete:,onCompleteParams:[],onStart:,onUpdate, rotation,delay, 등등.

     

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

    onCompleteParams:[], onComplete 함수 지정시 넘길 파라미터를 지정해 준다.(onStart 와 onUpdate로 똑같이적용)

     

    _bezier: [] 이동할때 베지어 곡선을 만들기 위한 점을 지정해 준다.

    time : 변화가 진행되는 시간을 정해준다.

    delay : 명령문이 실행되고, delay: 몇초 가 흐른 뒤에 해당 명령문을 실행 시켜 준다.

     

    transition:"" 변화 진행되는 그래프를 지정해 준다.

     

     
     그럼 사용해 보겠습니다. circle_mc 무비 클립을 만들고,

     
    1. import caurina.transitions.Tweener;
    2.  
    3. Tweener.addTween(circle_mc,{x:300,y:300,time:2.0,transition:"easeoutinelastic"});

     Flash 자체의 Tween 과 다르게 한번에 여러 속성을 변경 시킬수 있습니다. 해당 속성에 들어 가는 값은 목표치 즉, 변경 하고자 하는 결과 위치를 나타 냄니다. 괴물투수 형님이 쓰신 팁을 인용하면

     

     

    간단히 사용해보기

    <A>

    Tweener.addTween(myObject , {x:20, time:1, transition:"easeOut"});

     

    <B>

    Tweener.addTween(myObject , {_frame:20, time:1, transition:"easeOut"});

     

    간단한 설명

    이것은 기본적으로 1. 바꾸고 싶은 것과 바꾸고 싶은것의 2. 목표치를 적어넣음으로써 작동합니다.

     

    위의 <A>에서 바꾸고 싶은건 x 좌표이고 목표치는 20이 되겠고

    <B>에서는 바꾸고 싶은건 프레임이고 가고 싶은 프레임은 20프레임이 되겠네요

     

    그리고 뒤의 time은 이동하는 시간이고 뒤의 transitions는 운동의 느낌을 나타냅니다.

     

    <A>

    x는 myObject 이놈이 원래 가지고 있는 속성입니다.

    myObject가 무비클립이라면 x , y , alpha , width , height 등등이 되겠죠?

     

    <B>

    여기서 _frame은 myObject란 놈이 원래 가지고 있는 속성이 아닙니다

    이것은 google tweener에서 스페셜하게도 제공하는 스페셜한 special properties인 것입니다

    frame , color , sound 등등이 있고 사용은 동일하게 하되 ,

    속성명 앞에 _(언더바)가 붙는 특징이 있습니다.

     

     

     
    1. import caurina.transitions.Tweener;
    2.  
    3. startfunc(circle_mc);
    4.  
    5. function startfunc(_mc:MovieClip):void
    6. {
    7.         Tweener.addTween(_mc,{onComplete:completefunc,onCompleteParams:[_mc],scaleX:5.0,scaleY:5.0,time:2.0,transition:"easeoutinelastic"});
    8. }
    9. function completefunc(_mc:MovieClip):void
    10. {
    11.         trace("트윈종료 : "+_mc);
    12. }

     

    참 쉽지요? ;;; 

    저는 Tween 보다 caurina 를 자주 사용 한담니다. 그 만큼 편하고, 속도도 나름(?) 괜찬게 나오는 좋은 녀석입니다. 지금까지 네비게이션을 만들기 위한 기초 부분에 대해 써 보았습니다. 다음에는 iMac navigation 디자인 및, 구현 방법, 프로토 타입을 만들어 보도록 하겠습니다.   

    이제 3월 18일이면 AIR 가 우리나라에서도 정식으로 나오게 되고, Flex 3 도 런칭이 되게 됩니다. 이 말은 Actionscript 3.0 이 더이상 Flash Flex 만을 위한 조금한 일부분을 벗어나 RIA 의 선두 주자로의 도약을 시작할것이라 생각됩니다. 많은 분들이 Actionscript 3.0 은 선택이 아니라, 필수라는 말을 하심니다. 이제 그 말이 현실이 되어 나타 나고 있습니다. 곧 Adobe 에서 디자이너와 개발자의 협업을 위한

    "Thermo"(http://labs.adobe.com/wiki/index.php/Thermo) 가 출시 될 것이고, Actionscript3.0 의 중요성은 더욱 강조될 것입니다.  

    Adobe 에서 이렇게 발빠르게 움직이고 있는데, 쓰는 사람이 가만히 있을수는 없겠지요??

    "자 공부 합시다. 그리고 삽질 합시다."

    역시나 잘못된 부분이나, 질문 사항 거침 없이 댓글 부탁드립니다. 



    Posted by Flash 동강
    동강의AS3.0 강좌2008.12.11 01:37

    스터디에서 같이 해보게 될 이미지 슬라이드  소스 파일 입니다.
    3가지 클래스를 메인으로 사용하고 있습니다.    

    1. Tween
    2. Loader
    3. Timer 

    지금까지의 강좌에서 계속 사용해 왔고, 언급했으므로 소스를 파악하시기엔 무리가 없을듯 합니다.
    중점적으로 볼 부분에는 강조를 해 놓았으니 그 부분에 대해 어떤 구조로 이미지가 돌아가고 있구나 정도 파악하시고 참여 하시면 됩니다. 소스를 미리 올리는 이유는 로직적으로 이해하기 어려운 부분이 포함되어 있기 때문에  미리 올리는 것이니 꼭 꼭 실행 시켜 보세요.   

     CustomMain.as ( Document class)

     
    1. package {
    2.        
    3.         import flash.display.MovieClip;
    4.         import flash.utils.Timer;
    5.         import fl.transitions.Tween;
    6.         import fl.transitions.easing.*;
    7.         import Circle;
    8.                
    9.         import flash.events.TimerEvent;
    10.  
    11.                
    12.         public class CustomMain extends MovieClip
    13.         {
    14.                 private var frame_arr:Array;
    15.                 private var frame_time:Timer;
    16.                 private var frame_num:int;
    17.                
    18.                 private var position_arr:Array;
    19.                
    20.                 public function CustomMain():void
    21.                 {
    22.                          frame_num = -1;
    23.                          frame_arr = new Array();
    24.                          position_arr = [-500,0,500];
    25.                          frame_arr[0] = new Circle(-500,0);
    26.                          frame_arr[1] = new Circle(-500,0);
    27.                          frame_arr[2] = new Circle(-500,0);
    28.                                                  
    29.                                                  
    30.                                                  frame_arr[0].loadimage("http://dongkang.ivyro.net/data/image.jpg");
    31.                                                  frame_arr[1].loadimage("http://dongkang.ivyro.net/data/image2.jpg");
    32.                                                  frame_arr[2].loadimage("http://dongkang.ivyro.net/data/image3.jpg");
    33.                                                  
    34.                          addChild(frame_arr[0]);
    35.                          addChild(frame_arr[1]);
    36.                          addChild(frame_arr[2]);
    37.                          
    38.                          frame_time = new Timer(3000);
    39.                          frame_time.start();
    40.                          frame_time.addEventListener("timer",frametimehandler);
    41.              
    42.                 }
    43.                 private function frametimehandler(e:TimerEvent):void
    44.                 {              
    45.                                
    46.                                                
    47.                         if(frame_num == -1)
    48.                         {
    49.                             new Tween(frame_arr[0],"x",Strong.easeInOut,frame_arr[0].x,position_arr[1],20,false);  
    50.                                                        
    51.                         }
    52.                         else
    53.                         {       
    54.                                                        
    55.                                                         var targetF:int = frame_num%3;
    56.                                                         var targetB:int = (frame_num+1)%3;
    57.                                                         trace(targetB);
    58.                                                        
    59.                       new Tween(frame_arr[targetF],"x",Strong.easeInOut,position_arr[1],position_arr[2],20,false);      
    60.                       new Tween(frame_arr[targetB],"x",Strong.easeInOut,position_arr[0],position_arr[1],20,false);
    61.                                                        
    62.                            
    63.                                
    64.                         }
    65.                                                 frame_num++;
    66.                                                
    67.                        
    68.                        
    69.                 }              
    70.                
    71.         }
    72.        
    73.        
    74. }

     

     Circle.as
     
    1. package {
    2.         import flash.display.DisplayObject;
    3.         import flash.display.Loader;
    4.         import flash.display.MovieClip;
    5.         import flash.events.Event;
    6.         import flash.net.URLRequest;   
    7.  
    8.         public class Circle extends MovieClip {
    9.  
    10.                 public function Circle(xn:int,yn:int):void {
    11.                         this.x = xn;
    12.                         this.y = yn;
    13.  
    14.  
    15.                 }
    16.                 public function loadimage(url:String):void {
    17.  
    18.                         var ld:Loader = new Loader();
    19.                         ld.load(new URLRequest(url));
    20.                         ld.contentLoaderInfo.addEventListener(Event.COMPLETE, onldComplete);
    21.                         addChild(ld);
    22.  
    23.                 }
    24.                 public function onldComplete(e:Event):void
    25.                 {
    26.                          var mObject:DisplayObject = e.target.content;
    27.              mObject.width=500;
    28.              mObject.height=450;               
    29.                 }
    30.                
    31.         }
    32. }

     

    Posted by Flash 동강
    동강의AS3.0 강좌2008.12.11 01:36

    요즘엔 구글링을 하면서, 이 사이트 저 사이트 많이 돌아 다니고 있는데, 정말 세상을 넓고, 대단한 사람들은 많다 라고 세삼 느껴지네요.  

    월요일 입니다. 다들 피곤하시져?? 주말에도 일하신 분들도 있으실테고, 주말 동안 푹 쉬신 분들도 있을 겁니다.  월요일이고, 새롭게 시작하는 느낌으로 일주일을 시작하는것도 좋을듯 싶습니다.  

    이번에 볼 내용은 Timer class 와 Loader class 입니다. 두 클래스 모두 강력한 기능으로 작업의 능률을 높여 주는 그런 클래스들 입니다. 우선 Timer class 부터 레퍼런스를 살펴 봅시다.  

     Timer 

    클래스  public class Timer
    상속 Timer  EventDispatcher  Object

    언어 버전 :  ActionScript 3.0
    Player 버전 :  Flash Player 9

     

     
      Timer(delay:Number, repeatCount:int = 0)
      지정된 지연 및 반복 횟수 상태를 사용하여 새 Timer 객체를 만듭니다.  
     
    1. var time:Timer = new Timer(1000,5);
    2. time.start();

      delay 시간은 ms 단위로 합니다. 1000 = 1초가 되는 거지요. repeatCount 는 이 timer을 몇번 반복해서 실행 시키겠는가?

      위에서는 5번 실행 시키고 실행을 중단하게 됩니다.

     꼭 start() 를 해줘야 시작이 되고, 멈추는건 stop(); 으로 멈출수 있습니다. 그러면 저거 두개만 으로 어떻게 Timer 를 활용하는가? 보통 TimerEvent 라는 Timer 가 가지고 있는 기본 이벤트와 함께 사용됩니다.

     

     
    1. package{
    2.        
    3.         import flash.display.Sprite;                  
    4.         import flash.events.TimerEvent;                // 기본 import
    5.         import flash.utils.Timer;
    6.        
    7.         public class TimerExample extends Sprite
    8.         {
    9.                 private var time:Timer;                   // 객체 정의
    10.                
    11.                 public function TimerExample():void
    12.                 {
    13.                         time = new Timer(1000,5);
    14.                         time.start();
    15.                         time.addEventListener(TimerEvent.TIMER,ontimerhandler);
    16.                         time.addEventListener(TimerEvent.TIMER_COMPLETE,onCompletehandler);
    17.                
    18.                 }
    19.                 private function ontimerhandler(event:TimerEvent):void
    20.                 {
    21.                         trace("1초");
    22.                        
    23.                 }
    24.                 private function onCompletehandler(event:TimerEvent):void
    25.                 {
    26.                         trace("타임 끝");
    27.                 }
    28.                
    29.         }
    30. }

     

    time.addEventListener(TimerEvent.TIMER,ontimerhandler);
    1초 마다 실행되는 함수를 정의합니다. 지정한 시간에 호출되는 함수를 정의(이벤트를 생성시켜줌)

    time.addEventListener(TimerEvent.TIMER_COMPLETE,onCompletehandler);
    time 이 모두 실행 된 후에 실행되는 함수를 지정 (이벤트를 생성시켜줌)

    //output

    1초
    1초
    1초
    1초
    1초
    타임 끝

    우리가 쓰고 있는 enterframe 이 fps 단위로 실행되는 반면, Timer 는 초 단위로 실행 됩니다. Timer 가 enterframe 에 비해서 정확할수 있다고 말하는것도 여기에 있는듯 합니다. 다른 속성도 있으나 잘 쓰이지 않으므로 레퍼런스를 한번 보시는것도 좋을듯  싶습니다.

     

     Loader

     

     
      클래스 public class Loader
      상속 Loader  DisplayObjectContainer InteractiveObject  DisplayObject  EventDispatcher  Object

     

     
     Loader()
     SWF, JPEG, GIF 또는 PNG 파일 등을 로드하는 데 사용할 수 있는 Loader 객체를 만듭니다.
     
     
    1. var ld:Loader = new Loader();
    2. ld.load(new URLRequest("image.jpg"));

     ld 라는 로더를 만들어서 URLRequest 로 정의된 주소값의 jpg나 gif png swf 파일을 로드 합니다.

     

    참고 ) URLRequest

    URLRequest 클래스는 하나의 HTTP 요청에 포함된 모든 정보를 캡처합니다.

    말이 어려워지므로, 걍 주소를 정의하기 위해서는 URLRequest 타입으로 해야 된다는것만 알아 주세요

    (2.0 과의 차이점입니다. )

     

     

     
    1. package{
    2.        
    3.         import flash.display.Sprite;
    4.         import flash.display.Loader;
    5.         import flash.events.*;
    6.         import flash.net.URLRequest;
    7.         import flash.display.DisplayObject;
    8.  
    9.         public class LoaderExample extends Sprite{
    10.                
    11.                 private var ld:Loader;
    12.                
    13.                 public function LoaderExample():void
    14.                 {
    15.                         ld = new Loader();
    16.                         var url:URLRequest = new URLRequest("image.jpg");
    17.                         ld.load(url);
    18.                         ld.contentLoaderInfo.addEventListener(Event.COMPLETE, completehandler);
    19.                         ld.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progresshandler);
    20.                        
    21.                         addChild(ld);                  
    22.                 }
    23.                 private function completehandler(event:Event):void
    24.                 {
    25.                          var mObject:DisplayObject = event.target.content;
    26.                          mObject.width=100;
    27.                          mObject.height=100;
    28.                        
    29.                 }
    30.                 private function progresshandler(event:ProgressEvent):void
    31.                 {
    32.                         var mPercent:Number =int( event.bytesLoaded/event.bytesTotal*100.0);
    33.  
    34.                         trace(mPercent);
    35.                 }
    36.                
    37.         }
    38.        
    39. }

     

    같은 폴더에 image.jpg 라는 파일이 있어야 로드가 됩니다. 없으면 URL 에러를 일으킴니다.

     

    //output

    로드중
    로드중
    로드중
    로드중
    로드끝

     

    여기서 contentLoaderInfo 는 뭔가?

      contentLoaderInfo : LoaderInfo
    [read-only] 로드 중인 객체에 해당하는 LoaderInfo 객체를 반환합니다.
     

    LoaderInfo 란 Loader 에 의해 불러와지는 데이터의 정보 입니다. 예를 들면 jpg 이미지라면 크기 (width, height 가 있겠지요?)

    Loader 는 이러한 LoaderInfo 를 참조하여 그 값들을 변경할수 있습니다. 어쩌피 이미지가 swf 파일이 로드 되는 것도 bitmapdata 를 거쳐서 들어 오는것이기 때문에 변환이 가능합니다. ( 하지만 크로스 브라우징 문제가 발생할수도 있습니다 )

     

    1.  
    2. package{
    3.        
    4.         import flash.display.Sprite;
    5.         import flash.display.Loader;
    6.           import flash.display.DisplayObject;
    7.         import flash.events.*;
    8.     import flash.net.URLRequest;
    9.  
    10.         public class LoaderExample extends Sprite{
    11.                
    12.                 private var ld:Loader;
    13.                
    14.                 public function LoaderExample():void
    15.                 {
    16.                         ld = new Loader();
    17.                         var url:URLRequest = new URLRequest("image.jpg");
    18.                         ld.load(url);
    19.                         ld.contentLoaderInfo.addEventListener(Event.COMPLETE, completehandler);
    20.                         ld.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progresshandler);
    21.                        
    22.                         addChild(ld);                  
    23.                 }
    24.                 private function completehandler(event:Event):void
    25.                 {
    26.                          var mObject:DisplayObject = event.target.content;
    27.                          mObject.width=100;
    28.                          mObject.height=100;              // 로드된 이미지는 100 / 100 으로 사이즈 변경
    29.                        
    30.  
    31.                 }
    32.                 private function progresshandler(event:ProgressEvent):void
    33.                 {
    34.                         var mPercent:Number =int( event.bytesLoaded/event.bytesTotal*100.0);
    35.  
    36.                         trace(mPercent);                // 로드 되는 과정을 알수 있다.
    37.                 }
    38.  
    39.                
    40.         }
    41.        
    42. }

     

    위의 completehandler 함수에서는 event.target.content 로 정보를 받은 뒤 변경을 해 주게 되고 progresshandler 에서는 byteLoaded 를 이용해서 실시간 로드된 값을 알수 있습니다. 이것을 이용해서 로딩 바를 만들수 있습니다.  앞으로 만들어 볼것의 기본이 되는 두 클래스를 설명해 보았습니다. 잘 이해 안되는 부분은 질문 날려 주시고요 . 잘못된 부분이나 추가 내용은 댓글이나 답글 달아 주세요. 이 공간의 저 만의 강좌 공간이 아니라, 강좌라는 주제에 대해 토의하는 공간입니다. 쑥스러워 하지 마시고, 참여 부탁드립니다. 그럼 두 클래스를 이용한 간단한 해보기 입니다.  

    1. 5장의 이미지를 준비

    2. 배열에 5장의 이미지를 저장

    3. Timer class 를 이용해 2초에 한번씩 로드 되는 겔러리를 만든다.   

    겔러리를 만들면서 Ctrl + Alt + del 을 눌러 메모리가 늘어 나는 상황을 관찰해 봅시다! 기초 스터디 팀에게는 미리 낸 해보기라, 미리 올라온 소스를 참고해 보시는것도 좋을듯 합니다. 다하신 분들은 꼭 메모리가 늘어 나는 상황을 관찰해 보시기 바람니다.   

    수고 하셨습니다. 기분좋은 한주 시작 하세요!

     

    Posted by Flash 동강
    동강의AS3.0 강좌2008.12.11 01:32

    자주 올린다고 했는데, 속도가 더디네요.ㅋㅋ 졸업 시즌이다 보니 친구들 졸업식에 갔다 오게 되고, 오늘은 친형 졸업식에 갔다 왔담니다;; 크헐...... 날씨도 많이 풀리고, 학기가 시작한다고 생각하니;; 머리에 쥐가 날꺼 같은;; 으악!!!!!  

    오늘은 기초스터디를 하고 있는 것과 이어서 " 사용자 정의 클래스 " 에 대해 간단히 하는 방법을 알아 보고

    "내가 만든 클래스를 사용한다" 라는 주제로 시작해 보겠습니다.   

    우선 5강 동적 생성 부분에서 Linkage 로 객체를 정의 해서 Linkage Properties 창에서  Class 에 이름을 입력을 하는것으로 내가 스테이지에 그린 객체가 클래스로 정의 된다는 것을 알았습니다 

    (잘 기억 안나시면 http://cafe.naver.com/flashactionscript/12025 되돌아 가보시는것도 좋습니다 )  

    그럼 내가 클래스를 만들었는데, 그 클래스의 속성을 지정할수 없는가? 이 객체에 속성을 추가해 보고 싶다. 어떻게 해야 될까요?

    단순 Frame 액션에서는 어떻게 하는지 감이 오셨을 것입니다. 제가 말하고 있는 건 Linkage 로 Circle 이라는 클래스를 만들었을때, 이 객체를 어떻게 사용하는지는 알겠는데, 속성을 어떻게 추가 할것인가 하는 것입니다.

    어떻게 하시겠어요? Frame 액션에서는 이렇게 해 왔습니다.

     

     // circle frame 액션으로 적용
    1. var cir:Circle = new Circle();
    2. cir.x = 100;
    3. cir.y = 100;
    4. cir.alpha = 0.8;
    5. cir.width = 200;
    6. cir.height = 100;
    7. addChild(cir);
    8.  
    9. // 마우스 이벤트를 추가 하려면
    10. cir.addEventListener(MouseEvent.CLICK, fcirdownhandler);
    11.  
    12. function fcirdownhandler(event:MouseEvent):void
    13. {
    14.         trace("마우스 다운이랑께");
    15.        
    16.        
    17. }

     

    지금부터 사용하고자 하는 사용자 정의 클래스는 위의 액션과 똑같은 작용을 합니다. 그런데 구지 클래스로 만들어서 사용하려고 하는가? 우선은 습관이라고 말해 드리고 싶습니다. 단순 100줄도 안되는 액션 코드에서는 자신이 알아 볼수 있다면 frame 액션에 때려 박고, 사용하셔도 상관없습니다. 하지만 코드가 500~ 1000줄 10000줄까지 가면 어떻게 하시겠어요? Ctrl + F 조낸 눌러 가면서 일일이 변수명 확인해서 사용하는게 좋을까요 ? 아님 클래스를 따로 만들어서 관리 하시는게  좋으시겠어요? 선택은 자유지만, 전 필수라고 생각이 됩니다. 그 밖에도 무궁 무진한 장점들이 있으니 절 믿고 따라와 보세욜.

    이제 클래스 파일을 만들어 보겠습니다.

    메뉴의 File - New - Actionscript File 을 클릭 하세요.

    우선은 클래스를 만들기 위한 기본 구조 부터 익히겠습니다.

     
    1. package {
    2.        
    3.         import flash.display.MovieClip;
    4.         /* import 를 정의하는 부분 입니다.
    5.         import 란 이 package 안에서 사용되어질 다른 클래스들을 불러 오기 위한 부분입니다
    6.         C 에서는 include 라고 생각하시면 되겠고 자바랑은 똑같습니다.
    7.         보통 Flash fla 파일에서는 무비 클립과 같은 클래스들은 import 를 하지 않아도 사용이 가능하지만
    8.         여기에서는 import 를 해야 사용이 가능합니다. 아무 것도 없는 상태에서 하나하나 불러서 써야
    9.         사용할수 있는 것입니다
    10.         */
    11.        
    12.         public class Circle extends MovieClip{
    13. extends MovieClip 을 왜 해주는가? 구지 MovieClip 으로 안하고 Sprite로
    14. 하는 방법도 있지만 우선은 우리가 정의한 것이 MovieClip 이니 MovieClip
    15. 을 상속받아야 정의가 가능합니다.
    16.        
    17.                 // 클래스의 메인이 되는 부분 전역 변수를 여기에 선언합니다.
    18.                 public function Circle():void
    19.                 {
    20.                         /*
    21.                         클래스의 생성자 라는 부분입니다. 함수이름은 클래스 이름과 동일하게 작성해야
    22.                         이 해당 클래스의 생성자로 적용이 되게됩니다. 생성자란 무엇인가?
    23.                         사용자가 Circle 이라는 클래스를 만들었을때 바로 호출되는 부분입니다. 이 생성자에서
    24.                         이 클래스의 속성을 지정할수 있고, 처음으로 해야 되는 부분을 모두 여기에서
    25.                         정의하고 사용하게 됩니다
    26.                         */
    27.                          
    28.                         trace("생성");
    29.                        
    30.                 }
    31.                
    32.                
    33.         }
    34.        
    35.        
    36. }

     

    그리고 클래스 파일명은 Document 파일및 fla파일을 저장한 같은 폴더 안에 클래스 이름과 같은 이름으로 저장합니다

    (여기 에서는 Circle.as 입니다) 

    그리고 전 시간에 만들어보았던 Document 클래스를 fla 파일에 연결 시켜 봅시다.

     
    1. package {
    2.        
    3.         import flash.display.MovieClip;
    4.                
    5.         public class CustomMain extends MovieClip
    6.         {
    7.        
    8.                 public function CustomMain():void
    9.                 {
    10.                         var cir:Circle = new Circle();
    11.                         addChild(cir);
    12.                        
    13.                 }
    14.                
    15.                
    16.         }
    17.        
    18.        
    19. }

     

    // output

    생성  

    그동안 Document 클래스 사용법은 숙지 하셨지요? 기억 안나시면 6강으로...................
    그럼 위의 frame 액션으로 추가 시켜 줬던 Circle 에 대한 속성은 어떻게 정의해 줄까요?? 아주 간단합니다.

     
    1. package {
    2.  
    3.         import flash.display.MovieClip;
    4.         import flash.events.MouseEvent;
    5.         public class Circle extends MovieClip {
    6.  
    7.                 public function Circle():void {
    8.                         trace("생성");
    9.                         this.x = 100;
    10.                         this.y = 100;
    11.                         this.alpha = 0.8;
    12.                         this.width = 200;
    13.                         this.height = 100;
    14.  
    15.                         this.addEventListener(MouseEvent.CLICK, fcirdownhandler);
    16.  
    17.  
    18.                 }
    19.                 public function fcirdownhandler(event:MouseEvent):void {
    20.                         trace("마우스 다운이랑께");
    21.  
    22.                 }
    23.         }
    24. }

     

    여기서 this 란 Circle 이란 클래스 자기 자신의 의미 합니다. 그러니 자기 자신에게 속성을 추가해 주는것이지요. 정말 간단하죠? 지금까지 as 파일 2 개 fla 파일 1개가 생성되었습니다.  function 앞에 public 이나 private 로 정의를 하고 있는데, 우선은 모두 public 으로 해도 무방합니다. 클래스의 개념을 좀더 추가해 주면서 설명하도록 하겠습니다.   

    어찌 파일이 좀 깔끔해 졌다 라는 것을 느끼고 계신가요??  이것으로 [Base 강좌] 에서 이론에 대한 부분중 큰 가닥은 잡은것 같습니다.  늘 하는 얘기지만 어렵다고 생각하시는 분들이 많으실꺼라 봄니다. 하지만 이게 3.0 의 아주아주아주 기초중에 기초 라는 점을 알아 두셨으면 좋겠습니다. 앞으로 엄청난 기능을 자랑하는 내장 클래스들과, 우수한 개발자들이 만들어 놓은 클래스를 활용할 수 있게 되기 위해서는 아직 갈길이 많이 남아 있습니다. 기초 부터 탄탄히 라고, 하나하나 스텝을 밟아 가시기 바람니다.   

    앞으로는 실습을 중심으로 이론을 추가해 나아가면서 Base에 살을 붙여 나가도록 하겠습니다. 수고 하셨습니다.

    다음 강에 뵙겠습니다. 안뇽~ 

     

    역시 틀린 부분이나 질문 거침없는 답글 댓글 부탁드립니다. (해보기는 없습니다;;;;;  아싸! )