[AS3] argument 오브젝트

Programming/ActionScript 3.0 2007. 7. 6. 08:34
argument 오브젝트

디폴트 값으로 지정되어 있지 않은 인수를 생략 하고 함수를 호출하려고 하면 컴파일러가 에러를 돌려준다. 또 선언되고 있는 것보다 많은 인수를 지정하여 호출하는 경우도 compile error가 되지만  둘 모두 실행은 된다.

인수에 액세스 하기 위해서는 arguments라고 하는 오브젝트를 사용할 수 있다. 이것은 선언 없음으로 함수 내에서 참조할 수 있는 오브젝트로 건네 받은 인수의 배열이라고 부르며 오브젝트 (arguments.callee)를 프롭퍼티로서 가지고 있다. 인수명에 arguments이 사용되고 있는 함수 내에서는 arguments는 그 인수를 가리키게 되어 arguments 오브젝트를 사용할 수 없게 된다.

arguments 오브젝트는 아래와 같은 재귀 함수에서 처럼 편리하게 이용할 수 있다.
var factirial:Function = function(x:int):int {
if (x == 0) {
return 1;
} else {
return (x * arguments.callee(x - 1));
}
}

인수의 수가 결정되지 않은 경우는 compile error를 무시하고 함수를 호출하지 않으면 안 된다는 것은 좋지 않다. 그래서 AS3 에는 arguments를 대신하는 다음과 같은 기능이 준비되어 있다.

「... 」 인수

AS3의 마지막 인수로서 「... + 임의의 이름」을 지정하면 정의된 수 이상의 인수를 건네줄 수 있게 된다. 명시적으로 이름이 지정되어 있지 않은 인수는 「임의의 이름」으로 지정된 이름을 가지는 배열로서 사용할 수 있다. 아래의 예에서는 rest라고 하는 배열에 2 와 3을 전달한다.
function sampFunc(x:int, ... rest) {
if (rest.length > 0) {
trace(rest[0];
}
}
// 2가 출력된다.
sampFunc(1, 2, 3);

arguments 오브젝트와 달리 이 방법으로 하면 컴파일러도 불만이 없다. 함수 정의로부터 인수의 수를 정하지 않았다는 것을 컴파일러는 인지할 수 있게 된다. 사전에 인수의 수를 특정할 수 없는 경우는 「... 」 의 사용을 추천한다. 단,「... 」이 지정되어 있으면 arguments 오브젝트는 사용할 수 없다.

    

설정

트랙백

댓글

[AS3] URLVariables 클래스

Programming/ActionScript 3.0 2007. 7. 6. 06:55
URLVariables 클래스
public 함수 URLVariables(source:String = null)

새로 URLVariables 오브젝트를 작성한다. URLVariables 오브젝트를 URLRequest 오브젝트의 data 프롭퍼티에 건네준다.

스트링과 함께 URLVariables constructor을 호출하면 decode() 메소드가 자동적으로 실행되고 그 스트링이 URLVariables 오브젝트의 프롭퍼티로 변환된다.

파라미터
    source:String (default = null) —URL encode 된 스트링.


decode() 메소드
public function decode(source:String):void

변수 스트링을 지정하면 URLVariables 오브젝트의 프롭퍼티로 변환된다.

이 메소드는 URLVariables 이벤트에 의해서 내부적으로 사용된다. 대부분의 경우 유저가 직접 이 메소드를 호출할 필요는 없다.

다음의 예에서는 http://www.[yourDomain].com/application.jsp로 호스트 되는 리모트 어플리케이션을 열어서 URLVariables 오브젝트로 받는 유저 세션에 관한 데이터를 어플리케이션에 건네준다.

이 예의 내용은 다음과 같다.

   1. constructor함수는 request라는 이름의 리모트 어플리케이션의 URL을 파라미터로 취득하는  URLRequest 인스턴스를 작성한다.
   2. URLVariables 오브젝트를 작성하고 2개의 프롭퍼티에 값을 할당한다.
   3. URLVariables 오브젝트가 URLRequest 오브젝트의 data 프롭퍼티에 할당한다.
   4. navigateToURL를 호출하고 새로운 브라우저 윈도우를 열어서 리모트 어플리케이션의 URL에 접속한다.

메모 : 이 예를 실행하려면 리모트 어플리케이션의 URL을 실제의 URL로 바꿀 필요가 있다. 또한 URLVariables 오브젝트의 Flash Player가 보낸 정보를 처리하기 위한 서버 코드가 필요하다.
package {
import flash.display.Sprite;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.net.URLVariables;

public class URLVariablesExample extends Sprite {

public function URLVariablesExample() {
var url:String = "http://www.[yourDomain].com/application.jsp";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
variables.exampleSessionId = new Date().getTime();
variables.exampleUserLabel = "guest";
request.data = variables;
navigateToURL(request);
}
}}


    

설정

트랙백

댓글

[AS3] URLLoader 클래스

Programming/ActionScript 3.0 2007. 7. 6. 06:32
URLLoader 클래스
외부로부터의 XML 데이터등을 읽어들일 때는 URLLoader 클래스를 사용할 수 있다.


URLRequest 클래스를 통한 데이터 송신
URLLoader를 사용해서 서버에 리퀘스트를 보내려면 우선 URLRequest 클래스의 인스턴스를 만든다. URLRequest의 오브젝트에는 리퀘스트 URL이나 헤더 정보 등을 지정할 수 있다.

아래 작성한 코드는 URLRequest 오브젝트를 인수로서 URLLoader의 load() 메소드를 호출한다.




var myReq:URLRequest = new URLRequest();
myReq.url = "foo.xml"; // constructor의 인수로도 지정 가능
var myLoader:URLLoader = new URLLoader();
myLoader.load(myReq);
HTTP 헤더에 정보를 추가하는 경우는 항목 마다 URLRequestHeader 클래스의 인스턴스를 작성하여 URLRequestHeader 오브젝트의 requestHeaders 속성(Array 형태)에 추가한다.
var myReq:URLRequest = new URLRequest("foo.xml");
var myRH:URLRequestHeader = new URLRequestHeader("pragma", "no-cache");
myReq.requestHeaders.push(myRH);
var myLoader:URLLoader = new URLLoader();
myLoader.load(myReq);

수신한 데이터의 처리
load()를 실행하고 나서 데이터의 읽기 처리가 끝날 때까지는 ActionScript로부터 읽어 들인 데이터에 액세스 할 수 없다. URLLoader는 수신 처리를 완료하면 complete 이벤트를 발생시키므로 complete 이벤트에 대한 이벤트 핸들러 내에서 데이터 조작을 실시해야 한다. 읽어들인 데이터는 URLLoader의 data 속성으로부터 액세스 할 수 있다.
myLoader.addEventListener(Event.COMPLETE, completeHandler);
myLoader.load(new URLRequest("foo.xml"));

private function completeHandler(event:Event):void {
trace(myLoader.data);
}

읽혀진 데이터는 DataFormat 클래스에 정의하고 있는 3종류의 포맷 형태를 갖는다. URLLoader 오브젝트의 dataFormat 속성을 보면 다음과 같다.

    * DataFormat.TEXT : String 형의 문자열
    * DataFormat.BINARY : ByteArray 형의 바이너리 데이터
    * DataFormat.VARIABLES : URL encode 된 폼 변수를 가진다 URLVariables 오브젝트

데이터의 송신
서버에 데이터를 송신할 때도 위와 같이 3종류의 포맷을 사용할 수 있다. 송신하는 데이터를 URLRequest 오브젝트의 data 속성에 세트 하면 리퀘스트시에 세트한 데이터가 보내진다.

아래의 예에서는 URLVariables 오브젝트를 POST 형태로 송신하고 있다. 이 경우 데이터는 x-www-form-urlencoded 포맷에 encode 되어 보내진다.

var myVars:URLVariables = new URLVariables();
myVars.userID = "guest";
myVars.password = "foo";
myReq.data = myVars;
myReq.url = "ww.sample.com/foo.jsp";
myReq.method = URLRequestMethod.POST;
myLoader.load(myReq);

송신 방법 (GET/POST)은 URLRequest 오브젝트의 method 속성에 URLRequestMethod 클래스에 정의된 값을 사용하여 지정한다. 디폴트는 GET다. POST하는 경우는 데이터의 MIME 타입을 URLRequest 오브젝트의 contentType 속성으로 설정할 수 있다. ByteArray 오브젝트를 송신하는 경우는 GET은 사용할 수 없다.

    

설정

트랙백

댓글

[AS3] navigateToURL 함수

Programming/ActionScript 3.0 2007. 7. 6. 06:13
navigateToURL 함수

AS3 어플리케이션으로부터 또 하나의 브라우저 윈도우를 열고 싶을 때, 또는 현재 AS3 어플리케이션을 실행중의 윈도우를 다른 HTML 컨텐츠로 바꾸고 싶을 때, navigateToURL() 함수를 사용한다. AS3이전 버전에서는 getURL()을 사용하였다. 아래는 navigateToURL() 함수의 정의.

public function navigateToURL(request:URLRequest, window:String = null):void

1 첫 번째 인수에는 URLRequest 오브젝트를 지정한다. 이 오브젝트에는 URLLoader 클래스에서는  리퀘스트 하는 URL이나 헤더 정보, 그리고 송신하는 데이터와 송신 방법 등을 지정한다.

2 번째의 인수에는 리퀘스트의 결과를 수신하는 윈도우 target을 지정한다. 이것은 디폴트값이 정의되고 있기 때문에 생략이 가능하다. 생략 했을 경우에는 새로운 윈도우가 열린다. 즉 "_blank" 를 지정한 것과 동등의 결과가 된다.

아래의 샘플에서는 navigateToURL()의 두번째 인수를 "_self"로 하고 있기 때문에 AS3 어플리케이션을 실행하고 있는 윈도우에서 컨텐츠를 열게 된다.
import flash.net.navigateToURL;

var myVars:URLVariables = new URLVariables();
myVars.currentTime = new Date().getTime();
myVars.city = "Tokyo";

var myReq:URLRequest = new URLRequest();
myReq.url = "http://www.sample.com/weather";
myReq.data = myVars;

// 현재의 윈도우에 컨텐츠를 연다.
navigateToURL(myReq, "_self");

navigateToURL() 함수를 사용하려면 import해서 사용한다.


sendToURL() 함수
AS3 어플리케이션으로부터 서버에 데이터를 보내고 싶지만 결과는 무시하고 싶을 때는 sendToURL() 함수를 사용한다. 사용법은 위에서 소개한 것처럼 navigateToURL() 함수와 거의 비슷하다. 차이는 2번째의 인수가 없다는 것이다.

public function sendToURL(request:URLRequest):void


import flash.net.sendToURL;

var myVars:URLVariables = new URLVariables();
myVars.user = "foo";
myVars.data = "hello";

var myReq:URLRequest = new URLRequest();
myReq.url = "http://www.sample.com/post";
myReq.data = myVars;
myReq.method = URLRequestMethod.POST;
// 서버에 데이터를 송신
sendToURL(myReq);


    

설정

트랙백

댓글

[AS3] 클래스 액세스 제한

Programming/ActionScript 3.0 2007. 7. 6. 00:52
프롭퍼티의 선언에 private로 지정하면 다른 클래스에서는 참조할 수 없게 된다. 또 public으로 지정했을 경우는 어떤 클래스에서도 참조할 수 있다.

Protected로 지정한 프롭퍼티는 계승한 클래스에서는 참조를 할 수 있다. Default인 internal 의 경우는 같은 패키지내의 클래스이면 참조가 가능하다.

주의할 것은 protected의 경우 다른 패키지의 클래스에서 참조를 시도해도 서브 클래스이면 참조가 가능하다는 것이다. 반대로 protected의 프롭퍼티는 같은 패키지내의 클래스에서도 서브 클래스가 아니면 참조할 수 없다는 것이다.

또 internal의 프롭퍼티는 같은 패키지내의 서브 클래스에서만 참조가 가능하다.

예를 들어보면 우선 foo라는 패키지에 FooBase 클래스를 정의한다. 클래스 내에는 protected와 internal 의 2종류의 함수를 정의한다.
package foo
{
public class FooBase
{
protected function protectedFunc():void {
}
internal function internalFunc():void {
}
}
}
다음은 bar라고 하는 패키지에 상기 FooBase의 서브 클래스를 정의한다. 함수를 오버라이드(override) 하기 위해 override 키워드를 사용하고 있다.
package bar
{
import foo.FooBase;

public class BarSub extends FooBase
{
// 부모클래스의 정의를 오버라이드(override)
override protected function protectedFunc():void {
}
// 여기는 internal이기 때문에 오버라이드(override) 할 수 없다.
override internal function internalFunc():void {
}
}
}
위 코드를 컴파일 해 보면 protectedFunc() 메소드는 가능하지만 internalFunc() 메소드는 그런 함수는 발견되지 못하여 에러를 출력한다.

또 서브 클래스내의 코드에서 직접 부모클래스의 protected 프롭퍼티를 참조할 수 없다.
public class BarSub extends FooBase
{
public function callProtected():void {
var foo:FooBase = new FooBase();
// protected 의 메소드를 호출해 본다
foo.protectedFunc();
}
}
위의 예의 경우 callProtected()에서 에러가 발생한다.

    

설정

트랙백

댓글

[AS3] ActionScript 3.0 strict 옵션의 기능

Programming/ActionScript 3.0 2007. 7. 5. 17:22
서브 클래스를 정의하려면 extends 키워드를 사용한다.
// 부모클래스 정의
public class MyBase
{
public function hello():String {
return "hello";
}
}

// 서브 클래스의 정의
public class MySub extends MyBase
{
}


서브 클래스의 오브젝트는 부모클래스의 오브젝트와 같게 사용할 수 있다.
// MyBase 형의 변수에 대입
var base:MyBase = new MyBase();
var sub:MyBase = new MySub();

// MyBase 형의 인수를 받는 함수에 건넨다
needBase(sub);
needBase(base);

public function needBase(obj:MyBase):void {
trace(obj.hello());
}
반대로 부모클래스를 서브 클래스로 대신하여 인수로 전달 할 수 없다, 아래의 코드는 ActionScript 3.0 환경 설정에서 -strict 옵션을 붙이지 않으면 실행할 수 있지만 ActionScript 2.0에서는 에러를 출력한다.
var sub:MyBase = new MySub();
needSub(sub);

public function needSub(obj:MySub):void {
trace(obj.hello());
}

    

설정

트랙백

댓글

[FlashCS3] grant skinner의 Flash CS3용 Adobe AIR extension

Programming/ActionScript 3.0 2007. 7. 5. 08:03
사용자 삽입 이미지










Adobe에서 아직 Flash CS3용 AIR 기능확장을 제공하고 있지는 않지만  grant skinner가 Flash CS3용 AIR extension을 자작해 공개해 놓았다.

 
Step 1 :
Adobe Labs에서 Flex 3 SDK를 다운 받아서 특정 폴더를 만들어 압축을 풀어 놓는다.


Step 2 :
Extension Manager v1.8 를 다운 받아서 설치

Step 3 :
AIRPanel zip 파일을 다운 받아서 압축을 풀고 stop2에서 설치한 Extension 프로그램으로 AIRRanel extension을 등록한다. (플래시 툴이 열려 있을 경우는 닫고 다시 실행해야 other panel에서 확인이 가능하다)

Step 4 :
처음 AIRPanel extension을 설치하고 fla를 air파일로 만들기 전에 AIRPanel의 test버튼을 클릭했을 때 adl.exe 파일을 등록하기 위한 open창이 뜨면 step1에서 받아놓은 sdk 폴더에 보면 /bin 폴더에서 확인할 수 있다. 그것을 등록한다.

그리고 test버튼을 클릭하면 air파일을 만들기 전에 테스트로 화면에서 확인 할 수 있고 Package 버튼을 클릭하면 실제로 air파일을 생성하게 된다. Settings 버튼은 어플리케이션의 기본적인 정보와 SystemChrome에서는 standard와 none를 제공하고 있는데 none를 선택하고 Transparent를 체크하면 transparent로 뚫린 플래시 어플리케이션을 만들 수 있다

주의할 점은 fla파일이 한글을 포함한 폴더 경로에 있을 경우에는 air를 생성하지 못한다. 영문 폴더를 생활화...
    

설정

트랙백

댓글

[AS3] 이벤트 리스너와 garbage collection

Programming/ActionScript 3.0 2007. 7. 5. 04:35
필요 없는 오브젝트의 참조가 남아있으면 그 오브젝트가 사용하고 있는 메모리 영역을 사용할 수 없게 된다. 특히 복수가 참조하는 오브젝트에 대해서는 참조를 해제하는 것을 잊어버리게 되면 메모리의 낭비가 발생하므로 주의해야 한다.

이벤트 리스너를 등록하려면 이벤트의 타겟으로 되는 오브젝트와 이벤트 리스너를 가지는 오브젝트 사이에 참조를 할 수 있다. AS3에서는 아래와 같이 기술한다.

eventTarget.addEventLisener("eventType", eventHandler);

이 코드를 실행하면 eventTarget과 현재 스크립트가 포함된 this 사이에 참조가 만들어진다. 하지만 이것은 명시적인 참조의 추가가 아니기 때문에 참조의 삭제가 필요한 경우 간과할 수 있다.

아래는 이벤트 리스너 추가시에 참조의 취급 방법에 대한 내용이다.


참조의 방향
참조에는 방향성이 있다. 즉, 오브젝트간의 참조는 한 방향으로만 가능하다. 예를 들면 아래와 같은 코드가 있을 때,
var foo = new Foo();
foo.bar = this;
foo = null;
1행에서 만들어진 참조는 this -> new Foo() 방향으로 만들어진 참조이다. 2행에서 만들어진 참조는 1행과 반대로 new Foo() -> this 방향으로 만들어 진 참조다. 3행에서 1행의 참조를 삭제하게 되면 this -> new Foo()으로의 참조를 할 수 없다.

가비지컬렉터는 오브젝트 트리의 루트로부터 참조를 찾아 들어 간다. 우선 루트의 오브젝트를 찾아내고 다음에 그 오브젝트의 오브젝트를 찾아내는 동작을 반복하게 된다. 위 샘플을 실행했을 경우 this에 new Foo()로 만들어진 오브젝트를 찾아 낼 수 없다. 즉 2행째에 작성한 참조가 남아있다고 해도 3행을 실행하게 되면 메모리 문제는 해결될 수 있다.


오브젝트에 이벤트 리스너 추가
오브젝트에 이벤트 리스너를 추가할 경우에 참조 방향으로는 아래와 같다.
import flash.events.Event;
import flash.events.MouseEvent;
var foo = New Foo();
addChild(foo);
foo.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(evt:Event):void{
trace(this);
}
위 코드에서 foo 오브젝트를 작성하고 그 오브젝트에 clickHandler라는 이벤트 리스너를 등록하였다. clickHandler 메소드는 스크립트가 작성된 this 오브젝트의 메소드가 된다.

이러한 경우 foo 오브젝트의 참조를 삭제할 때 이벤트 리스너도 삭제하지 않으면 메모리에 잔존하는 문제의 원인이 될 수 있다. 아래와 같이 오브젝트로부터 this에 이벤트 리스너를 설정할 경우도 같다.
parent.addEventListener("click", clickHandler);
약한 참조의 이용
약한 참조는 참조가 존재하고 있어도 가비지콜렉터에 의해서 참조로서 보이지 않는 참조이다. 이는 매우 편리하게 사용할 수 있는데 이벤트 리스너에 의해 생성되는 참조가 모두 약한 참조라면 참조의 방향을 신경 쓰지 않고 등록한 리스너를 방치해 두어도 문제가 되지 않기 때문이다. 이벤트 리스너를 등록할 때 약한 참조를 사용할지를 지정할 수 있다. addEventListener()의 5번째 인수를 true로 적용하면 약한 참조를 사용할 수 있다.
addEventListener("eventType", listenerHandler, false, 0, true);
3번째와 4번째 인수는 false와 0 값을 지정해 두면 대체적으로 문제가 없기 때문에 위와 같은 형태로 5번째 인수를 false와 true로 적용하여 강한 참조와 약한 참조를 사용할 수 있다.

    

설정

트랙백

댓글

[AS3] AS3와 AS2의 통신 LocalConnection 클래스

Programming/ActionScript 3.0 2007. 7. 4. 04:59

AS3로 만든 플래시에서 AS2로 만든 swf를 로드 할 수는 있지만 그 안에 있는 메소드나 변수에 접근 할 수는 없다. 블로그의 메뉴와 배경에 나타나는 나비는 as2로 만들었고,  infinite메뉴는 따로 AS3로 만들었기 때문에 서로 다른 swf 파일로 되어 있다.

고민이 되었던 부분은 infinite 메뉴를 클릭했을 때 fullscreen 형태로 컨텐츠를 보여주게 되면서 아래에 있는 블로그의 기존에 생성하던 나비와 플레이 되고 있던 음악은 종료해야 한다는 것이었다. 나비의 경우는 화면에 보이지 않으면서 불필요하게 CPU를 낭비하게 되고 음악 또한 불필요하다.

그래서 직접 AS3 코드에서 AS2코드를 참조할 수 없으니 간접적으로 참조할 수 있는 방법으로 LocalConnection 클래스를 사용하게 되었다. LocalConnection의 경우는 as2,와 as3에서 서로 호환적으로 사용이 가능하다.

    

설정

트랙백

댓글

[AS3] root 변수 참조 방법

Programming/ActionScript 3.0 2007. 7. 4. 04:42
root에 있는 변수나 메소드에 접근할 때 actionscript 2.0에서는 _root를 절대적 참조 영역으로 사용하였으나 as3부터는 _root를 통해 직접적으로 변수나 함수를 참조할 수가 없다.

as3에서 root영역에 있는 변수나 함수를 참조하기 위해서는 아래와 같은 형태로 가능하다. (코드의 일부 개념적인 부분은 한상훈님의 설명을 참조하였다.)  'ADDED_TO_STAGE'라는 이벤트는 constructor를 통해서 인스턴스를 생성할 때 메모리 영역을 할당 받기 전의 참조로 인한 문제를 방지하기 위해 사용한 듯한데 아직까지 as3의 개념이 확실히 잡히지 않았다.






import flash.events.MouseEvent;
import flash.events.Event;

var menu_num:Number = 100;

mc.buttonMode = true;
mc.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(evt:Event):void{
var rootTest:RootTest = new RootTest();
addChild(rootTest);
rootTest.getTrace();
}

package{
import flash.display.MovieClip;
import flash.events.Event;

public class RootTest extends MovieClip{

private var _root:MovieClip;

public function RootTest(){
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(evt:Event):void{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
_root = root as MovieClip;//or MovieClip(root);
}
public function getTrace():void{
trace(stage);
trace(_root.menu_num);
}
}}
출력 :
[object Stage]
100

    

설정

트랙백

댓글

[AS3] Timer 클래스에서 주의할 점.

Programming/ActionScript 3.0 2007. 7. 2. 08:03

오늘 AS3로 무비클립의 특정 프레임으로 이동하는 모션 클래스를 제작하다가 Timer 클래스의 버그인줄 알고 Timer 관련 레퍼런스를 찾아보니 버그가 아니라 설정된 기능이었다.

보통 Timer 클래스를 정의하여 사용할 때 두 개의 파라미터를 전달하게 되는데 그 첫 번째는 handler 메소드의 실행 간격을 정의하는 Delay고 두 번째 파라미터는 몇 번을 실행할 것인가를 나타내는 repeatCount:int . 아래의 코드는 1초 간격으로 5handler 메소드를 실행하게 된다.

var timer:Timer = new Timer(1000, 5);

위 코드에서 두 번째 파라미터 값이 값을 갖게 되면 한번 실행되고 종료하지만 0 값을 갖게 되면 무한히 handler 메소드를 실행하며 currentCount값도 무한하게 증가한다. repeatCount default값이 0이기 때문에 두번째 파라미터를 설정하지 않을 경우도 stop() 메소드로 Timer이벤트를 종료할 때가지 실행하게 된다.  

import flash.utils.Timer;
import flash.events.TimerEvent;

var timer:Timer = new Timer(30, 0); // or new Timer(30);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();

function timerHandler(evt:Event):void{
trace(evt.currentTarget.currentCount);
}

런타임시 스크립트상에서 repeatCount로 전달되는 파라미터 값이 0의 값을 갖게 될 때는 주의해서 Timer 이벤트를 종료해 줄 필요가 있다.

    

설정

트랙백

댓글

[AS3] Array에 추가된 새로운 메소드들

Programming/ActionScript 3.0 2007. 7. 2. 03:56
every() 메소드    
AS3 function every(callback:Function, thisObject:* = null):Boolean

지정된 함수에서 false를 돌려주는 아이템에 이를 때까지 배열내의 각 아이템에 테스트 함수를 실행한다. 이 메소드를 사용하면 배열내의 모든 아이템이 있는 기준(값이 특정의 수치보다 작은 등)이 만족하는지 어떤지를 판별할 수 있다.

파라미터
    callback:Function — 배열내의 각 아이템에 대해 실행하는 함수. 이 함수에는 단순한 비교 (item < 20 등)나 보다 복잡한 연산을 포함할 수 있다 .또 이 함수를 호출하려면 다음과 같이 아이템의 값, 아이템의 인덱스, 및 Array 오브젝트의 3개 인수를 사용한다.

function callback(item:*, index:int, array:Array):Boolean;

    thisObject:* (default = null) — 함수의 this로서 사용하는 오브젝트.

반환값
    Boolean — 불리언 값. true를 돌려준다 (지정된 함수에 대해 배열 내의 모든 아이템이 true 를 돌려주는 경우)  그 이외의 경우는 false를 돌려준다.

다음의 예에서는 2개의 배열을 테스트하고 각 배열내의 모든 아이템이 수치인지를 판별하고 테스트 결과를 출력한다. 첫번째 배열의 결과는 true, 2번째의 배열은 false를 나타내고 있으며 false를 받는 즉시 테스트 함수의 순회는 종료된다.
package {
import flash.display.Sprite;
public class Array_every extends Sprite {
public function Array_every() {
var arr1:Array = new Array(1, 2, 4);
var res1:Boolean = arr1.every(isNumeric);
trace("isNumeric:", res1);// true

var arr2:Array = new Array(1, "ham", 2);
var res2:Boolean = arr2.every(isNumeric);
trace("isNumeric:", res2);// false
}
private function isNumeric(element:*, index:int, arr:Array):Boolean {
trace(element);
return (element is Number);
}
}
}

출력 :
1
2
4
isNumeric: true
1
ham
isNumeric: false


forEach( ) 메소드    
AS3 function forEach(callback:Function, thisObject:* = null):void

배열내의 각 아이템에 대해 함수를 실행한다.

파라미터
    callback:Function — 배열내의 각 아이템에 대해 실행하는 함수. 이 함수에는 단순한 커멘드 (trace() 스테이트먼트 등)나 보다 복잡한 연산을 포함할 수 있다. 또 이 함수를 호출하려면  다음과 같이 아이템의 값, 아이템의 인덱스, 및 Array 오브젝트와 같이 3개의 인수를 사용한다.

    function callback(item:*, index:int, array:Array):void;

    thisObject:* (default = null) — 함수의 this로서 사용하는 오브젝트.

다음의 예에서는 배열내의 각 아이템에 대해서 trace() 스테이트먼트를 traceEmployee() 함수로 대체하고 있다.
package {
import flash.display.Sprite;
public class Array_forEach extends Sprite {
public function Array_forEach() {
var employees:Array = new Array();
employees.push({name:"Employee 1", manager:false});
employees.push({name:"Employee 2", manager:true});
employees.push({name:"Employee 3", manager:false});
trace(employees);
employees.forEach(traceEmployee);
}
private function traceEmployee(element:*, index:int, arr:Array):void {
trace(element.name + " (" + element.manager + ")");
}
}
}

다음의 예도 배열내의 각 아이템에 대해 trace() 스테이트먼트를 실행하고 있지만 여기서 사용한 traceEmployee() 함수에는 약간의 변경이 있다.
package {
import flash.display.Sprite;
public class Array_forEach_2 extends Sprite {
public function Array_forEach_2() {
var employeeXML:XML = <employees>
<employee name="Steven" manager="false" />
<employee name="Bruce" manager="true" />
<employee name="Rob" manager="false" />
</employees>;
var employeesList:XMLList = employeeXML.employee;
var employeesArray:Array = new Array();
for each (var tempXML:XML in employeesList) {
employeesArray.push(tempXML);
}
employeesArray.sortOn("@name");
employeesArray.forEach(traceEmployee);
}
private function traceEmployee(element:*, index:Number, arr:Array):void {
trace(element.@name + ((element.@manager == "true") ? " (manager)" : ""));
}
}
}

filter() 메소드    
AS3 function filter(callback:Function, thisObject:* = null):Array

배열내의 각 아이템에 대해 테스트 함수를 실행하여 지정된 함수에 대해서 true를 돌려주는 모든 아이템을 포함하는 새로운 배열을 작성한다. false를 돌려주는 아이템은 새로운 배열에 포함하지 않는다.

파라미터
    callback:Function — 배열내의 각 아이템에 대해 실행하는 함수. 이 함수에는 단순한 비교 (item < 20 등)나 보다 복잡한 연산을 포함할 수 있다. 또 이 함수를 호출하려면 다음과 같이 아이템의 값, 아이템의 인덱스, 및 Array 오브젝트와 같이 3개의 인수를 사용한다.

    function callback(item:*, index:int, array:Array):Boolean;

    thisObject:* (default = null) — 함수의 this로서 사용하는 오브젝트.

반환값
    Array — 원본 배열내의 아이템으로 true를 돌려준 것을 모두 포함한 새로운 배열이다.

다음의 예에서는 관리자인 모든 종업원의 배열을 작성한다.
package {
import flash.display.Sprite;
public class Array_filter extends Sprite {
public function Array_filter() {

var employees:Array = new Array();
employees.push({name:"Employee 1", manager:false});
employees.push({name:"Employee 2", manager:true});
employees.push({name:"Employee 3", manager:false});
trace("Employees:");
employees.forEach(traceEmployee);

var managers:Array = employees.filter(isManager);
trace("Managers:");
managers.forEach(traceEmployee);
}
private function isManager(element:*, index:int, arr:Array):Boolean {
return (element.manager == true);
}
private function traceEmployee(element:*, index:int, arr:Array):void {
trace("t" + element.name + ((element.manager) ? " (manager)" : ""));
}
}
}

map() 메소드    
AS3 function map(callback:Function, thisObject:* = null):Array

배열내의 각 아이템에 대해 함수를 실행하여 원본 배열의 각 아이템에 대한 함수의 결과에 대응하는 아이템으로부터 완성되는 새로운 배열을 작성한다.

파라미터
    callback:Function — 배열내의 각 아이템에 대해 실행하는 함수. 이 함수에는 단순한 커멘드 (스트링의 배열의 대문자 소문자의 변경 등)나 보다 복잡한 연산을 포함할 수 있다. 또 이 함수를 호출하려면 다음과 같이 아이템의 값, 아이템의 인덱스, 및 Array 오브젝트와 같이 3개의 인수를 사용한다.

    function callback(item:*, index:int, array:Array):void;
 
    thisObject:* (default = null) — 함수의 this로서 사용하는 오브젝트.

반환값
    Array — 원본배열내의 각 아이템의 함수의 결과가 포함되는 새로운 배열이다.

다음의 예에서는 배열내의 모든 아이템을 대문자로 변경하고 있다.
package {
import flash.display.Sprite;
public class Array_map extends Sprite {
public function Array_map() {
var arr:Array = new Array("one", "two", "Three");
trace(arr); // one,two,Three

var upperArr:Array = arr.map(toUpper);
trace(upperArr); // ONE,TWO,THREE
}
private function toUpper(element:*, index:int, arr:Array):String {
return String(element).toUpperCase();
}
}
}

some() 메소드    

AS3 function some(callback:Function, thisObject:* = null):Boolean

true를 돌려주는 아이템에 이를 때까지 배열내의 각 아이템에 테스트 함수를 실행한다. 이 메소드를 사용하면 배열내의 어느 아이템의 기준(값이 특정의 수치보다 작은지 등)을 만족하는지 어떤지를 판별할 수 있다.

파라미터
    callback:Function — 배열내의 각 아이템에 대해 실행하는 함수. 이 함수에는 단순한 비교 (item < 20 등)나 보다 복잡한 연산을 포함할 수 있다. 또 이 함수를 호출하려면 다음과 같이 아이템의 값, 아이템의 인덱스, 및 Array 오브젝트와 같이 3개의 인수를 사용한다.

    function callback(item:*, index:int, array:Array):Boolean;

    thisObject:* (default = null) — 함수의 this로서 사용하는 오브젝트.

반환값
    Boolean — 불리언 값. true를 돌려준다. (지정된 함수에 대해 배열내의 몇개의 아이템이 true를 돌려주는 경우). 그 이외의 경우는 false를 돌려준다.

다음의 예에서는 배열 내 요소 중 undefined 값이 포함된 것을 표시한다.
package {
import flash.display.Sprite;
public class Array_some extends Sprite {
public function Array_some() {
var arr:Array = new Array();
arr[0] = "one";
arr[1] = "two";
arr[3] = "four";
var isUndef:Boolean = arr.some(isUndefined);
trace(isUndef);
if (isUndef) {
trace("array contains undefined values: " + arr);
} else {
trace("array contains no undefined values.");
}
}
private function isUndefined(element:*, index:int, arr:Array):Boolean {
return (element == undefined);
}
}
}
출력 :
true
array contains undefined values: one,two,,four

    

설정

트랙백

댓글

[AS3] 기본적인 어플리케이션 작성

Programming/ActionScript 3.0 2007. 6. 28. 16:09
Flash, Flex Builder, Dreamweaver또는 임의의 텍스트 문자 편집기를 사용하여 as 확장자(extension)를 가지는 외부 ActionScript 원시 파일을 작성할 수 있다.

ActionScript 3.0은 Flash authoring tool나 Flex Builder 등 다양한 어플리케이션 개발 환경에서 사용할 수 있다.

아래에서는 Flash authoring tool 또는 Flex Builder 2 툴을 사용한 간단한 ActionScript 3.0 어플리케이션의 작성과 확장을 스텝 방식으로 학습해본다. 작성하는 어플리케이션은 ActionScript 3.0의 외부 클래스 파일을 Flash 및 Flex 어플리케이션으로 사용하기 위한 단순한 견본을 제시한다. 그 패턴은 다른 모든 어플리케이션에 적용할 수 있는 기본적인 것이다.


ActionScript 어플리케이션의 설계

어플리케이션의 작성을 시작하기 전에 어떠한 어플리케이션을 만들 것인가를 생각할 필요가 있다.

설계는 어플리케이션의 이름과 목적을 나타내는 짧은 설명 등과 같이 간단한 것에서부터 다수의 UML (Unified Modeling Language) 그림을 포함한 것과 같이 복잡한 것으로 나타낼 수 있는데 어느 것을 사용하여도 상관없다. 아래에서 나올 내용은 ActionScript 어플리케이션의 개발과 설계에서 빠뜨릴 수 없는 순서라고 할 수 있다.

다음에서 설명할 어플리케이션은 ActionScript 어플리케이션을 공부할 때 처음으로 사용되는 예로서 단순한 설계를 사용한 표준적인 "Hello World" 어플리케이션이다.

    * 어플리케이션의 이름은 HelloWorld 다.

    * "Hello, World!" 라고하는 문자열이 포함된 텍스트 필드가 1개 표시된다.

    * 이 필드를 간단하게 재이용할 수 있도록 Greeter라는 이름의 객체 지향 클래스가 1개 사용된다. 이 클래스는 Flash 문서 또는 Flex 어플리케이션 내에서 사용할 수 있다.

    * 기본이 되는 어플리케이션을 작성한 후에 유저에게 유저명을 입력시켜서 어플리케이션에 그 이름을 유저 리스트와 조합시키는 새로운 기능을 추가하다.

위와 같이 간결하게 정의하고 어플리케이션의 작성을 시작한다.


HelloWorld 프로젝트와 Greeter 클래스의 작성

Hello World 어플리케이션의 설계 설명에서는 재이용하기 쉬운 코드를 사용한다는 것이 명시되어 있다. 이 목표를 고려하여 어플리케이션은 Greeter라는 이름의 객체 지향 클래스를 1개 사용한다.이 클래스는 Flex Builder 또는 Flash authoring tool로 작성한 어플리케이션 내에서 사용된다.

Flash authoring tool로 Greeter 클래스를 작성하려면:

   1. Flash authoring tool로 [파일]-[신규]를 선택한다.

   2. [신규 문서] 다이알로그 박스로 ActionScript 파일을 선택하여 [OK]를 클릭한다.

ActionScript 편집 윈도우가 표시된다.

   3. [파일]-[저장]을 선택한다. 어플리케이션을 보존하는 폴더를 선택하여 ActionScript 파일에 Greeter.as라는 이름을 붙여 [OK]를 클릭한다.

 
Greeter 클래스에의 코드의 추가

Greeter 클래스는 오브젝트 Greeter를 정의하고 이것을 통해 HelloWorld 어플리케이션을 사용할 수 있다.

Greeter 클래스에 코드를 추가하려면 :

   1. 새로운 파일에 다음 코드를 입력한다.

package
{
public class Greeter
{
public function sayHello():String

{
var greeting:String;
greeting = "Hello World!";
return greeting;
}
}
}
Greeter 클래스에서는 " Hello World!";"라는 문자열을 돌려주는 1개의 sayHello() 메소드가 포함되어 있다.

   2. [파일]-[저장]을 선택하고 이 ActionScript 파일을 저장한다..

이로써 Flash 또는 Flex 어플리케이션으로 Greeter 클래스를 사용할 수 있게 되었다.


ActionScript 코드를 사용하는 어플리케이션의 작성

작성된 Greeter 클래스는 필요한 것을 모두 갖춘 어플리케이션이지만 어플리케이션 전부를 나타내는 것은 아니다. Greeter 클래스를 사용하려면 Flash 문서 또는 Flex 어플리케이션을 작성할 필요가 있다.

HelloWorld 어플리케이션에서는 Greeter 클래스의 새로운 인스턴스가 작성된다. 다음에 나타내는 것은 어플리케이션에 Greeter 클래스를 합성하는 방법이다..

Flash authoring tool를 사용해 ActionScript 어플리케이션을 작성하려면:

   1. [파일]-[신규]를 선택한다.

   2. [신규 문서] 다이알로그 박스로 [Flash 문서]를 선택하고 [OK]를 클릭한다.

새로운 Flash 윈도우가 표시된다.

   3. [파일]-[저장]을 선택한다. Greeter.as 클래스 파일과 같은 폴더를 선택하여 Flash 문서에 HelloWorld.fla라는 이름을 붙이고 [OK]를 클릭한다.

   4. [Flash 툴] 팔레트로 [텍스트 툴]을 선택한 후, 스테이지상에서 드레그 하여 폭 300 픽셀, 높이 약 100 픽셀의 새로운 텍스트 필드를 정의한다.

   5. 스테이지상의 텍스트 필드가 선택된 상태에서 [프롭퍼티] 윈도우에 텍스트 필드의 인스턴스명을 mainText라고 입력한다.

   6. 메인 타임 라인의 최초의 프레임을 클릭한다.

   7. [액션] 패널에 다음의 스크립트를 입력한다.
	var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello();
   8. 파일을 저장한다.

ActionScript 어플리케이션의 퍼블리시를 통한 테스트


어플리케이션 개발은 반복 프로세스다. 코드를 기술하여 컴파일 하고 올바르게 컴파일 될 때까지 코드를 편집한다. 컴파일 된 어플리케이션을 실행해 테스트하고 의도한 설계가 실현되고 있는지 어떤지를 확인한다. 의도한 설계대로 실현되지 않을 경우에는 실현될 때까지 코드를 편집한다. Flash 및 Flex Builder의 개발 환경에는 어플리케이션을 퍼블리시, 테스트, 및 디버그 하는 다수의 방법이 준비되어 있다.

다음에 각 환경에서 HelloWorld 어플리케이션을 테스트하는 기본적인 순서를 나타낸다.

Flash authoring tool를 사용해 ActionScript 어플리케이션을 퍼블리시 및 테스트하려면:

   1. 어플리케이션을 퍼블리시하고, compile error가 없는가 확인한다. Flash authoring tool로 [컨트롤]-[무비 프리뷰]를 선택하고 ActionScript 코드를 컴파일 하여 HelloWorld 어플리케이션을 실행한다.

   2. 어플리케이션을 테스트했을 때, [출력] 윈도우에 에러나 경고가 표시되었을 경우에는HelloWorld.fla 또는 HelloWorld.as 파일에서 에러의 원인을 수정하고 나서 어플리케이션의 테스트를 다시 시도한다.

   3. compile error가 없으면 Flash Player 윈도우에 Hello World 어플리케이션이 표시된다. 윈도우에는 "Hello World!"라는 텍스트가 표시된다.

 
이로써 간단하지만 ActionScript 3.0을 사용하여 완전한 객체 지향 어플리케이션을 작성할 수 있었다. 다음으로는 HelloWorld 어플리케이션을 확장해본다.


HelloWorld 어플리케이션의 확장

여기에서는 어플리케이션을 좀 더 흥미롭게 작성 해본다. 어플리케이션에 유저명을 요구시켜서 그것을 이름 리스트와 검증시켜본다.

우선 Greeter 클래스를 갱신해 새로운 기능을 추가한다. 다음에 Flex 또는 Flash 어플리케이션을 갱신해 새로운 기능을 추가한다.

Greeter.as 파일을 갱신하려면 :

   1. "Greeter.as" 파일을 연다.

   2. 파일의 내용을 다음과 같이 변경한다.

package{
public class Greeter{
// Defines the names that should receive a proper greeting.

public static var validNames:Array = ["Sammy", "Frank", "Dean"];

// Builds a greeting string using the given name.

public function sayHello(userName:String = ""):String{

var greeting:String;

if (userName == ""){
greeting = "Hello. Please type your user name, and then press the Enter key.";
}else if (validName(userName)){
greeting = "Hello, " + userName + ".";
}else{
greeting = "Sorry, " + userName + ",you are not on the list.";
}
return greeting;
}

// Checks whether a name is in the validNames list.

public static function validName(inputName:String = ""):Boolean{
if (validNames.indexOf(inputName) > -1){
return true;
}else{
return false;
}
}
}
}
Greeter 클래스는 몇개의 새로운 기능이 추가되었다.

   3. validNames 배열은 유효한 유저명을 리스트로 나타낸다. 이 배열은 Greeter 클래스의 로드시에 3개의 이름의 리스트에 초기화된다.

   4. sayHello() 메소드는 유저명을 받아들여 어떠한 조건에 근거하여 인사를 변경할 수 있게 된다. userName이 문자열 ("") 인 경우 greeting 프롭퍼티는 유저에게 이름의 입력을 요구하는 것으로 설정한다. 유저명이 유효하면 인사는 "Hello, userName"이 된다. 마지막으로 2개의 조건 어느 쪽에도 적합하지 않는 경우에는 greeting 변수는 "Sorry, userName, you are not on the list." 로 설정된다.

   5. validName() 메소드는 inputName변수 값을 validNames 배열내에서 발견했을 경우에는 true 를, 발견되지 않았을 경우에는 false를 반환한다. 스테이트먼트 validNames.indexOf(inputName) 는 validNames 배열 내에서 inputName 문자열과 같은 문자열이 있는지를 검사한다. Array.indexOf() 메소드는 배열내의 오브젝트 초기의 인스턴스의 인덱스 위치, 또는 오브젝트가 배열에 발견되지 않았을 경우에는 값 -1을 반환한다.

 
아래와 같이 Flash 파일 또는 Flex 파일을 편집한다.

 
Flash authoring tool를 사용해 어플리케이션을 변경하려면:

   1. HelloWorld.fla 파일을 연다.

   2. 프레임 1의 스크립트를 아래와 같이 변경하고 문자열 ("")를 Greeter 클래스의 sayHello() 메소드에게 건네도록 한다.
 
	var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello("");
   3. [툴] 팔레트의 [텍스트] 툴을 선택하고 스테이지상에서 기존의 mainText 텍스트 필드의 바로 아래에 2개의 새로운 텍스트 필드를 작성한다.

   4. 최초의 텍스트 필드의 라벨이 되는 텍스트로서 User Name: 이라고 입력한다.

   5. 1개의 새로운 텍스트 필드를 선택하고 텍스트 필드의 타입으로서 InputText를 선택한다. 인스턴스명으로서 textIn이라고 입력한다.

   6. 메인 타임 라인의 최초의 프레임을 클릭한다.

   7. [액션] 패널에서 기존의 스크립트의 아래에 아래와 같은 스크립트를 추가한다.
mainText.border = true;
textIn.border = true;

textIn.addEventListener(KeyboardEvent.KEY_UP, keyPressed);

function keyPressed(event:Event):void
{
if (event.keyCode == Keyboard.ENTER)
{
mainText.text = myGreeter.sayHello(textIn.text);
}
}
이 스크립트는 아래와 같은 기능을 한다
   8. 최초의 2행은 단순하게 2개의 텍스트 필드의 경계선을 정의한다.

   9. textIn 필드 등의 입력 텍스트 필드에는 dispatch 할 수 있는 이벤트 세트가 있다. addEventListener() 메소드에 의해서 특정의 타입의 이벤트가 발생했을 때에 실행되는 함수를 정의할 수 있다. 이 예에서는 키보드의 Enter 키를 떼었을 때 이벤트를 처리하게 된다.

  10. keyPressed() 커스텀 함수는 myGreeter 오브젝트의 sayHello() 메소드를 호출하여 textIn 텍스트 필드의 텍스트를 파라미터로서 건네준다. 이 메소드는 건네 받은 값에 근거하여 인사의 문자열을 돌려준다. 반환된 문자열은 mainText 텍스트 필드의 text 프롭퍼티에 할당할 수 있다.

프레임 1의 완전한 스크립트는 다음과 같다.
mainText.border = true;
textIn.border = true;

var myGreeter:Greeter = new Greeter();
mainText.text = myGreeter.sayHello("");

textIn.addEventListener(KeyboardEvent.KEY_UP, keyPressed);

function keyPressed(event:Event):void
{
if (event.keyCode == Keyboard.ENTER)
{
mainText.text = myGreeter.sayHello(textIn.text);
}
}
  11. 파일을 저장한다.

  12. [컨트롤]-[무비 프리뷰]를 선택하고 어플리케이션을 실행한다.

어플리케이션을 실행하면 유저명 입력을 통해서 메시지를 구할 수 있다. 유효한 유저명 (Sammy ,Frank , 또는 Dean)를 입력하면 "hello"라는 확인 메세지가 표시된다.

    

설정

트랙백

댓글

[AS3] 데이터형 기본

Programming/ActionScript 3.0 2007. 6. 27. 15:21

ActionScript 3.0에서는 사용할 수 있는 많은 데이터형이 있다. 이러한 데이터형에는 "단순한" 또는 "기본적인" 데이터형이라고 볼 수 있는 것이 있다.

    * String : 이름 또는 텍스트 형태의 문자
    * Numeric : ActionScript 3.0에는 수치 데이터형으로 3종류의 데이터형을 사용한다.
          o Number : 소수점이 있거나 없는 값을 포함한 모든 수치
          o int : 정수 (소수점이 없는 자연수)
          o uint : 부호 없는 정수. 즉 부의 수가 되지 않는 자연수
    * Boolean : 스위치의 on이나 off, 2개의 값이 동일한가 아닌가 등의 true 나 false의 값

단순한 데이터형은 1개의 정보를 나타낸다. 예를 들어 단일의 숫자 또는 텍스트의 1문장 등이지만 ActionScript에서 정의되는 데이터형의 대부분은 정리되고 그룹화된 세트값을 나타내기 위해 복잡한 데이터형으로서 기술할 수 있다. 예를 들어 데이터형 Date의 변수는 1개의 값, 즉 특정의 시점을 나타내지만 그 일자의 값은 실제로는 일, 월, 년, 시간, 분 , 초 등 복수의 값으로 나타내며 모두 개별의 수치를 갖는다. 이 때문에 일자는 단일의 값으로 해서 생각하지만 (Date 변수를 작성해 단일의 값으로 해서 처리할 수 있지만) 컴퓨터의 내부에서는 1개의 일자를 정의하는 복수 값으로부터 완성되는 그룹이라고 볼 수 있다.

프로그래머가 정의하는 데이터형 이외의 데이터형 대부분은 복잡한 데이터형이다. 복잡한 데이터형이라고 할 수 있는 것은 다음과 같다.

    * MovieClip : 무비 클립 심볼
    * TextField : 다이나믹 텍스트 필드 또는 텍스트 입력 필드
    * SimpleButton : 버튼 심볼
    * Date : 특정의 시점에 관한 정보 (일자와 시간)

데이터형과 같은 의미로 많이 사용되는 용어에 클래스와 오브젝트가 있다. 클래스는 단지 데이터형을 정의한 것이고 오브젝트는 클래스의 실제의 인스턴스다. MovieClip의 변수는 MovieClip 오브젝트로 기술할 수 있다.

    

설정

트랙백

댓글

[AS3] MouseEvent 활용 예제

Programming/ActionScript 3.0 2007. 6. 26. 16:43
아래 예에서는 MouseEventExample 및 ChildSprite 클래스를 사용하여 단순한 이미지를 사용, 마우스 이벤트가 송출되는 방법을 나타낸다.
















package {
import flash.display.Sprite;

public class MouseEventExample extends Sprite {
private var size:uint = 100;
private var bgColor:uint = 0xFFCC00;

public function MouseEventExample() {
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}

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

class ChildSprite extends Sprite {
private var size:uint = 50;
private var overSize:uint = 60;
private var backgroundColor:uint = 0xFFCC00;
private var overColor:uint = 0xCCFF00;
private var downColor:uint = 0x00CCFF;

public function ChildSprite() {
draw(size, size, backgroundColor);
addEventListener(MouseEvent.CLICK, clickHandler);
addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler);
}

private function draw(w:uint, h:uint, bgColor:uint):void {
graphics.clear();
graphics.beginFill(bgColor);
graphics.drawRect(0, 0, w, h);
graphics.endFill();
}

private function clickHandler(event:MouseEvent):void {
trace("clickHandler");
}

private function doubleClickHandler(event:MouseEvent):void {
trace("doubleClickHandler");
}

private function mouseDownHandler(event:MouseEvent):void {
trace("mouseDownHandler");
draw(overSize, overSize, downColor);

var sprite:Sprite = Sprite(event.target);
sprite.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
sprite.startDrag();
}

private function mouseMoveHandler(event:MouseEvent):void {
trace("mouseMoveHandler");
event.updateAfterEvent();
}

private function mouseOutHandler(event:MouseEvent):void {
trace("mouseOutHandler");
draw(size, size, backgroundColor);
}

private function mouseOverHandler(event:MouseEvent):void {
trace("mouseOverHandler");
draw(overSize, overSize, overColor);
}

private function mouseWheelHandler(event:MouseEvent):void {
trace("mouseWheelHandler delta: " + event.delta);
}

private function mouseUpHandler(event:MouseEvent):void {
trace("mouseUpHandler");
var sprite:Sprite = Sprite(event.target);
sprite.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
sprite.stopDrag();
draw(overSize, overSize, overColor);
}
}
이 예제 소스는 다음과 같이 처리 한다.

1.    사각을 만드는데 사용하는 사이즈 (100 × 100 픽셀)와 배경색 (오렌지색)의 프롭퍼티를 선언한다.
2.    Constructor의 ChildSprite 오브젝트 child를 작성한다. 처음에 child의 constructor에서 draw() 메소드를 호출하여 오렌지색의 100 × 100 픽셀의 사각형을 (0,0) 의 좌표에 표시한다. 그 다음 코드는 7 개의 이벤트 청취자와 각 핸들러 메소드를 추가로 작성한다.

*    click/clickHandler() : 마우스 커서를 사각형 위에 놓고 왼쪽 mouse button을 싱글 클릭 했을 때 송출된다.
*    doubleClick/doubleClickHandler( ): 사각형 위에서 왼쪽 mouse button이 더블 클릭 되었을 때 송출된다.
*    mouseDown/mouseDownHandler() : ChildSprite 오브젝트 (오렌지색의 사각형)를 클릭하면 trace() 메세지가 화면에 표시되고 ChildSprite.draw()를 호출하여 mouseOverHandler()에서 나타난 밝은 청색의 사각형 위치에 어두운 황색 사각형이 표시된다. 또 mouseDownHandler() 메소드에 의해서 mouseMove 이벤트 청취자를 등록한다. 이것에 의해서 마우스의 이동이 처리되고 startDrag() 메소드를 호출하게 되어 Sprite 오브젝트의 드러그가 가능하게 된다.
*    mouseOut/mouseOutHandler() : 포인터가 사각형의 영역을 out하면 송출된다. draw() 메소드를 호출하여 사각형을 기존의 디폴트 색으로 변환한다.
*    mouseOver/mouseOverHandler( ): 마우스 포인터가 사각형과 겹쳐지면 송출된다. 이 메소드를 통해서 사각형은 어두운 황색 배경색으로 바뀌고 크기도 커진다.
*    mouseUp/mouseUpHandler(): 유저가 mouse button을 떼어 놓으면 mouseMove 이벤트 청취자가 삭제되어 stopDrag된다.
*    mouseMove/mouseMoveHandler(): 왼쪽 mouse button을 클릭하고 있는 동안 이 메소드는 Flash Player에 대해서 계속 오렌지색의 사각형을 다시 그리기를 요청하게 된다.
*    mouseWheel/mouseWheelHandler(): 사각형 위에서 마우스 휠을 회전시켰을 때에 송출된다.


    

설정

트랙백

댓글

[AS3] Stage resize 활용예제

Programming/ActionScript 3.0 2007. 6. 26. 14:39


















package {
   import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;

public class StageExample extends Sprite {

public function StageExample() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.ACTIVATE, activateHandler);
stage.addEventListener(Event.RESIZE, resizeHandler);
}

private function activateHandler(event:Event):void {
trace("activateHandler: " + event);
}

private function resizeHandler(event:Event):void {
trace("resizeHandler: " + event);
trace("stageWidth: " + stage.stageWidth + " stageHeight: " + stage.stageHeight);
}
}
}



    

설정

트랙백

댓글

Cube 클래스 모션 테스트

Programming/Papervision3D 2007. 6. 26. 12:01

Papervision3d Cube 클래스를 이용한 기본적인 모션 테스트.

클릭에 따라 cubematerial도 변경해 봤다.













[Flash] http://jasu.tistory.com/attachment/cfile26.uf@2723AE3B58802115320BE3.swf



    

설정

트랙백

댓글

papervision3d objects

Programming/Papervision3D 2007. 6. 26. 11:47
papervision3d를 이용하여 기본적으로 제공하는 object들을 나열해 보았다. cube 오브젝트에 마우스 오버를 했을 때 cube object가 rotation 되는데 각 오브젝트들이 이벤트를 받았을 때 주체가 되는 것과 DisplayObject target의 관계가 어떻게 되는지는 좀더 찾아봐야 할 것 같다...

복잡하지 않은 오브젝트, plane과 같은 것을 이용하면 안정된 포퍼먼스를 내는 재미있는 페이지 전환이나 네이게이션 형태를 만들어 낼 수 있을 듯 싶다... ActionScript 3.0을 공부하면서 좀더 연구해 봐야 하겠다...






[Flash] http://jasu.tistory.com/attachment/cfile5.uf@2101A93A5880211502AC3B.swf





    

설정

트랙백

댓글

[AS3] MovieClip 클래스

Programming/ActionScript 3.0 2007. 6. 24. 02:08
패키지    flash.display
    public dynamic class MovieClip
계승    MovieClip -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher  -> Object
-----------------------------------------------------------------------------
프롭퍼티
-----------------------------------------------------------------------------
currentFrame:int  [read-only]

MovieClip 인스턴스의 타임 라인내의 재생 헤드가 놓여져 있는 프레임의 번호를 나타낸다. 무비 클립에 복수의 씬이 있는 경우에는 이 값은 현재의 씬의 프레임 번호다.

public function get currentFrame():int

다음의 코드에서는 gotoAndStop() 메소드와 currentFrame 프롭퍼티를 사용하여 무비 클립 mc1 의 재생 헤드를 현재의 위치로부터 5 프레임 앞에서 정지한다.
mc1.gotoAndStop(mc1.currentFrame + 5);
-----------------------------------------------------------------------------
currentLabel:String  [read-only]

MovieClip 인스턴스의 타임 라인내의 재생 헤드가 놓여져 있는 현재의 라벨이다.

public function get currentLabel():String

다음의 코드에서는 MovieClip 오브젝트 mc1 의 currentLabel 프롭퍼티의 사용 방법을 나타낸다.

trace(mc1.currentLabel);
-----------------------------------------------------------------------------
currentLabels:Array  [read-only]

현재의 씬의 FrameLabel 오브젝트의 배열을 돌려준다. MovieClip 인스턴스가 씬을 사용하고 있지 않는 경우, 배열에는 MovieClip 인스턴스 전체의 모든 프레임 라벨이 포함된다.

public function get currentLabels():Array

다음의 코드에서는 MovieClip 오브젝트 mc1 의 currentLabels 프롭퍼티의 사용 방법을 나타낸다. FrameLabel 클래스에는 frame과 name 프롭퍼티가 정의되어 있다.

import flash.display.FrameLabel;
var labels:Array = mc1.currentLabels;
for (var i:uint = 0; i < labels.length; i++) {
var label:FrameLabel = labels[i];
trace("frame " + label.frame + ": " + label.name);
}
mc1의 프레임 중에 1프레임에 “label1”, 15프레임에 “label2”가 정의되어 있을 경우,
출력 :
frame 1: label1
frame 15: label2
-----------------------------------------------------------------------------
currentScene:Scene  [read-only]

MovieClip 인스턴스의 타임 라인내의 재생 헤드가 놓여져 있는 현재의 씬이다.

public function get currentScene():Scene

다음의 코드에서는 MovieClip 오브젝트 mc1 의 currentScene 프롭퍼티의 사용 방법을 나타낸다.

import flash.display.Scene;
var scene:Scene = mc1.currentScene;
trace(scene.name + ": " + scene.numFrames + " frames");
-----------------------------------------------------------------------------
enabled:Boolean  [read-write]

무비 클립의 유효 / 무효를 나타내는 불리언 값이다. enabled 의 디폴트는 true다. Enabled을 false 로 설정되면 버튼 무비클립의 [오버], [다운], [업]의 각 프레임은 무효가 되지만 이벤트 (mouseDown ,mouseUp ,keyDown ,keyUp 등)를 계속 받는다.

enabled 프롭퍼티는 무비 클립의 버튼을 닮은 프롭퍼티만을 제어한다. enabled 프롭퍼티는 언제라도 변경할 수 있다. 이 프롭퍼티의 변경 후 무비 클립은 곧바로 유효 / 무효가 된다. enabled 프롭퍼티가 false로 설정되어 있는 경우 오브젝트는 자동 탭 순서에 포함되지 않는다.

public function get enabled():Boolean
public function set enabled(value:Boolean):void

다음의 코드에서는 enabled 프롭퍼티를 사용하여 MovieClip 오브젝트 mc1 의 버튼을 닮은 프롭퍼티를 무효로 하는 방법을 나타낸다.

mc1.enabled = true;
mc1.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(evt:Event):void{
trace(evt.currentTarget.name);
}
위 코드에서 mc1이라는 버튼에서 over, out, down 프레임은 무효화 되지만 마우스 클릭을 통한 이벤트는 계속 받고 있는 것을 확인 할 수 있다.
-----------------------------------------------------------------------------
framesLoaded:int  [read-only]

스트리밍 SWF 파일로부터 로드 된 프레임수를 나타낸다. frameLoaded 프롭퍼티를 사용하고 특정의 프레임과 그 전의 모든 프레임의 내용이 로드 되고 있어 브라우저로 로컬에 사용할 수 있을지를 판별할 수 있다. 이것을 사용하여 큰 용량으로 제작된 SWF 파일의 다운로드를 감시할 수 있다. 예를 들어 SWF 파일의 지정된 프레임이 로드를 완료할 때까지 그 SWF 파일이 로드되지 않았다는 것을 나타내는 메세지를 유저에게 표시하는 경우에 사용할 수 있다.

무비 클립에 복수의 씬이 있는 경우는 framesLoaded 프롭퍼티는 무비 클립내의 모든 씬의 로드가 끝난 프레임의 수를 돌려준다.

public function get framesLoaded():int

다음의 코드에서는 framesLoaded 프롭퍼티와 totalFrames 프롭퍼티를 사용하고 스트리밍 MovieClip 오브젝트 mc1 의 로드가 완료했는지를 확인하는 방법을 나타낸다.

if (mc1.framesLoaded == mc1.totalFrames) {
trace("OK.");
}
-----------------------------------------------------------------------------
scenes:Array  [read-only]

MovieClip 인스턴스내의 씬의 이름 프레임수 프레임 라벨이 리스트 되어 있는 Scene 오브젝트의 배열이다.

public function get scenes():Array

다음의 코드에서는 MovieClip 오브젝트 mc1 의 scenes 프롭퍼티의 사용 방법을 나타낸다.

import flash.display.Scene;
for (var i:uint = 0; i < mc1.scenes.length; i++) {
var scene:Scene = mc1.scenes[i];
trace("scene " + scene.name + ": " + scene.numFrames + " frames");
}
-----------------------------------------------------------------------------
totalFrames:int  [read-only]

MovieClip 인스턴스내의 프레임 총수를 나타낸다.

무비 클립에 복수의 프레임이 있는 경우는 totalFrames 프롭퍼티는 무비 클립내의 모든 씬의 프레임 총수를 돌려준다.

public function get totalFrames():int

다음의 코드에서는 MovieClip 오브젝트 mc1의 totalFrames 프롭퍼티의 사용 방법을 나타낸다.

trace(mc1.totalFrames);
-----------------------------------------------------------------------------
trackAsMenu:Boolean  [read-write]

SimpleButton 또는 MovieClip 오브젝트인 다른 표시 오브젝트가 마우스 해방 이벤트를 받을 수 있을지를 나타낸다. trackAsMenu 프롭퍼티를 사용해 메뉴를 작성할 수 있다. trackAsMenu 프롭퍼티는 임의의 SimpleButton 또는 MovieClip 오브젝트에 대해서 설정할 수 있다. trackAsMenu 프롭퍼티의 디폴트는 false다.

trackAsMenu 프롭퍼티는 언제라도 변경할 수 있다. 이 프롭퍼티를 변경한 무비 클립에는 새로운 동작이 즉시 반영된다.

public function get trackAsMenu():Boolean
public function set trackAsMenu(value:Boolean):void

다음의 코드에서는 trackAsMenu 프롭퍼티를 사용해 MovieClip 오브젝트 mc1의 마우스 해방 이벤트를 유효하게 하는 방법을 나타낸다.

mc1.trackAsMenu = true;
-----------------------------------------------------------------------------
Constructor의 상세
-----------------------------------------------------------------------------
MovieClip()의 constructor   
public 함수 MovieClip()

new MovieClip()를 통해 무비클립 인스턴스를 작성 후 스테이지상의 표시 오브젝트 컨테이너의 addChild() 메소드 또는 addChildAt() 메소드를 호출할 수 있다.
-----------------------------------------------------------------------------
메소드의 상세
-----------------------------------------------------------------------------
gotoAndPlay() 메소드
public function gotoAndPlay(frame:Object, scene:String = null):void

지정된 프레임으로 SWF 파일의 재생을 시작한다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 행해진다. 프레임 뿐만이 아니라 씬도 지정하는 경우는 scene 파라미터의 값도 지정해 준다.
파라미터
    frame:Object — 재생 헤드의 발송지가 되는 프레임 번호를 나타내는 수치, 또는 재생 헤드의 발송지가 되는 프레임의 라벨을 나타내는 스트링이다. 번호를 지정하는 경우는 지정하는 씬으로의 번호를 지정한다. 씬을 지정하지 않는 경우는 재생하는 글로벌 프레임 번호를 결정하는데 현재의 씬을 관련지을 수 있다 .씬을 지정했을 경우 재생 헤드는 지정된 씬내의 프레임 번호로 점프 한다.
 
    scene:String (default = null) — 재생하는 씬의 이름이다. 이 파라미터는 옵션이다.

다음의 코드에서는 gotoAndPlay() 메소드를 사용해 무비 클립 mc1의 재생 헤드를 현재의 위치로부터 5프레임 앞에서 진행한다.

mc1.gotoAndPlay(mc1.currentFrame + 5);
다음의 코드에서는 gotoAndPlay() 메소드를 사용해 무비 클립 mc1의 재생 헤드를 "Scene 12"이라는 이름의 씬내의 "intro" 라벨 프레임으로 이동한다.

mc1.gotoAndPlay("intro", "Scene 12");
-----------------------------------------------------------------------------
gotoAndStop() 메소드    
public function gotoAndStop(frame:Object, scene:String = null):void

이 무비 클립의 지정된 프레임에 재생 헤드를 보내서 정지시킨다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 이루어진다. 프레임에 있는 씬을 지정하는 경우는 scene 파라미터를 지정한다.
파라미터
    frame:Object — 재생 헤드의 발송지가 되는 프레임 번호를 나타내는 수치 또는 재생 헤드의 발송지가 되는 프레임의 라벨을 나타내는 스트링이다. 번호를 지정하는 경우는 지정하는 씬으로의 번호를 지정한다. 씬을 지정하지 않는 경우는 발송지의 글로벌 프레임 번호를 결정하는데 현재의 씬을 관련지을 수 있다. 씬을 지정했을 경우 재생 헤드는 지정된 씬내의 프레임 번호에 보내져 정지한다.
 
    scene:String (default = null) — 씬이름이다. 이 파라미터는 옵션이다.

다음의 코드에서는 gotoAndStop() 메소드와 currentFrame 프롭퍼티를 사용하여 무비 클립 mc1의 재생 헤드를 현재의 위치로부터 5프레임 앞에서 정지한다.

mc1.gotoAndStop(mc1.currentFrame + 5);
다음의 코드에서는 gotoAndStop()을 사용해 무비 클립 mc1의 재생 헤드를 "Scene 12" 이라는 이름의 씬내의 "finale"프레임 라벨 위치로 이동해 정지한다.

mc1.gotoAndStop("finale", "Scene 12");
-----------------------------------------------------------------------------
nextFrame() 메소드    
public function nextFrame():void

다음의 프레임에 재생 헤드를 보내 정지한다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 이루어진다.

다음의 예에서는 2개의 SimpleButton 오브젝트가 타임 라인을 제어한다. prev 버튼은 재생 헤드를 전의 프레임으로 이동하고 nextBtn 버튼은 재생 헤드를 다음의 프레임에 이동한다.

import flash.events.MouseEvent;
mc1.stop();
prevBtn.addEventListener(MouseEvent.CLICK, goBack);
nextBtn.addEventListener(MouseEvent.CLICK, goForward);

function goBack(event:MouseEvent):void {
mc1.prevFrame();
}

function goForward(event:MouseEvent):void {
mc1.nextFrame();
}
-----------------------------------------------------------------------------
nextScene() 메소드    
public function nextScene():void

MovieClip 인스턴스의 다음의 씬에 재생 헤드를 이동한다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 이루어진다.

다음의 예에서는 2개의 SimpleButton 오브젝트가 타임 라인을 제어한다. prevBtn 버튼은 재생 헤드를 전 씬으로 이동하고 nextBtn 버튼은 재생 헤드를 다음의 씬으로 이동한다.

import flash.events.MouseEvent;

mc1.stop();
prevBtn.addEventListener(MouseEvent.CLICK, goBack);
nextBtn.addEventListener(MouseEvent.CLICK, goForward);

function goBack(event:MouseEvent):void {
mc1.prevScene();
}

function goForward(event:MouseEvent):void {
mc1.nextScene();
}
-----------------------------------------------------------------------------
play() 메소드    
public function play():void

무비 클립의 타임 라인내에서 재생 헤드를 이동한다.

다음의 코드에서는 stop() 메소드를 사용해 무비 클립 mc1을 정지하여 유저가 continueText라는 이름의 텍스트 필드를 클릭했을 때에 재생을 재 시작한다.

import flash.text.TextField;
import flash.events.MouseEvent;

var continueText:TextField = new TextField();
continueText.text = "Play movie...";
addChild(continueText);

mc1.stop();
continueText.addEventListener(MouseEvent.CLICK, resumeMovie);

function resumeMovie(event:MouseEvent):void {
mc1.play();
}
-----------------------------------------------------------------------------
prevFrame() 메소드    
public function prevFrame():void

전 프레임에 재생 헤드를 되돌려 정지한다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 이루어진다.

다음의 예에서는 2개의 SimpleButton 오브젝트가 타임 라인을 제어한다. prev 버튼은 재생 헤드를 전의 프레임으로 이동하고 nextBtn 버튼은 재생 헤드를 다음의 프레임에 이동한다.

import flash.events.MouseEvent;

mc1.stop();
prevBtn.addEventListener(MouseEvent.CLICK, goBack);
nextBtn.addEventListener(MouseEvent.CLICK, goForward);

function goBack(event:MouseEvent):void {
mc1.prevFrame();
}

function goForward(event:MouseEvent):void {
mc1.nextFrame();
}
-----------------------------------------------------------------------------
prevScene() 메소드    
public function prevScene():void

MovieClip 인스턴스의 전 씬에 재생 헤드를 이동한다. 이 처리는 프레임내의 모든 잔존 액션이 실행을 완료한 후에 이루어진다.

다음의 예에서는 2개의 SimpleButton 오브젝트가 타임 라인을 제어한다. prevBtn 버튼은 재생 헤드를 전의 씬으로 이동하고 nextBtn 버튼은 재생 헤드를 다음의 씬으로 이동한다.

import flash.events.MouseEvent;

mc1.stop();
prevBtn.addEventListener(MouseEvent.CLICK, goBack);
nextBtn.addEventListener(MouseEvent.CLICK, goForward);

function goBack(event:MouseEvent):void {
mc1.prevScene();
}

function goForward(event:MouseEvent):void {
mc1.nextScene();
}
-----------------------------------------------------------------------------
다음의 예는 MovieClipExample 클래스를 사용하여 MovieClip의 다양한 프롭퍼티를 감시하는 방법을 나타낸 것이다. 이것은 아래와 같은 순서로 실행된다.

   1. constructor    함수로 MovieClipExample 오브젝트(MovieClip을 계승한다)의 프롭퍼티의 값을 표시하는데 사용하는 텍스트 필드를 정의한다.
   2. getPropertiesString() 메소드의 반환값이 outputText 텍스트 필드의 텍스트로서 사용된다. getPropertiesString() 메소드는 무비 클립의 이하의 프롭퍼티의 값이 받아들여진 스트링을 돌려준다. currentFrame, currentLabel, currentScene, framesLoaded ,totalFrames , 및 trackAsMenu .
   3. constructor    함수내의 2행의 코드는 outputText 텍스트 필드의 width 및 height 프롭퍼티를 조정한다.
   4. constructor    함수의 마지막 행은 outputText 텍스트 필드를 표시 리스트에 추가한다.

package {
import flash.display.MovieClip;
import flash.text.TextField;

public class MovieClipExample extends MovieClip {

public function MovieClipExample() {
var outputText:TextField = new TextField();
outputText.text = getPropertiesString();
outputText.width = stage.stageWidth;
outputText.height = outputText.textHeight;
addChild(outputText);
}

private function getPropertiesString():String {
var str:String = ""
+ "currentFrame: " + currentFrame + "n"
+ "currentLabel: " + currentLabel + "n"
+ "currentScene: " + currentScene + "n"
+ "framesLoaded: " + framesLoaded + "n"
+ "totalFrames: " + totalFrames + "n"
+ "trackAsMenu: " + trackAsMenu + "n";
return str;
}
}
}
    

설정

트랙백

댓글

[AS3] PrintJob 클래스

Programming/ActionScript 3.0 2007. 6. 20. 05:04

Adobe Flash Player 9는 OS 의 프린트 인터페이스와 통신하여 페이지를 프린트 스풀러에 보낼 수 있다 .Flash Player로부터 스풀러에 송신하는 페이지에는 표시되고 있는 컨텐츠, 동적인 컨텐츠, 또는 화면외에 유저에게 표시되지 않는 컨텐츠 (데이타베이스의 값이나 동적인 텍스트 등)를 포함할 수 있다. 또한 flash.printing.PrintJob 클래스의 프롭퍼티가 유저의 프린터 설정에 근거한 Flash Player에 의해 설정되기 위해서 적절한 페이지 서식을 지정할 수 있다.


페이지의 프린트
ActionScript를 사용하여 Flash Player로부터 페이지를 프린트 할 때의 기본적인 순서로서는 다음과 같이 4 개의 주요한 스테이트먼트 순서로 작성된다.

•    new PrintJob() : 지정한 이름으로 새로운 프린트 작업을 작성한다.
•    PrintJob.start() : OS 의 프린트 처리를 시작한다. 유저의 프린트 다이알로그 박스가 표시되어 프린트 작업의 읽기 전용 프롭퍼티가 설정된다.
•    PrintJob.addPage() : 프린트 작업의 컨텐츠에 관한 상세 정보를 설정한다. 파라미터로 Sprite 오브젝트 (및 Sprite에 포함되는 Child)의 지정, 프린트 범위의 사이즈 지정, 및 이미지를 벡터와 비트 맵과 같이 어느 형식에서 프린트 할 것인가를 지정할 수 있다. addPage()를 여러 차례 호출하면 복수의 페이지에 복수의 스프라이트를 프린트 할 수 있다.
•    PrintJob.send() : 페이지를 OS 의 프린터에 전송한다.

따라서 매우 단순한 스크립트는 다음과 같다 (import 및 class 스테이트먼트는 컴파일 하기 위해서 필요함) .

import flash.printing.PrintJob;
public class BasicPrintExample extends Sprite {
var myPrintJob:PrintJob = new PrintJob();
myPrintJob.start() ;
myPrintJob.addPage(mySprite);
myPrintJob.send();
}
복수 페이지 프린트
복수 페이지의 컨텐츠를 프린트 하는 경우는 각 페이지의 컨텐츠를 다른 스프라이트 (아래의 예에서는 sheet1 및 sheet2)에 할당하여 각각에 붙여 PrintJob.addPage()를 호출한다.

package {
import flash.display.MovieClip;
import flash.printing.PrintJob;
import flash.printing.PrintJobOrientation;
import flash.display.Stage;
import flash.display.Sprite;
import flash.text.TextField;
import flash.geom.Rectangle;

public class PrintMultiplePages extends MovieClip {
private var sheet1:Sprite;
private var sheet2:Sprite;

public function PrintMultiplePages():void {
init();
printPages();
}

private function init():void {
sheet1 = new Sprite();
createSheet(sheet1, "Once upon a time...", {x:10, y:50, width:80, height:130});
sheet2 = new Sprite();
createSheet(sheet2, "There was a great story to tell, and it ended quickly.nnThe end.", null);
}

private function createSheet(sheet:Sprite, str:String, imgValue:Object):void {
sheet.graphics.beginFill(0xEEEEEE);
sheet.graphics.lineStyle(1, 0x000000);
sheet.graphics.drawRect(0, 0, 100, 200);
sheet.graphics.endFill();

var txt:TextField = new TextField();
txt.height = 200;
txt.width = 100;
txt.wordWrap = true;
txt.text = str;

if(imgValue != null) {
var img:Sprite = new Sprite();
img.graphics.beginFill(0xFFFFFF);
img.graphics.drawRect(imgValue.x, imgValue.y, imgValue.width, imgValue.height);
img.graphics.endFill();
sheet.addChild(img);
}
sheet.addChild(txt);
}

private function printPages():void {
var pj:PrintJob = new PrintJob();
var pagesToPrint:uint = 0;
if(pj.start()) {
if(pj.orientation == PrintJobOrientation.LANDSCAPE) {
throw new Error("Page is not set to an orientation of portrait.");
}

sheet1.height = pj.pageHeight;
sheet1.width = pj.pageWidth;
sheet2.height = pj.pageHeight;
sheet2.width = pj.pageWidth;

try {
pj.addPage(sheet1);
pagesToPrint++;
}
catch(e:Error) {
// 에러에 응답한다
}

try {
pj.addPage(sheet2);
pagesToPrint++;
}
catch(e:Error) {
// 에러에 응답한다
}

if(pagesToPrint > 0) {
pj.send();
}
}
}
}
}

확대•축소, 트리밍, 및 응답

경우에 따라서는 화면의 표시와 프린트와의 외관상의 차이에 대응하기 위해서 표시 오브젝트의 사이즈 (또는 그 외의 프롭퍼티)를 프린트시에 조정할 필요가 있다. 프린트 하기 전에 표시 오브젝트의 프롭퍼티 ( scaleX 및 scaleY 프롭퍼티) 를 조정할 때 프린트 범위를 정의하는 사이즈보다 크게 오브젝트를 확대하면 일그러짐이 발생하는 것에 주의해야 한다. 또한 많은 경우에는 페이지를 프린트 한 다음에 프롭퍼티를 원래의 값으로 되돌릴 필요가 있다.
다음의 코드는 txt 표시 오브젝트의 치수를 확대•축소 (단, 배경에 있는 녹색의 박스는 그대로)하고 있는 것으로 지정한 원본 사이즈에 의해서 텍스트 필드가 트리밍 되는 예를 보여준다. 프린트 한 다음은 텍스트 필드를 화면 표시용의 원래의 사이즈로 되돌린다. OS 의 [인쇄] 다이알로그 박스로 프린트 작업이 캔슬되었을 경우 Flash Player의 표시 내용을 변경하여 작업이 캔슬된 것을 경고한다.
package {
import flash.printing.PrintJob;
import flash.display.Sprite;
import flash.text.TextField;
import flash.display.Stage;
import flash.geom.Rectangle;

public class PrintScaleExample extends Sprite {

private var bg:Sprite;
private var txt:TextField;

public function PrintScaleExample():void {
init();
draw();
printPage();
}

private function printPage():void {
var pj:PrintJob = new PrintJob();
txt.scaleX = 3;
txt.scaleY = 2;
if(pj.start()) {
trace(">> pj.orientation: " + pj.orientation);
trace(">> pj.pageWidth: " + pj.pageWidth);
trace(">> pj.pageHeight: " + pj.pageHeight);
trace(">> pj.paperWidth: " + pj.paperWidth);
trace(">> pj.paperHeight: " + pj.paperHeight);

try {
pj.addPage(this, new Rectangle(0, 0, 100, 100));
}
catch(e:Error) {
// 아무것도 하지 않는다
}
pj.send();
}
else {
txt.text = "Print job canceled";
}
// txt 의 확대•축소 프롭퍼티를 바탕으로 되돌린다
txt.scaleX = 1;
txt.scaleY = 1;
}


private function init():void {
bg = new Sprite();
bg.graphics.beginFill(0x00FF00);
bg.graphics.drawRect(0, 0, 100, 200);
bg.graphics.endFill();

txt = new TextField();
txt.border = true;
txt.text = "Hello World";
}

private function draw():void {
addChild(bg);
addChild(txt);
txt.x = 50;
txt.y = 50;
}
}
}
    

설정

트랙백

댓글

[AS3] Matrix 오브젝트의 사용

Programming/ActionScript 3.0 2007. 6. 20. 04:01
Matrix 클래스는 좌표 공간의 사이에 포인트를 매핑 하는 방법을 결정하는 변환 행렬을 나타낸다. Matrix 오브젝트의 프롭퍼티를 설정하여 Matrix 오브젝트를 Transform 오브젝트의 matrix 프롭퍼티에 적용하고 그 Transform 오브젝트를 표시 오브젝트의 transform 프롭퍼티에 적용하는 것으로 표시 오브젝트에 대해서 다양한 그래픽 변환을 실행할 수 있다. 실현될 수 있는 변환 기능으로서는 평행이동 (x 위치 및 y 위치의 이동) , 회전, 확대•축소, 경사등이 있다.

Matrix 오브젝트의 정의
매트릭스는 프롭퍼티 (a ,b ,c ,d ,tx ,ty)를 조정해 직접 정의할 수도 있지만 createBox() 메소드를 사용해 정의하는 편이 간단하다. 이 메소드의 파라미터에서는 작성하는 매트릭스에서 정의하는 확대•축소, 회전, 평행이동의 효과를 직접 정의할 수 있다. 예를 들어 다음의 코드로 작성한 Matrix 오브젝트에는 수평 방향 2.0배 확대, 수직 방향 3.0배 확대, 45도의 회전, 오른쪽으로 10 피크셀의 이동, 및 아래에 20 피크셀의 이동의 효과가 있다.

var matrix:Matrix = new Matrix();
var scaleX:Number = 2.0;
var scaleY:Number = 3.0;
var rotation:Number = 2 * Math.PI * (45 / 360);
var tx:Number = 10;
var ty:Number = 20;
matrix.createBox(scaleX, scaleY, rotation, tx, ty);
또한 scale() ,rotate() ,translate() 의 각 메소드를 사용하면 Matrix 오브젝트로 설정한 확대•축소, 회전, 평행이동의 효과를 변경할 수 있다. 이러한 메소드로 지정한 값은 기존의 Matrix 오브젝트로 설정되어 있는 값과 합쳐진다. 예를 들어, 다음의 코드에서는 scale() (와)과 rotate()를 2 회 호출하고 있기 때문에 Matrix 오브젝트의 효과는 4 배의 확대와 60도의 회전이 된다.

var matrix:Matrix = new Matrix();
var rotation:Number = 2 * Math.PI * (30 / 360); // 30
var scaleFactor:Number = 2;
matrix.scale(scaleFactor, scaleFactor);
matrix.rotate(rotation);
matrix.scale(scaleX, scaleY);
matrix.rotate(rotation);
myDisplayObject.transform.matrix = matrix;
경사 변형을 Matrix 오브젝트에 적용하려면 b 프롭퍼티 또는 c 프롭퍼티를 조정한다. b 프롭퍼티를 조정하면 매트릭스가 수직 방향으로 경사하고 c 프롭퍼티를 조정하면 매트릭스가 수평 방향으로 경사한다. 다음의 코드는 myMatrix Matrix 오브젝트를 수직 방향으로 2배 경사한 것이다.

var skewMatrix:Matrix = new Matrix();
skewMatrix.b = Math.tan(2);
myMatrix.concat(skewMatrix);
Matrix 에 의한 변환은 표시 오브젝트의 transform 프롭퍼티에 적용할 수 있다. 예를 들어 다음의 코드에서는 myDisplayObject오브젝트에 매트릭스 변환을 적용하고 있다.

var matrix:Matrix = myDisplayObject.transform.matrix;
var scaleFactor:Number = 2;
var rotation:Number = 2 * Math.PI * (60 / 360); // 60
matrix.scale(scaleFactor, scaleFactor);
matrix.rotate(rotation);
myDisplayObject.transform.matrix = matrix;
첫 라인에서 myDisplayObject 표시 오브젝트가 사용하는 기존의 변환 매트릭스 (myDisplayObject 표시 오브젝트의 transformation, 프롭퍼티의 matrix 프롭퍼티) 를 Matrix 오브젝트로 설정한다. 이렇게 하는 것으로 표시 오브젝트의 위치, 확대율, 회전각을 근거로 한 Matrix 클래스 메소드의 실행에 의한 효과를 누적하여 적용할 수 있다.

메모 : flash.geometry 패키지에는 ColorTransform 클래스도 포함되어 있지만 이 클래스는 Transform 오브젝트의 colorTransform 프롭퍼티를 설정할 때에 사용하는 것이다. 기하학 변환에는 사용하지 않는다.


그라데이션에 관한 Matrix 오브젝트의 정의
셰이프로 사용하는 그라데이션을 정의하려면 flash.display.Graphics 클래스의 beginGradientFill() 및 lineGradientStyle() 메소드를 사용한다. 그라데이션을 정의할 때 이러한 메소드의 파라미터로 매트릭스를 지정한다.
위와 같은 목적으로 매트릭스를 작성하려면 createGradientBox() 메소드를 사용해 그라데이션 정의용의 장방형을 정의하는 것이 가장 간단한 방법이다. createGradientBox() 메소드로 지정하는 파라미터에서는 그라데이션의 확대•축소, 회전, 및 위치를 정의한다. 예를 들어 다음과 같은 성질을 가지는 그라데이션을 작성한다고 하면

•    GradientType.LINEAR
•    그린과 블루의 2 색,ratios 배열을 [0, 255] (으)로 설정
•    SpreadMethod.PAD
•    InterpolationMethod.LINEAR_RGB

다음의 예로 보이는 그라데이션은 createGradientBox() 메소드의 rotation 파라미터가 다르지만 그 외의 설정은 모두 같다.

사용자 삽입 이미지
width = 100;
height = 100;
rotation = 0;
tx = 0;
ty = 0;     



사용자 삽입 이미지
width = 100;
height = 100;
rotation = Math.PI/4; // 45
tx = 0;
ty = 0;     



사용자 삽입 이미지
width = 100;
height = 100;
rotation = Math.PI/2; // 90
tx = 0;
ty = 0;     


다음의 예로 보이는 그린 블루의 선상 그라데이션 효과는 createGradientBox() 메소드의 rotation ,tx ,ty 파라미터가 다르지만 그 외의 설정은 모두 같다.

사용자 삽입 이미지
width = 50;
height = 100;
rotation = 0;
tx = 0;
ty = 0;     



사용자 삽입 이미지
width = 50;
height = 100;
rotation = 0
tx = 50;
ty = 0;     



사용자 삽입 이미지
width = 100;
height = 50;
rotation = Math.PI/2; // 90
tx = 0;
ty = 0;     



사용자 삽입 이미지
width = 100;
height = 50;
rotation = Math.PI/2; // 90
tx = 0;
ty = 50;     



사용자 삽입 이미지
width = 50;
height = 100;
rotation = 0;
tx = 25;
ty = 0;     



다음의 코드는 마지막에 보이는 방사상 그라데이션을 생성한다.

import flash.display.Shape;
import flash.display.GradientType;
import flash.geom.Matrix;

var type:String = GradientType.RADIAL;
var colors:Array = [0x00FF00, 0x000088];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var spreadMethod:String = SpreadMethod.PAD;
var interp:String = InterpolationMethod.LINEAR_RGB;
var focalPtRatio:Number = 0;

var matrix:Matrix = new Matrix();
var boxWidth:Number = 50;
var boxHeight:Number = 100;
var boxRotation:Number = Math.PI/2; // 90
var tx:Number = 25;
var ty:Number = 0;
matrix.createGradientBox(boxWidth, boxHeight, boxRotation, tx, ty);

var square:Shape = new Shape;
square.graphics.beginGradientFill(type,
colors,
alphas,
ratios,
matrix,
spreadMethod,
interp,
focalPtRatio);
square.graphics.drawRect(0, 0, 100, 100);
addChild(square);

// 위와 같으나 package 형태의 클래스로 외부에 저장된 as 파일
package {
import flash.display.*;
import flash.geom.*;


public class RadialGradientExample extends Sprite {
public function RadialGradientExample() {
var type:String = GradientType.RADIAL;
var colors:Array = [0x00FF00, 0x000088];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var spreadMethod:String = SpreadMethod.PAD;
var interp:String = InterpolationMethod.LINEAR_RGB;
var focalPtRatio:Number = 0;

var matrix:Matrix = new Matrix();
var boxWidth:Number = 50;
var boxHeight:Number = 100;
var boxRotation:Number = Math.PI/2;// 90°
var tx:Number = 25;
var ty:Number = 0;
matrix.createGradientBox(boxWidth, boxHeight, boxRotation, tx, ty);

var square:Shape = new Shape;
square.graphics.beginGradientFill(type,
colors,
alphas,
ratios,
matrix,
spreadMethod,
interp,
focalPtRatio);
square.graphics.drawRect(0, 0, 100, 100);
addChild(square);
}
}}

    

설정

트랙백

댓글

[AS3] Rectangle 오브젝트의 사용

Programming/ActionScript 3.0 2007. 6. 20. 03:21
1. Rectangle 오브젝트의 개요
Rectangle 오브젝트는 장방형의 영역을 정의한다. Rectangle 오브젝트에는 위치 (좌상구석의 x 좌표와 y 좌표로 정의된다)와 프롭퍼티 width, height가 있다. Rectangle 오브젝트의 프롭퍼티를 지정하려면 다음과 같이 Rectangle 클래스의 인스턴스를 생성한다.
import flash.geom.Rectangle;
var rx:Number = 0;
var ry:Number = 0;
var rwidth:Number = 100;
var rheight:Number = 50;
var rect1:Rectangle = new Rectangle(rx, ry, rwidth, rheight);
2. Rectangle 오브젝트의 사이즈 변경과 이동
Rectangle 오브젝트의 사이즈 변경 및 이동하려면 다수의 방법이 있다. x 및 y 프롭퍼티를 변경하면 직접 Rectangle 오브젝트의 위치를 이동할 수 있다.

import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace (rect1) // (x=0, y=0, w=100, h=50)
rect1.x = 20;
rect1.y = 30;
trace (rect1); // (x=20, y=30, w=100, h=50)
다음코드에서 알 수 있듯이 left 또는 top 프롭퍼티를 변경하면 Rectangle 오브젝트의 위치를 이동해 left 및 top 각각의 값에 대응하는 x 및 y 프롭퍼티의 값이 변화한다. 단, Rectangle 오브젝트의 우측아래구석의 위치는 변화하지 않고 그 대신 장방형의 사이즈가 변화한다.

import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace (rect1) // (x=0, y=0, w=100, h=50)
rect1.left = 20;
rect1.top = 30;
trace (rect1); // (x=20, y=30, w=80, h=20)
다음의 예에서 알 수 있듯이 Rectangle 오브젝트의 bottom 또는 right 프롭퍼티를 변경하면 좌상구석의 위치는 변화하지 않고 장방형의 사이즈가 변화한다.

import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace (rect1) // (x=0, y=0, w=100, h=50)
rect1.right = 60;
rect1.bottom = 20;
trace (rect1); // (x=0, y=0, w=60, h=20)
아래 코드는 Rectangle 오브젝트의 offset() 메소드를 이용하여 위치를 이동하는 방법이다.

import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace (rect1) // (x=0, y=0, w=100, h=50)
rect1.offset(20, 30);
trace (rect1); // (x=20, y=30, w=100, h=50)
offsetPt() 메소드도 이와 같지만 파라미터로서 x 및 y 의 오프셋 값이 아니라 Point 오브젝트를 지정한다.
Rectangle 오브젝트의 inflate() 메소드에 dx 및 dy 의 2 개의 파라미터를 지정해 사이즈를 변경할 수도 있다. 장방형의 중심점을 기준으로 크기를 변화시킬 수 있다.

import flash.geom.Rectangle;
var x1:Number = 0;
var y1:Number = 0;
var width1:Number = 100;
var height1:Number = 50;
var rect1:Rectangle = new Rectangle(x1, y1, width1, height1);
trace (rect1) // (x=0, y=0, w=100, h=50)
rect1.inflate(6,4);
trace (rect1); // (x=-6, y=-4, w=112, h=58)
inflatePt() 메소드도 이와 같지만 파라미터로서 dx 및 dy 의 값이 아니라 Point 오브젝트를 지정한다.

3. 2 개의 Rectangle 오브젝트로부터 완성되는 결합 및 교차의 취득
2 개의 장방형을 맞춘 경계선에 의해서 형성되는 장방형 영역을 취득하려면 union() 메소드를 사용한다.

import flash.display.*;
import flash.geom.Rectangle;
var rect1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(rect1); // (x=0, y=0, w=100, h=100)
var rect2:Rectangle = new Rectangle(120, 60, 100, 100);
trace(rect2); // (x=120, y=60, w=100, h=100)
trace(rect1.union(rect2)); // (x=0, y=0, w=220, h=160)
2 개의 장방형이 서로 겹치는 부분을 나타내는 장방형 영역을 취득하려면 intersection() 메소드를 사용한다.

import flash.display.*;
import flash.geom.Rectangle;
var rect1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(rect1); // (x=0, y=0, w=100, h=100)
var rect2:Rectangle = new Rectangle(80, 60, 100, 100);
trace(rect2); // (x=120, y=60, w=100, h=100)
trace(rect1.intersection(rect2)); // (x=80, y=60, w=20, h=40)
2 개의 장방형서로 겹쳐지는 부분이 있는지를 조사하려면 intersects() 메소드를 사용한다. 또한, 표시 오브젝트가 스테이지상의 특정 영역내에 배치되어 있는지를 조사하는 경우에도 intersects() 메소드를 사용할 수 있다. 다음의 코드에서는 circle 오브젝트를 포함한 표시 오브젝트 컨테이너의 좌표 공간이 스테이지의 좌표 공간과 같다는 전제에서 intersects() 메소드를 사용하고, 표시 오브젝트 circle이 target1 및 target2의 Rectangle 오브젝트로 정의된 스테이지의 지정된 영역과 교차하고 있을지를 판단하는 방법을 나타내고 있다.

import flash.display.*;
import flash.geom.Rectangle;
var circle:Shape = new Shape();
circle.graphics.lineStyle(2, 0xFF0000);
circle.graphics.drawCircle(250, 250, 100);
addChild(circle);
var circleBounds:Rectangle = circle.getBounds(stage);
var target1:Rectangle = new Rectangle(0, 0, 100, 100);
trace(circleBounds.intersects(target1)); // false
var target2:Rectangle = new Rectangle(0, 0, 300, 300);
trace(circleBounds.intersects(target2)); // true
위와 같이 2 개의 표시 오브젝트의 경계를 나타내는 부분이 서로 겹치는지를 조사하는 경우에도 intersects() 메소드를 사용할 수 있다. 표시 오브젝트의 경계선내의 영역에 포함된 선의 굵기에 의해서 여분의 스페이스가 필요한 경우는 그 만큼을 포함한 영역을 취득하기 위해서 DisplayObject 클래스의 getRect() 메소드를 사용할 수 있다.

    

설정

트랙백

댓글

AS3 공부를 하며...

Miscellaneous/Story 2007. 6. 18. 00:37
flalab 모임에서 받은 CS3를 깔기 위해 새로운 마음으로 윈도우를 밀고 사용중이다. 아직 국내 AS3관련 자료가 많지 않아서 외국 사이트 및 튜토리얼등을 찾아다니며 공부를 하고 있는데 지금은 어도비 사이트에 있는 자료가 상당히 도움을 주고 있다.

예전에 블로그에 만들어 놓았던 Infinite 메뉴 부분을 CS3로 꾸며보기 위해 준비중이다. 아직은 CS3에서 자주 사용되는 이벤트 처리의 상세한 부분까지 개념을 잡지 못했고 AS3의  패키지가 정리는 잘 되어 있지만 대부분 사용해 보지 않은 기능들이 많아서 import 전에 생각을 많이 하게 된다.

일단 ActionScript 3.0을 공부하는 진도에 따라서 차근차근 Infinite 메뉴는 구상해봐야 겠다. 외국에 비해서는 많이 늦은 감이 있는 공부지만 papervision3d를 만지작 거리다보면 AS3를 공부 하지 않을 수가 없다. 매력적인 엔진임은 분명하다. 앞으로 3d관련하여 재미있는 결과물들을 많이 도출할 수 있을 듯 싶다.


    

설정

트랙백

댓글

[AS3] 이벤트 청취자

Programming/ActionScript 3.0 2007. 6. 17. 03:30
이벤트 청취자란 특정한 이벤트에 응답하여 Flash Player에 의해 실행되는 함수이며 이벤트 핸들러라고도 불린다. 이벤트 청취자를 등록하려면 2개의 순서로 실행한다. 우선, 목적 이벤트에 응답하여 Flash Player에서 실행시키기 위한 함수 또는 클래스 메소드를 작성한다. 이것은 청취자 함수 또는 이벤트 핸들러 함수로 불리기도 한다. 그 다음에 addEventListener() 메소드를 사용하여 그 청취자 함수를 이벤트의 타겟 또는 해당하는 이벤트 플로우에 포함되는 임의의 표시 리스트 오브젝트에 등록하는 과정으로 진행한다.

청취자 함수의 작성
ActionScript 3.0의 이벤트 모델 가운데 청취자 함수의 작성에 관한 부분은 DOM 이벤트 모델에 준거하고 있지 않다. DOM 이벤트 모델에서는 이벤트 청취자와 청취자 함수가 명확하게 구별되고 있다. 이벤트 청취자는 EventListener 인터페이스를 implements한 클래스의 인스턴스를 의미하며 청취자 함수는 그 클래스가 갖춘 handleEvent() 메소드를 의미한다. DOM 이벤트 모델에 대해서는 청취자 함수 자체를 등록하는 것이 아니라 청취자 함수를 포함한 클래스 인스턴스를 등록하는 형식을 취한다.

ActionScript 3.0의 이벤트 모델은 이벤트 청취자와 청취자 함수와의 구별이 없다. ActionScript 3.0 에는 EventListener 인터페이스가 없고 청취자 함수는 클래스내 클래스외에 정의할 수도 있다. 또, 청취자 함수의 이름이 handleEvent() 일 필요는 없고 식별자로서 유효한 임의의 이름을 붙일 수 있다. ActionScript 3.0에서는 대체적으로 청취자 함수 자체의 이름을 등록하는 형식을 취하지만 그렇게 해야만 하는 것은 아니다.

클래스외에 정의한 청취자 함수
다음의 코드는 붉은 정방형의 셰이프를 표시하는 단순한 SWF 파일이다. 클래스내에 있는 clickHandler() 청취자 함수로 붉은 정방형에 대해 사용자의 마우스 클릭 이벤트를 받아들이고 있다.

package {
import flash.display.Sprite;

public class ClickExample extends Sprite {
public function ClickExample() {
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}

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

class ChildSprite extends Sprite {
public function ChildSprite() {
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
}

function clickHandler(event:MouseEvent):void {
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
이 SWF 파일에서는 유저에 의해서 정방형이 클릭되면 Flash Player는 다음의 trace 출력을 생성한다.

clickHandler detected an event of type: click
the this keyword refers to: [object global]

이벤트 오브젝트가 clickHandler()에 파라미터로서 건네 받고 있다. 이것에 의해 청취자 함수 중에서 이벤트 오브젝트를 조사할 수 있다. 이 예에서는 이벤트 오브젝트의 type 프롭퍼티를 사용하여 이벤트가 "click" 이벤트인 것을 확인하고 있다.

이 예에서는 this 키워드의 값도 확인하고 있다. this는 글로벌 오브젝트를 참조하고 있다. 왜냐하면 청취자 함수를 커스텀 클래스나 오브젝트에 속하지 않는 외부에서 정의하고 있기 때문이다.

클래스 메소드로서 정의한 청취자 함수
다음의 예에서는 위에서 이야기 한 것과 같이 ClickExample 클래스를 정의하고 있지만 clickHandler() 함수를 ChildSprite 클래스의 메소드로서 정의하고 있는 점이 다르다.

package {
import flash.display.Sprite;

public class ClickExample extends Sprite {
public function ClickExample() {
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}

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

class ChildSprite extends Sprite {
public function ChildSprite() {
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(event:MouseEvent):void {
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
}

이 SWF 파일로 유저에 의해서 붉은 정방형이 클릭되면 Flash Player는 다음의 trace 출력을 생성한다.

clickHandler detected an event of type: click
the this keyword refers to: [object ChildSprite]

this 키워드는 ChildSprite 인스턴스를 참조하고 있다. 이 점에 관해서는 동작이 변경되고 있어 ActionScript 2.0과는 다르다. ActionScript 2.0 의 컴퍼넌트에서는 UIEventDispatcher.addEventListener() 에 대해서 클래스 메소드를 지정했을 경우 청취자 메소드의 스코프는 메소드가 정의되고 있는 클래스가 아니라 이벤트를 브로드캐스트 한 컴퍼넌트에 근거해 정해지게 되어 있었다. 즉, 이 예와 같은 테크닉을 ActionScript 2.0에서 작성했다고하면 this 키워드는 ChildSprite 인스턴스가 아니라 이벤트를 브로드캐스트 한 컴퍼넌트를 참조하게 된다.

예전의 ActionScript에서는 청취자 메소드로부터 그 메소드가 있는 클래스 내의 다른 메소드나 프롭퍼티에 액세스 할 수 없기 때문에 경우에 따라서는 매우 큰 문제가 생기고 있었다. 이것을 회피하기 위해서 ActionScript 2.0 에는 mx.util.Delegate 클래스를 사용해서 청취자 메소드의 스코프를 변경할 수 있는 방법이 준비되어 있었다. 하지만 ActionScript 3.0부터는 addEventListener() 의 호출시에 bound methods가 작성되기 위해서 이 해결방법은 불필요한 것이 되었다. 결과적으로 this 키워드의 참조처는 ChildSprite 인스턴스인 child가 되어 ChildSprite 클래스내의 다른 메소드나 프롭퍼티에 액세스 할 수 있게 되었다.

바람직하지 않은 이벤트 청취자 등록의 방법
제 3 의 테크닉으로서 범용 오브젝트를 작성해서 그 오브젝트의 프롭퍼티에 의해서 동적으로 청취자 함수를 할당하는 방법이 있지만 이것을 사용하는 것은 추천할 수 없다. 이 방법을 설명하는 것은 ActionScript 2.0에서 일반적으로 사용되고 있었던 바람직하지 않은 방법이라는 이유 때문이다. ActionScript 3.0에서는 사용하지 않는 것이 좋다. 이 테크닉에서는 this 키워드의 참조처가 청취자 오브젝트가 아니라 글로벌 오브젝트가 되기 때문에 바람직하지는 않다.

다음의 예에서는 위에서 작성한 것과 같이 ClickExample 클래스를 정의하고 있지만 청취자 함수를 myListenerObj라고 하는 범용 오브젝트의 일부로서 정의하고 있는 점이 다르다.

package {
import flash.display.Sprite;

public class ClickExample extends Sprite {
public function ClickExample() {
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}

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

class ChildSprite extends Sprite {
public function ChildSprite() {
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, myListenerObj.clickHandler);
}
}

var myListenerObj:Object = new Object();
myListenerObj.clickHandler = function (event:MouseEvent):void {
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
trace의 결과는 다음과 같다.

clickHandler detected an event of type: click
the this keyword refers to: [object global]

this 의 참조처는 myListenerObj 인 것 같이 보여 trace 출력도 [object Object]가 되어 있지만 실제의 참조처는 글로벌 오브젝트다. 동적인 프롭퍼티명을 addEventListener() 의 파라미터로서 지정했을 경우 Flash Player는 bound methods를 작성할 수가 없다. 왜냐하면 이 경우에 listener 파라미터로서 건네 받는 것은 청취자 함수의 단순한 memory address이며 Flash Player는 그 memory address와 myListenerObj 인스턴스를 연결시켜주는 수단이 없기 때문이다.

이벤트 청취자의 관리
청취자 함수를 관리하려면 IEventDispatcher 인터페이스의 메소드를 사용한다. IEventDispatcher 인터페이스는 DOM 이벤트 모델에 있어서의 EventTarget 인터페이스의 ActionScript 3.0 버전이다. IEventDispatcher라는 이름에서는 Event 오브젝트를 송신(송출) 하는 것이 주된 목적인 것처럼 생각되지만 실제로는 이벤트 청취자를 등록, 확인, 및 삭제하는 목적으로 메소드를 사용할 기회가 가장 많다고 말할 수 있다. IEventDispatcher 인터페이스에는 다음의 코드에 나타난 5 개의 메소드가 정의되어 있다.

package flash.events
{
public interface IEventDispatcher
{
function addEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false,
priority:Integer=0,
useWeakReference:Boolean=false):Boolean;

function removeEventListener(eventName:String,
listener:Object,
useCapture:Boolean=false):Boolean;

function dispatchEvent(eventObject:Event):Boolean;

function hasEventListener(eventName:String):Boolean;
function willTrigger(eventName:String):Boolean;
}
}
Flash Player API는 EventDispatcher 클래스에 IEventDispatcher 인터페이스가 implements 되고 있다. 이 클래스는 이벤트 플로우의 일부나 이벤트 타겟으로서 기능하는 모든 클래스에 대한 기본 클래스다. 예를 들어 DisplayObject 클래스는 EventDispatcher 클래스를 계승하고 있다. 이 때문에  표시 리스트내의 임의의 오브젝트는 IEventDispatcher 인터페이스의 메소드에 액세스 할 수 있다.

이벤트 청취자의 추가
addEventListener()는 IEventDispatcher 인터페이스로 가장 자주 사용되는 메소드다. 청취자 함수를 등록할 때 이 메소드를 사용한다. type 및 listener 의 2 개의 파라미터는 필수다. type 파라미터에서는 이벤트의 타입을 지정한다. listener 파라미터에서는 목적의 이벤트가 발생했을 때에 실행하는 청취자 함수를 지정한다. listener 파라미터에는 함수에의 참조 또는 클래스 메소드의 참조의 어느쪽이든 지정할 수 있다.

addEventListener() 메소드의 useCapture 파라미터를 사용하면 이벤트 플로우의 어느 단계에서 청취자를 액티브하게 하는지를 제어할 수 있다. useCapture에 true를 지정하면 그 청취자는 이벤트 플로우의 캡쳐 단계에서 액티브하게 된다. useCapture 에 false를 지정하면 그 청취자는 이벤트 플로우의 타겟 단계와 bubbling 단계에서 액티브하게 된다. 이벤트 플로우의 모든 단계에 있고 이벤트를 받으려면 useCapture 에 true를 지정했을 경우와 useCapture 에 false를 지정했을 경우의 양쪽 모두에 대해서 2 회 addEventListener()를 호출할 필요가 있다.

addEventListener() 메소드의 priority 파라미터는 DOM Level 3 이벤트 모델의 정식적 파라미터가 아니다. 이것은 이벤트 청취자를 보다 유연하게 편성하도록 ActionScript 3.0에서 독자적으로 제공되고 있는 파라미터이다. addEventListener()를 호출할 때에 priority 파라미터에 정수치를 지정하는 것으로 이벤트 청취자의 우선도를 설정할 수 있다. 디폴트치는 0이지만 부의 정수치 또는 정의 정수치를 지정할 수 있다. 지정한 수치가 높은 만큼 이벤트 청취자가 빠른 순서로 실행된다. 같은 우선도로 등록된 복수의 이벤트 청취자가 있는 경우 그것들은 등록순서에 의해서 먼저 등록한 이벤트 청취자가 빨리 실행된다.

useWeakReference 파라미터를 사용하면 그 청취자 함수에 대한 참조를 통상의 참조로 하는지 약참조로 하는지를 지정할 수 있다. 이 파라미터에 true를 지정하면 청취자 함수가 사용되지 않게 된 이후에도 메모리상에 계속 남는 것을 막을 수 있다. Flash Player는 "가베지 콜렉션"의 테크닉에 의해서 사용되지 않게된 오브젝트를 메모리로부터 삭제한다. 어느 오브젝트에 대해서 참조가 한 개도 존재하지 않을 때는 그 오브젝트는 더 이상 사용되지 않는다고 판단하여 약참조에의하여 참조 밖에 있는 오브젝트는 가베지 콜렉션의 대상이 된다.

이벤트 청취자의 삭제
불필요하게 된 이벤트 청취자를 삭제하려면 removeEventListener() 메소드를 사용한다. 불필요하게 된 청취자는 삭제하는 것을 추천한다. 필수의 파라미터는 eventName 및 listener의 2 개로 addEventListener() 메소드의 필수 파라미터와 같다. 위에서 이야기 했던 것과 같이 이벤트 플로우의 모든 단계에 있고 이벤트를 받는 경우는 useCapture 에 true를 지정했을 경우와 false를 지정했을 경우의 양쪽 모두에 대해서 2 회 addEventListener()를 호출한다. 그리고 양쪽 모두의 이벤트 청취자를 삭제하려면 useCapture 에 true를 지정했을 경우와 false를 지정했을 경우의 양쪽 모두에 대해 2 회 removeEventListener()를 호출할 필요가 있다.

이벤트의 송출
dispatchEvent() 메소드는 독자적인 이벤트 오브젝트를 이벤트 플로우에 송출하는 경우에 사용하는 상급 개발자 전용의 메소드다. 이 메소드로 지정할 수 있는 파라미터는 1 개로 Event 클래스 또는 그 서브 클래스의 인스턴스를 지정한다. 송출된 이벤트 오브젝트의 target 프롭퍼티에는 dispatchEvent()로 불려 간 오브젝트가 설정된다.

기존의 이벤트 청취자의 확인
IEventDispatcher 인터페이스가 갖추는 나머지 2 개의 메소드는 이벤트 청취자의 존재에 관한 유용한 정보를 취득하기 위해서 사용한다. 지정한 표시 리스트 오브젝트에 지정한 이벤트 타입의 이벤트 청취자가 등록되어 있는 경우 hasEventListener() 메소드는 true를 돌려준다. willTrigger() 메소드도 지정한 표시 리스트 오브젝트에 청취자가 등록되어 있는 경우에 true를 돌려주지만 willTrigger()은 지정한 표시 오브젝트 자체를 확인할 뿐만 아니라 이벤트 플로우의 모든 단계에 있어서의 그 표시 리스트 오브젝트의 조상도 모두 확인할 수 있다.

에러 이벤트의 청취자를 등록하지 않는 경우
에러 처리에 관해서 ActionScript 3.0에 있어서의 가장 중요한 메카니즘은 이벤트가 아니라 예외지만 비동기의 조작 (파일의 로드 등)에는 예외 처리를 사용할 수 없다. 비동기의 조작을 실행중에 에러가 발생하면 Flash Player 에 의해 에러 이벤트 오브젝트가 송출된다. 에러 이벤트에 대한 청취자를 작성하지 않은 경우 디버그판의 Flash Player는 발생한 에러에 관한 정보가 다이알로그 박스에 표시된다. 예를 들어, 파일의 로드 처리에 대해 무효인 URL를 지정하면 standalone의 디버그판 Flash Player에서 에러를 나타내는 다이알로그 박스가 표시된다.

에러 이벤트의 대부분은 ErrorEvent 클래스에 근거하고 있기 때문에 Flash Player는 이러한 메시지를 표시하기 위해 text라는 프로퍼티가 있다. 다만 StatusEvent 클래스와 NetStatusEvent 클래스의 2 개는 이것에 해당하지 않는다.

이러한 에러 이벤트가 발생해도 그에 따라서 SWF 파일의 실행이 정지하지는 않는다. 단지 디버그판의 브라우저 플러그인 또는 standalone의 Player 다이알로그 박스에 의해서 에러의 정보가 나타날 뿐이다.

    

설정

트랙백

댓글

[AS3] 이벤트 오브젝트

Programming/ActionScript 3.0 2007. 6. 16. 23:10
ActionScript 3.0의 새로운 이벤트 처리 시스템에 있는 이벤트 오브젝트는 2 개의 용도로 사용된다. 하나는 구체적인 개개의 이벤트를 표현해 해당 이벤트에 관한 정보를 각종 프롭퍼티에 적용하는 것이고 다른 하나는 각종 메소드를 사용하여 이벤트 오브젝트를 조작해 이벤트 처리 시스템의 동작을 변화시키는 것이다.

그러한 프롭퍼티와 메소드에 액세스 하기 쉽게 Flash Player API 에 있는 모든 오브젝트는 이벤트 오브젝트가 기본 클래스로 정의되어 있다. Event 클래스는 모든 이벤트 오브젝트에 공통되는 기본적인 프롭퍼티와 메소드를 갖추고 있다.

우선 Event 클래스의 프롭퍼티와 Event 클래스의 메소드에 대해 설명하고 마지막으로 Event 클래스에 서브 클래스가 존재하는 이유에 대해 알아보면 다음과 같다.

Event 클래스의 프롭퍼티
Event 클래스에는 이벤트 오브젝트에 관한 중요한 정보를 제공하는 다수의 읽기전용 프롭퍼티와 정수가 있다. 다음의 프롭퍼티는 특히 중요하다.

이벤트 오브젝트의 타입은 정수에 의해서 나타내져 Event.type 프롭퍼티에 적용된다.
이벤트의 디폴트 동작을 캔슬할 수 있을지 없을지를 Boolean 값에 의해서 나타내져 Event.cancelable 프롭퍼티에 넣게 된다.

디폴트 동작
이벤트에 응답하는 코드는 개발자가 기술하지 않으면 안 되는 것이 대부분이지만 이벤트에 대해서 어떠한 정해진 동작이 명확한 경우에는 일반적인 처리가 Flash Player에 의해서 자동적으로 실행되는 것들이 있다. (개발자가 이 동작을 캔슬하기 위한 코드를 기술했을 경우를 제외한다). Flash Player 에 의해서 자동적으로 실행되는 동작을 디폴트 동작이라고 부른다.

예를 들어, 유저에 의해서 TextField 오브젝트에 텍스트가 입력되었을 때 대부분의 경우는 입력된 텍스트를 그 TextField 오브젝트에 표시할 필요가 있다. 이것은 매우 일반적인 동작이므로 Flash Player 에 이미 정해진 동작이다. 이 동작이 불필요한 경우는 새로운 이벤트 처리 시스템을 사용해 디폴트 동작을 캔슬할 수 있다. 유저에 의해서 TextField 오브젝트에 텍스트가 입력되면 그 입력을 나타내는 행동은 TextEvent 클래스의 인스턴스가 Flash Player에 의해서 작성된다. 입력 텍스트가 Flash Player에 의해서 TextField 오브젝트내에 표시되는 것을 막으려면 그 특정의 TextEvent 인스턴스에 액세스하여 preventDefault() 메소드를 호출하여 처리할 수 있다..

디폴트 동작안에는 캔슬할 수 없는 것도 있다. 예를 들어, 유저에 의해서 TextField 오브젝트내의 단어가 더블 클릭 되면 Flash Player로부터 MouseEvent 오브젝트를 생성하게 된다. 이 경우의 디폴트 동작인 커서 위치에 있는 단어를 하이라이트 하는 처리는 개발자가 임의로 막을 수 없다.

디폴트 동작은 Flash Player로부터 송출되는 이벤트 오브젝트밖에 관련지을 수 없기 때문에ActionScript 의 프로그램으로 송출한 이벤트 오브젝트에 대해서는 실행되지 않는다. 이 점을 이해해 두는 것은 중요한데 예를 들어, EventDispatcher 클래스의 메소드를 사용해 textInput 타입의 이벤트 오브젝트를 송출할 수 있지만 그 경우는 이벤트 오브젝트에 디폴트 동작을 관련지을 수 없다. 따라서 프로그램으로부터 textInput 이벤트를 송출해도 그 결과를 Flash Player 에 의해서 TextField 오브젝트에 문자로 표시될 수는 없다.

이벤트 오브젝트의 타입
모든 이벤트 오브젝트에는 각각 이벤트 타입이 설정된다. 이벤트 타입은 스트링으로서 Event.type 프롭퍼티에 포함된다. 코드로 이벤트 오브젝트의 타입을 알 수 있으면 타입에 따라 오브젝트의 처리 방법을 구별할 수 있어 편리다. 예를 들어, 다음의 코드에서는 myDisplayObject 에게 건네지는 마우스 클릭의 이벤트 오브젝트 모두에 대해서 clickHandler() 청취자 함수가 응답하도록 지정하고 있다.

myDisplayObject.addEventListener(MouseEvent.CLICK, clickHandler);
Event 클래스 자체에 관련된 이벤트 타입의 수는 20 종류를 넘는다. Event 클래스 정의로부터 발췌한 일부 코드는 다음과 같다.

package flash.events
{
public class Event
{
// 클래스 정수
public static const ACTIVATE:String = "activate";
public static const ADDED:String = "added";
// 그 외의 정수는 생략
}
}
이러한 정수를 사용하면 특정의 이벤트 타입을 간단하게 참조할 수 있다. 각 정수가 나타내는 스트링을 직접 사용하는 것은 피하고 정수명으로 참조하는 것이 좋다. 코드에 입력한 정수명에 스펠링 미스가 있었을 경우는 컴파일러에 의해서 검출할 수 있으나 스트링의 값에 스펠링 미스가 있었을 경우는 컴파일시의 에러가 되지 않고 실행시에 예기치 않은 동작이 생겨서 곤란한 디버그 작업이 필요할 가능성이 있다. 예를 들어, 이벤트 청취자를 등록할 때는 다음과 같은 코드를 사용하는 것이 좋다.

myDisplayObject.addEventListener(MouseEvent.CLICK, clickHandler);
다음의 코드는 추천하지 않는 방법이다.

myDisplayObject.addEventListener("click", clickHandler);

디폴트 동작의 캔슬
코드로 cancelable 프롭퍼티를 조사하면 특정의 이벤트 오브젝트에 대한 디폴트 동작을 캔슬할 수 있을지를 알 수 있다. cancelable 프롭퍼티의 값은 Boolean 형태로 디폴트 동작에 대한 캔슬 가부를 나타낸다. 디폴트 동작의 캔슬이 가능한 이벤트는 소수이지만 해당하는 경우는 관련된 동작을 preventDefault() 메소드로 무효화할 수 있다.

이벤트 플로우 정보
Event 클래스의 다른 프롭퍼티에는 다음에 나타내는 것과 같이 이벤트 오브젝트 자체나 이벤트 플로우와의 관계에 관한 중요한 정보가 포함되어 있다.

bubbles : 그 이벤트 오브젝트의 전달 경로가 되는 이벤트 플로우의 구성요소에 관한 정보를 포함한다.
eventPhase  : 이벤트 플로우가 현재 어느 단계에 있는지를 나타낸다.
target : 이벤트 타겟의 참조.
currentTarget  : 해당 이벤트 오브젝트를 현재 처리하고 있는 표시 리스트 오브젝트의 참조.

bubbles 프롭퍼티
이벤트 오브젝트가 bubbling 단계에 있을 때(플로우의 역순으로 전달되는 상태)  그 오브젝트에 의해서 나타내지는 이벤트는 타겟 노드로부터 스테이지로 계층의 상위를 향해 돌아오는 도중에 있다. Event.bubbles 프롭퍼티에는 그 이벤트 오브젝트가 bubbling 단계를 경유할지를 나타낸다. Bubbling의 대상이 되는 이벤트는 반드시 캡쳐 단계와 타겟 단계의 대상이므로 이벤트 플로우의 3 단계 모두를 거치게 된다.이 프롭퍼티의 값이 true 의 경우 해당 이벤트 오브젝트는 3 개의 단계를 모두 경유한 것이고 값이 false 의 경우 해당 이벤트 오브젝트는 bubbling 단계를 경유하지 않은 것이다.

eventPhase 프롭퍼티
eventPhase 프롭퍼티를 조사하면 그 이벤트 오브젝트가 이벤트의 어느 단계에 있는지를 알수 있다. eventPhase 프롭퍼티에는 이벤트 플로우의 3 개의 단계 어느 쪽이든 나타내는 부호없는 정수치가 적용된다. 다음에 나타내는 코드의 발췌처럼 Flash Player API 에는 그러한 부호없는 정수치에 대응한다.  EventPhase 클래스는 flash.events 패키지에서 별도로 정의되어 있다.

package flash.events
{
public final class EventPhase
{
public static const CAPTURING_PHASE:uint = 1;
public static const AT_TARGET:uint = 2;
public static const BUBBLING_PHASE:uint = 3;
}
}
이러한 정수는 eventPhase 프롭퍼티에 대해 유효한 3 개의 값에 대응한다. 정수를 사용하면 코드의 읽기가 쉬워진다. 예를 들어, 이벤트 오브젝트가 타겟 단계에 있는 경우만 myFunc()라는 함수를 호출하도록 하려면 다음과 같은 코드로 조건을 판단할 수 있다.

if (e.eventPhase == EventPhase.AT_TARGET) {
myFunc();
}
target 프롭퍼티
target 프롭퍼티에는 해당 이벤트의 타겟인 오브젝트에 의해 참조가 적용된다. 타겟의 취급은 단순한 경우와 그렇지 않은 경우가 있다. 예를 들어, 마이크가 액티브하게 된 것을 나타내는 이벤트에서는 이벤트 오브젝트의 타겟은 Microphone 오브젝트인 것이 명확하지만 타겟이 표시 리스트내에 있는 경우는 표시 리스트의 계층 구조를 고려할 필요가 있다. 예를 들어, 복수의 표시 리스트 오브젝트가 서로 겹치는 지점이 유저에 의해서 마우스로 클릭되었을 경우 Flash Player는 스테이지로부터 가장 먼 계층에 있는 오브젝트가 이벤트 타겟으로서 선택된다. 그 형태는 다음과 같은 코드로 설명될 수 있다.

parent_mc.child_mc.addEventListener(MouseEvent.CLICK, childClickHandler);
parent_mc.addEventListener(MouseEvent.CLICK, parentClickHandler);

parent_mc.child_mc.buttonMode = parent_mc.buttonMode = true;

function childClickHandler(evt:Event):void{
trace(evt.target.name +" is a child");
}
function parentClickHandler(evt:Event):void{
trace(evt.target.name +" is a parent");
}

출력 :
child_mc is a child
child_mc is a parent

복잡한 SWF 파일에서는 target 프롭퍼티가 잘 기능하지 않는 것이 있다. 각 버튼에 대해서 오브젝트를 사용한 정형적인 수식 처리가 이루어지고 있는 경우는 target 프롭퍼티의 참조처가 버튼이 아니고 수식용의 오브젝트가 되어 버리는 상황이 발생할 수 있다. 이러한 상황에서는 버튼에 이벤트 청취자를 등록해 currentTarget 프롭퍼티를 사용하는 것이 일반적이다. 그렇게 하면 target 프롭퍼티가 상위 오브젝트를 참조하는 경우에도 currentTarget 프롭퍼티로 버튼을 참조할 수 있다.

currentTarget 프롭퍼티
currentTarget 프롭퍼티에는 해당 이벤트 오브젝트를 현재 처리하고 있는 표시 리스트 오브젝트로 참조할 수 있다. 조사하는 대상의 이벤트 오브젝트가 현재 어느 노드로 처리되고 있을지가 사전에 모른다는, 어떻게 보면 이상한 상황같이 들리지만 실제는 자주 일어나는 일이다. 왜냐하면 해당 이벤트 오브젝트의 이벤트 플로우에 포함되는 임의의 표시 오브젝트에 청취자 함수가 등록되어 있을 가능성이 있고 청취자 함수 자체가 임의의 장소에 배치될 가능성이 있기 때문이다. 게다가 1 depths 청취자 함수가 복수의 표시 오브젝트에 등록되어 있는 경우도 있을 수 있다. 프로젝트의 규모가 커져 복잡한 상황에 따라서 currentTarget 프롭퍼티의 유용성은 매우 높아진다.

parent_mc.child_mc.addEventListener(MouseEvent.CLICK, childClickHandler);
parent_mc.addEventListener(MouseEvent.CLICK, parentClickHandler);

parent_mc.child_mc.buttonMode = parent_mc.buttonMode = true;

function childClickHandler(evt:Event):void{
trace(evt.currentTarget.name +" is a child");
}
function parentClickHandler(evt:Event):void{
trace(evt.currentTarget.name +" is a parent");
}

출력 :
child_mc is a child
parent_mc is a parent



Event 클래스의 메소드
Event 클래스의 메소드는 다음의 3 종류로 구별할 수 있다.

유틸리티 메소드 : 이벤트 오브젝트의 카피를 작성하거나 스트링으로 변환한다.
이벤트 플로우 메소드 : 이벤트 오브젝트를 이벤트 플로우로부터 삭제한다.
디폴트 동작 메소드 : 디폴트 동작을 취소하거나 취소가 끝난 상태인지 어떤지를 확인한다.
 

Event 클래스의 유틸리티 메소드
Event 클래스에는 2 개의 유틸리티 메소드가 있다. clone() 메소드는 이벤트 오브젝트의 카피를 작성한다. toString() 메소드는 이벤트 오브젝트의 각종 프롭퍼티와 그러한 값을 나타내는 스트링을 생성한다. 어느 메소드도 이벤트 모델 시스템의 내부에서 사용되고 있는 것이지만 어플리케이션 개발자에게도 일반 용도 전용으로 공개되고 있다.

상급 개발자가 Event 클래스의 서브 클래스를 작성하는 경우에는 이벤트 서브 클래스를 정상적으로 기능시키기 위해서 양쪽 모두의 유틸리티 메소드를 오버라이드(override)하여 독자적인 버젼을 만들 필요가 있다.

Event 클래스의 이벤트 플로우 메소드

이벤트 오브젝트가 이벤트 플로우로 처리되는 것을 정지하려면 Event.stopPropogation() 메소드 또는 Event.stopImmediatePropogation() 메소드를 호출한다. 이것들 2 개의 메소드는 거의 같지만 현재의 노드에 등록되어 있는 나머지의 이벤트 청취자에 대해 실행을 허가할지 하지 않을지라는  점만이 다르다.

Event.stopPropogation() 메소드를 호출하면 해당 이벤트 오브젝트가 이벤트 플로우로 다음의 노드에 전달되는 것을 막을 수 있지만 현재의 노드에 등록되어 있는 이벤트 청취자는 모두 실행된다.
Event.stopImmediatePropogation() 메소드를 호출하면 해당 이벤트 오브젝트가 이벤트 플로우로 다음의 노드에 전달되는 것을 막아, 현재의 노드에 등록되어 있는 다른 이벤트 청취자의 실행도 막을 수 있다.
어느 메소드를 호출했을 경우도 이벤트에 관련되는 디폴트 동작이 실행할지 안할지에 영향을 주지 않는다. 디폴트 동작을 캔슬하려면 Event 클래스의 디폴트 동작 메소드를 별도로 사용할 필요가 있다.

Event 클래스의 디폴트 동작 메소드
디폴트 동작의 취소에 관해서는 preventDefault() 메소드와 isDefaultPrevented() 메소드의 2 개가 있다. preventDefault() 메소드를 사용하면 이벤트에 관련지을 수 있었던 디폴트 동작을 캔슬할 수 있다. 이미 preventDefault()를 호출했는지를 확인하려면 isDefaultPrevented() 메소드를 사용한다.호출이 끝난 경우는 반환값으로서 true를 보내고 아직 호출하지 않은 경우는 false를 돌려준다.

preventDefault() 메소드는 디폴트 동작의 캔슬이 가능한 이벤트에 대해서만 사용할 수 있다. 캔슬의 가부에 대해서는 API 문서로 해당하는 이벤트 타입의 항목을 참조하거나 ActionScript로 해당 이벤트 오브젝트의 cancelable 프롭퍼티를 확인해야 한다.

디폴트 동작을 캔슬해도 이벤트 플로우에 의한 이벤트 오브젝트 처리의 진행에는 영향을 주지 않는다. 이벤트 오브젝트를 이벤트 플로우로부터 없애려면 이벤트 플로우 메소드를 사용할 필요가 있다.

Event 클래스의 서브 클래스

많은 이벤트는 Event 클래스에 정의되고 있는 공통의 프롭퍼티 세트를 사용하면 충분히 표현할 수 있지만 Event 클래스의 프롭퍼티에서는 표현할 수 없는 독특한 성질을 가진 이벤트도 있다. 그러한 이벤트를 위해서 Flash Player API 에는 Event 클래스의 서브 클래스가 몇 개 정의되어 있다.

각 서브 클래스에는 그 이벤트의 카테고리에 특유의 프롭퍼티 및 이벤트 타입이 추가되어 있다. .예를 들어, 마우스의 입력에 관한 이벤트에는 Event 클래스에서 표현할 수 없는 독특한 성질이 있다. MouseEvent 클래스는 Event 클래스를 확장하여 마우스 이벤트의 발생 위치나 발생시에 특정의 키가 밀리고 있었는지등의 정보를 수반하는 프롭퍼티를 추가한 것이다.

또, Event 의 서브 클래스에는 해당 서브 클래스에 이벤트 타입을 나타내는 정수가 포함된다. 예를 들어 MouseEvent 클래스의 경우 마우스 관련의 이벤트 타입이다 click ,doubleClick ,mouseDown ,mouseUp 을 나타내는 정수가 각각 정의되어 있다.

    

설정

트랙백

댓글

[AS3] Flash Player 9 API 의 개요

Programming/ActionScript 3.0 2007. 6. 16. 17:24
ActionScript 3.0 의 Flash Player API 에는 오브젝트와 데이터를 낮은 레벨로 제어할 수 있는 다수의 새로운 클래스가 추가되었다. ActionScript 3.0 의 아키텍쳐는 기존의 ActionScript와는 달리 완전히 새롭고 보다 직관적이다. 예를 들어, Flash Player 9 API는 다음의 논리 패키지로 구성되어 있다. flash.display 패키지에는 Flash Player 의 비주얼 표시 리스트에 관한 모든 클래스가 포함되고 flash.media 패키지에는 오디오와 비디오를 처리하기 위한 클래스가 포함된다. 그리고 flash.text 에는 Flash Player 어플리케이션으로 텍스트를 처리하기 위한 클래스를 포함한다.

다음은 일반적으로 사용되는 클래스와 함수에 대해 각 패키지의 개요를 간단하게 보여준다.


flash.accessibility 패키지
flash.accessibility 패키지에는 Flash 컨텐츠 및 어플리케이션의 accessibility를 서포트하기 위한 클래스가 포함된다. Accessibility 클래스는 스크린 리더와의 통신을 관리한다. AccessibilityProperties 클래스를 사용하면 스크린 리더나 그 외의 accessibility 보조의 Flash 오브젝트의 제시 방법을 제어할 수 있다.

flash.display 패키지
flash.display 패키지에는 Flash Player에 의한 표시 리스트의 오브젝트를 제어하기 위해서 사용하는 코어 클래스가 포함되어 있다. Flash Player 어플리케이션의 모든 비주얼 엘리먼트가 포함된다.
ActionScript 2.0에서는 대부분의 비주얼 엘리먼트가 MovieClip 클래스에서 제어되어 Flash Player 에 의해서 내부에서 처리되고 있었다. 이 때문에 오브젝트의 저레벨 제어는 불가능했다. 하지만 ActionScript 3.0에서는 비주얼 엘리먼트를 제어할 수 있어서 기능과 사용 방법이 기존의 ActionScript보다 논리적으로 정의되고 있다. flash.display 패키지에는 다음의 클래스가 포함된다.
DisplayObject 클래스로부터 계승하는 기본적인 요소 DisplayObjectContainer ,Sprite 등 MovieClip 도 기본적인 요소이며 타임 라인을 필요로 하는 오브젝트에 사용한다. 다양한 버튼 상태를 나타내는 프롭퍼티 등, 버튼에 고유의 기능이 포함된 SimpleButton 클래스도 포함된다.

flash.errors 패키지
flash.errors 패키지에는 IOError (입출력 에러) , IllegalOperationError 등, Flash Player에 고유의 기능에 관련하는 에러 클래스가 포함된다. ActionScript 3.0에서 예외가 런타임 에러를 보고하는 주요한 메카니즘이다.

flash.events 패키지
flash.events 패키지에서는 새롭게 XML DOM (문서 오브젝트 모델) 이벤트 모델이 서포트되어EventDispatcher 기본 클래스가 포함된다. 이벤트에는 에러 이벤트도 포함되는데 에러 이벤트는 Loader.load() 메소드의 호출 등, 비동기 처리로 에러가 발생했을 때에 사용된다.

flash.external 패키지
flash.external 패키지에는 Flash Player8 그리고 fscommand() 함수를 대신하여 도입되었다. flash.external 패키지에는 ExternalInterface 클래스만이 포함된다. ExternalInterface 에 의해서 ActionScript와 Flash Player 컨테이너와의 통신이 가능하다.

flash.filters 패키지
flash.filters 패키지에는 Flash Player 8에서 도입된 비트맵 필터 효과의 클래스가 포함된다. 필터를 사용하면 풍부한 시각 효과를 표시 오브젝트에 적용할 수 있다. flash.filters 패키지의 클래스는 BevelFilter ,BlurFilter ,DisplacementMapFilter ,GlowFilter ,GradientBevelFilter , 및 GradientGlowFilter이다. 이 패키지에는 개별의 픽셀에 매트릭스를 적용하는 것으로 보다 복잡하고 광범위한 효과를 줄 수 있는 클래스가 포함되어 있다. 그것이 ColorMatrixFilter와 ConvolutionFilter이다.
 
flash.geom 패키지
flash.geom 패키지에는 Bitmap 클래스와 표시 오브젝트의 비트맵 캐쉬 프롭퍼티를 서포트한다. Point ,Rectangle ,Matrix 등의 geometry가 포함된다. 또, 칼라를 조작할 수 있는 Transform 및 ColorTransform 클래스도 포함된다.
 
flash.media 패키지
flash.media 패키지에는 클라이언트 컴퓨터로부터 흐르는 오디오 스트림 및 비디오 스트림을 처리하기 위한 클래스가 포함된다. Sound 클래스 및 이 클래스가 서포트하는 클래스를 사용하면 외부의 MP3 파일, 및 SWF 파일에 속한 스트리밍 사운드를 처리할 수 있다. Microphone 클래스를 사용하면 컴퓨터에 접속되고 있는 마이크로폰으로부터 오디오를 캡쳐 할 수 있다. Camera 및 Video 클래스를 사용하면 컴퓨터에 접속되고 있는 비디오 카메라로부터 비디오를 캡쳐 할 수 있다. 또, Video 클래스를 사용하면 외부 FLV 파일을 처리할 수 있다.
 
flash.net 패키지
flash.net 패키지에는 데이터의 송수신을 처리하는 다양한 클래스가 포함된다. Flash Player 9는 바이너리 데이터, XML , 텍스트,URL encode 된 변수, 업 로드 또는 다운로드할 수 있는 기능과 같이 많은 종류의 데이터를 처리할 수 있다. 데이터는 네트워크 서버와 Flash Player를 실행하고 있는 클라이언트 컴퓨터 사이에서 전송 할 수 있다.
이 패키지에는, navigateToURL()이나 sendToURL() 등, 서버와의 커뮤니케이션을 별로 필요로 하지 않는 단순한 조작에 사용할 수 있는 패키지 레벨의 함수도 포함되어 있다.

flash.printing 패키지

이 패키지에는 Flash 컨텐츠를 인쇄하기 위한 클래스가 포함된다.
 
flash.profiler 패키지
이 패키지에는 코드의 디버그에 도움을 주는 showRedrawRegions() 함수가 포함된다.
 
flash.system 패키지
flash.system 패키지에는 시스템 레벨의 기능을 제공하는 클래스와 Flash Player를 실행하고 있는 클라이언트 컴퓨터의 기능에 대해 제한된 특정 정보를 취득할 수 있는 클래스가 포함된다. Capabilities 및 IME 클래스를 사용하고 Flash Player를 실행하고 있는 컴퓨터의 특정의 하드웨어 및 소프트웨어 성능을 판단할 수 있다. 또한 Security ,SecurityDomain ,LoaderContext와 같은 시큐러티에 관련하는 클래스도 포함되어 있다.
flash.system 패키지에는 ApplicationDomain 클래스도 포함된다. 이 클래스를 사용하는 커스텀 클래스를 다른 어플리케이션 도메인에 분할해서 정의를 재이용할 수 있다.

flash.text 패키지
이 패키지에는 텍스트 필드, 텍스트의 포맷, 폰트, 에일리어징 제거, 텍스트의 스타일 시트, 및 레이아웃을 취급하는 클래스가 포함된다.

flash.ui 패키지
flash.ui 패키지에는 유저 인터페이스 (구체적으로 마우스 커서, 컴퓨터 키보드, context menu) 를 커스터마이즈하기 위한 클래스가 포함된다.

flash.utils 패키지
이 패키지에는 ByteArray , 지정한 타임 순서로 코드를 실행할 수 있다. Timer 클래스 등, 다양한 유틸리티 클래스가 포함된다. 또, ActionScript 코드를 실행하는 지연 시간이나 간격을 제어할 수 있는 패키지 레벨의 함수도 다수 포함된다.
 
flash.xml 패키지
flash.xml 패키지는 톱 레벨의 E4X 준거 XML 클래스가 도입되었기 때문에 ActionScript 1.0 및 2.0 XML 오브젝트와 호환성에 문제가 있을 수 있다. XML 관련 클래스는 flash.xml 패키지에 정리되었다.

    

설정

트랙백

댓글

[AS3] XML 처리의 새로운 어프로치

Programming/ActionScript 3.0 2007. 6. 16. 16:09
E4X:XML은 ActionScript 3.0 언어의 코어 기능의 베이스가 되고 있다. ActionScript 의 이전의 버젼 (Flash 5 의 ActionScript 1.0 및 그 이후) 에는 XML 데이터를 취급하는 클래스나 메소드가 있었지만 그것들은 ECMAScript 표준에 근거하는 것이 아니었다.

새롭게 설계된 ECMAScript for XML 사양에는 XML 데이터를 처리하기 위한 새로운 클래스군이나 기능이 정의되고 있다. 그것들은 총칭해 E4X로 불리고 있다. ActionScript 3.0은 E4X에 준거한 클래스로 XML , XMLList  ,QName , 및 Namespace 클래스를 갖추고 있다.

E4X 클래스의 메소드, 프롭퍼티, 연산자에 대한 책정 작업에서는 다음의 특징을 실현하는 것이 목표로 여겨졌다.

ActionScript 2.0 에 존재하고 있던 종래의 XML 클래스는 E4X 사양의 일부인 XML 클래스와 경합 하기 위해 ActionScript 3.0 XMLDocument 클래스명으로 변경되었다. XMLDocument ,XMLNode ,XMLParser ,XMLTag 의 각 클래스는 ActionScript 3.0의 XML을 컨트롤 하기 위해 필요한 새로운 클래스는 코어 클래스이므로 사용 시에 패키지를 읽어들 일 필요가 없다.
 
다음은 E4X를 사용한 데이터 처리의 예를 보여준다.

var myXML:XML =
    <order>
        <item id='1'>
            <menuName>burger</menuName>
            <price>3.95</price>
        </item>
        <item id='2'>
            <menuName>fries</menuName>
            <price>1.45</price>
        </item>
    </order>

XML 데이터는 실제의 어플리케이션에서는 Web 서비스나 RSS 피드등의 외부 소스로부터 로드하는 것이 일반적이지만 여기에서는 예를 단순하게 하기 위해서 XML 데이터를 리터럴로 할당했다.

다음의 코드에 나타내는 대로 E4X 에는 XML 의 프롭퍼티나 속성에의 액세스에 사용하는 닷 (.) 이나 속성 식별용의 접두사 (@) 등과 같이 알기 쉬운 연산자가 준비되어 있다.

trace(myXML.item[0].menuName);      // 출력 : burger
trace(myXML.item.(@id==2).menuName); // 출력 : fries
trace(myXML.item.(menuName=="burger").price); // 출력 : 3.95

XML의 노드에 새로운 노드를 할당하려면 다음과 같이 appendChild() 메소드를 사용한다.

var newItem:XML =
    <item id="3">
        <menuName>medium cola</menuName>
        <price>1.25</price>
    </item>

myXML.appendChild(newItem);
@ 및 . 연산자는 독해 뿐만이 아니라 다음과 같이 데이터의 할당에도 사용할 수 있다.

myXML.item[0].menuName="regular burger";
myXML.item[1].menuName="small fries";
myXML.item[2].menuName="medium cola";

myXML.item.(menuName=="regular burger").@quantity = "2";
myXML.item.(menuName=="small fries").@quantity = "2";
myXML.item.(menuName=="medium cola").@quantity = "2";
다음과 같이 for 루프를 사용하면 XML의 일련의 노드에 대한 반복 처리가 생긴다.

var total:Number = 0;
for each (var property:XML in myXML.item) {
var q:int = Number(property.@quantity);
var p:Number = Number(property.price);
var itemTotal:Number = q * p;
total += itemTotal;
trace(q + " " + property.menuName + " $" + itemTotal.toFixed(2))
}
trace ("Total: $", total.toFixed(2));
출력 :
2 regular burger $7.90
2 small fries $2.90
2 medium cola $2.50
Total: $ 13.30


외부 xml 파일을 로드 할 때

url.xml 파일 내용
<?xml version="1.0" encoding="euc-kr" ?>
<rss>
    <item id="1">
        <title>item 1</title>
        <img>img1</img>
        <target>_self</target>
    </item>
    <item id="2">
        <title>item 2</title>
        <img>img2</img>
        <target>_blank</target>
    </item>
    <item id="3">
        <title>item 3</title>
        <img>img3</img>
        <target>_parent</target>
    </item>
</rss>

var request:URLRequest = new URLRequest("url.xml");
var loader:URLLoader = new URLLoader();
loader.load(request);

loader.addEventListener(Event.COMPLETE, xmlLoaded);

function xmlLoaded(event:Event):void {
var myXML:XML = new XML(loader.data);
trace(myXML.item[0].title);
trace(myXML.item.(@id==2).title);
trace(myXML.item.(title == "item 1").title);
}
출력 :
item 1
item 2
item 1


    

설정

트랙백

댓글

[AS3] 배열의 카피

Programming/ActionScript 3.0 2007. 6. 16. 15:07
Array 클래스에는 배열의 카피를 작성하는 메소드는 준비되어 있지 않다. 배열의 "shallow copy" 는 concat() 또는 slice() 메소드를 파라미터 없이 호출하는 것으로 작성할 수 있다. shallow copy 에서는 오브젝트인 요소가 원래의 배열에 포함되어 있는 경우 카피한 배열내의 요소는 원래의 요소에 포함되고 있는 오브젝트에의 참조가 되어 참조하는 오브젝트는 카피되지 않는다. 따라서 원본 배열과 카피한 배열이 동일한 오브젝트를 참조하게 되어 한쪽으로부터 변경을 하면 이미 다른 한편에도 그 변경이 반영된다.

"deep copy"는 원의 배열내에서 참조되고 있는 오브젝트를 모두 카피하는 것이다. 그 경우 원본의 배열과 카피한 배열이 동일한 오브젝트를 참조하지 않는다. deep copy를 실행하려면 복수행의 코드를 기술할 필요가 있어 보통 특정한 함수를 작성하게 된다.

다음의 예에서는  deep copy를 실행하기 위해 actionscript에서는 clone() 함수를 정의하고 있다.아래 사용한 알고리즘은 Java 프로그래밍에서 일반적으로 사용되고 있는 방법이다. 우선 원래의 배열을 직렬화해서 ByteArray 클래스의 인스턴스를 작성하고 그것을 새로운 배열에 읽어들이는 것으로 카피를 실행하고 있다. 코드에 나타나고 있는 대로 이 함수는 오브젝트를 받아들이기 위해 인덱스 배열과 결합 배열의 양쪽 모두를 사용하고 있다.

import flash.utils.ByteArray;

function clone(source:Object):*{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}


    

설정

트랙백

댓글

[AS3] 타이머 간격의 제어

Programming/ActionScript 3.0 2007. 6. 16. 12:00
Flash authoring tool에 의한 어플리케이션 개발의 경우는 타임 라인을 사용해 어플리케이션의 진행을 프레임 단위로 확실히 제어할 수 있지만 ActionScript 만을 사용하는 프로젝트의 경우는 다른 타이밍 제어 메카니즘을 사용할 필요가 있다.

루프와 타이머의 차이
프로그램 언어에 따라서는 for문이나 do..while 등의 루프 스테이트먼트를 사용해 타이밍의 제어 방법을 독자적으로 궁리해야 하는 것이 있다.

일반적으로 루프 스테이트먼트는 동작환경이 되는 로컬 머신의 처리 속도에 따라 가능한 한 고속으로 실행되기 때문에 사용하는 시스템에 의해서 속도에 차이가 생긴다. 어플리케이션을 일정한 타이밍에 동작시키려면 어떠한 캘린더나 클럭에 의해서 생성되는 타이밍을 이용할 필요가 있다.게임, 애니메이션, 및 리얼타임 제어 등, 많은 어플리케이션은 어느 머신으로도 일관해서 이용할 수 있는 안정된 시간 베이스의 타이밍 메카니즘을 필요로 한다.

ActionScript 3.0 의 Timer 클래스에는 이러한 요구를 채우는 강력한 기능이 있다. Timer 클래스에서는 ActionScript 3.0 의 이벤트 모델을 사용해 지정된 시간 간격이 경과할 때 마다 타이머 이벤트를 송출한다.

Timer 클래스
타이밍 제어 기능의 취급에 대해서 ActionScript 3.0은 Timer 클래스 (flash.utils.Timer)라는 새로운 클래스를 통한 방법이 추천 되고 있다. 이 클래스를 사용하면 소정의 시간 간격이 경과할 때마다 이벤트를 송출할 수 있다.

타이머를 시작하려면 우선 Timer 클래스의 신규 인스턴스를 작성하고 그 인스턴스에 대해 타이머 이벤트를 생성하는 빈도 및 생성 종료까지의 송출 회수를 지정한다.

예를 들어, 다음의 코드에서는 1 초 마다의 이벤트 송출을 60 초간 계속하는 타이머 인스턴스를작성한 예다.

var oneMinuteTimer:Timer = new Timer(1000, 60);

타이머로는 소정의 시간 간격이 경과할 때마다 TimerEvent 오브젝트를 송출한다. TimerEvent 오브젝트의 이벤트형은 timer ( 정수 TimerEvent.TIMER 에 의해서 정의된다)이다. TimerEvent 오브젝트에는 표준의 Event 오브젝트와 같은 프롭퍼티가 포함되어 있다.

또 반복의 회수를 유한하게 설정한 타이머로는 마지막 시간 간격에 도달했을 때에 timerComplete 이벤트 ( 정수 TimerEvent.TIMER_COMPLETE 에 의해서 정의된다) 도 송출한다.

아래 짧은 소스를 보면 Timer 클래스의 실제의 동작이 어떻게 이루어 지는지 확인할 수가 있다.
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;

public class ShortTimer extends Sprite {
public function ShortTimer() {
// 5 초의 Timer를 신규 작성한다
var minuteTimer:Timer = new Timer(1000, 5);

// 시간 간격 이벤트 및 완료 이벤트용의 청취자를 지정한다
minuteTimer.addEventListener(TimerEvent.TIMER, onTick);
minuteTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);

// 타이머의 카운트를 시작한다.
minuteTimer.start();
}

public function onTick(evt:TimerEvent):void {
// 현재의 카운트를 표시한다
// 이 이벤트의 target이며 Timer 인스턴스 자체를 나타낸다
trace("tick " + evt.target.currentCount);
}

public function onTimerComplete(evt:Event):void {
trace("Time's Up!");
}
}
}
이 예에서는 ShortTimer 클래스가 작성되었을 때, 1 초 마다의 카운트를 5 초간 계속한다. 일단Timer 인스턴스를 작성하고 이 타이머용의 청취자를 2 개 지정하였다. 1 개는 카운트 각 회의 이벤트를 받는 청취자이고(minuteTimer.addEventListener(TimerEvent.TIMER, onTick);) 다른 하나는  timerComplete 이벤트를 받는 청취자이다.( minuteTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
)

타이머의 카운트를 시작하면 이후는 1 초간격으로 onTick() 메소드가 반복한다.
onTick() 메소드에서는 단지 현재의 카운트를 표시하고 있다. 5 초가 경과하면 onTimerComplete() 메소드가 호출되어 카운트가 종료한 것을 표시하게 된다.

이 샘플을 실행하면  트레이스 윈도우에 1 초 마다 다음의 행이 표시된다.

tick 1
tick 2
tick 3
tick 4
tick 5
Time's Up!


flash.utils 패키지에 포함되는 타이머 제어 함수
ActionScript 3.0 에는 ActionScript 2.0과 같은 타이머 제어 함수가 다수 준비되어 있다. 그것들은 패키지 레벨 함수로서 flash.utils 패키지에 포함되어 있어 ActionScript 2.0 의 경우와 같이 동작한다.

clearInterval(id:uint):void
setInterval() 호출을 취소한다.
 
clearTimeout(id:uint):void
setTimeout() 호출을 취소한다.
 
getTimer():uint
Flash Player가 초기화된 시점으로부터의 경과 밀리 세컨드수를 돌려준다.
 
setInterval(closure:Function, delay:Number, ... arguments):uint
밀리 세컨드 단위로 지정한 간격 마다 함수를 실행한다.
 
setTimeout(closure:Function, delay:Number, ... arguments):uint
밀리 세컨드 단위로 지정한 지연 시간의 경과 후에 지정한 함수를 실행한다.
 

이러한 함수는 이후 ActionScript 호환성을 유지하는 목적으로 ActionScript 3.0 에도 남아 있는 것이다. 앞으로 ActionScript 3.0 어플리케이션으로 사용하는 것에 기존의 호환성을 위해 남아 있는 메소드를 사용하는 것은 추천하지 않는다. 일반적으로 Timer 클래스를 사용하는 편이 효율적이다.

    

설정

트랙백

댓글

[AS3] 비디오의 조작

Programming/ActionScript 3.0 2007. 6. 15. 18:12
Video 클래스는 flash.display 패키지내에 없지만 DisplayObject 클래스의 서브 클래스다. 비디오를 Video 오브젝트에 관련지으려면 attachNetStream() 메소드 또는 attachCamera() 메소드를 사용할 필요가 있다.

다음은 넷스트림을 비디오에 관련 짓고, 비디오를 Sprite 표시 오브젝트 컨테이너에 추가하는 단순한 예를 보여준다.










import flash.display.Sprite;
import flash.net.*;
import flash.media.Video;

public class VideoTest extends Sprite {
private var videoUrl:String = "http://example.com/test.flv";

public function VideoTest() {

var connection:NetConnection = new NetConnection();
connection.connect(null);

var stream:NetStream = new NetStream(connection);
stream.publish(false);

var myVideo:Video = new Video(360, 240);
myVideo.attachNetStream(stream);
stream.play(videoUrl);

addChild(myVideo);
}
}


    

설정

트랙백

댓글