UI&C(User Interface & Communication) Lab을 끝맺음 하며...

Project/UI&C Lab 2007. 6. 22. 12:43
그 동안 ActionScript 2.0으로 UserInterface & Communication Lab(UICLab)을 진행하였던 작업물을 압축파일로 올려놓는다. 평소에 생각하던 아이디어나 기술적인 부분을 테스트 하기 위해 오프라인에서 진행하였으나 이제는 오프라인에서 진행하는 의미가 없어졌고 기술적인 진보를 위하여 이쯤에서 UICLab을 끝맺음 하고 앞으로는 시급한 사항이 아닌 이상은 ActionScript 3.0로 작업을 진행할까 한다.

차기 UICLab은 AS3 공부를 위한 아주 기초적인 것에서부터 시작할 듯 싶다. 오프라인에서 진행을 할지 아니면 블로그의 infinite 메뉴에서 진행할지는 앞으로 생각해 봐야 하겠다.

사용자 삽입 이미지


제작된 결과물에 대한 내용은 압축파일을 풀고 실행파일을 실행하면 왼쪽 메뉴 왼쪽에 중간에 나와있는 버튼을 클릭하면 상세하지는 못하나 결과물에 대한 설명을 볼 수 있다. 버튼 가독성이 떨어져서 버튼의 위치는 위 이미지에 표시해 놓았다.

아무쪼록 플래시를 시작하시는 분들에게 재미있다는 느낌이 전해졌으면 좋겠다...

UIClab.zip



    

설정

트랙백

댓글

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


    

설정

트랙백

댓글

[AS3] SimpleButton 오브젝트의 조작

Programming/ActionScript 3.0 2007. 6. 15. 18:02
ActionScript 3.0에서는 SimpleButton 클래스를 사용해 버튼의 동작을 정의할 수 있다. SimpleButton에는 다음의 3 개 상태가 있다.
upState
downState
overState

이것들은 SimpleButton 오브젝트의 프롭퍼티로 각각 DisplayObject 오브젝트이다. 예를 들어, 다음의 클래스는 단순한 텍스트 버튼을 정의한다.







import flash.display.*;
import flash.events.*;
public class TextButton extends SimpleButton {
public var selected:Boolean = false;
public function TextButton(txt:String) {
upState = new TextButtonState(0xFFFFFF, txt);
downState = new TextButtonState(0xCCCCCC, txt);
hitTestState = upState;
overState = upState;
addEventListener(MouseEvent.CLICK, buttonClicked);
}
public function buttonClicked(e:Event) {
trace("Button clicked.");
}
}
SimpleButton 오브젝트의 hitTestState 프롭퍼티는 버튼의 마우스 이벤트에 응답하는 DisplayObject 인스턴스다. 이 예의 TextButton 클래스는 버튼 상태 ( 업, 다운, 또는 오버) 에 사용한다. DisplayObject를 정의하는 다음의 클래스를 참조.

import flash.display.*;
import flash.text.TextFormat;
import flash.text.TextField;
class TextButtonState extends Sprite {
public var label:TextField;
public function TextButtonState(color:uint, labelText:String) {
label = new TextField();
label.text = labelText;
label.x = 2;
var format:TextFormat = new TextFormat("Verdana");
label.setTextFormat(format);
var buttonWidth:Number = label.textWidth + 10;
var background:Shape = new Shape();
background.graphics.beginFill(color);
background.graphics.lineStyle(1, 0x000000);
background.graphics.drawRoundRect(0, 0, buttonWidth, 18, 4);
addChild(background);
addChild(label);
}
}

    

설정

트랙백

댓글

[AS3] 비트 맵의 작성과 조작

Programming/ActionScript 3.0 2007. 6. 15. 17:54
BitmapData 클래스를 사용하면 Bitmap 오브젝트의 픽셀을 조작할 수 있다. 조작할 수 있는 것은 파일로부터 로드한 비트 맵이나 BitmapData의 메소드로 만든 비트맵이다. Bitmap 오브젝트에는 BitmapData에서 사용할 수 있는 bitmapData 프롭퍼티가 있다.

BitmapData 오브젝트는 픽셀의 구형 배열을 나타낸다. 새로운 비트맵을 프로그램 처리에 의해서 작성할 수 있다. 다음의 예는 BitmapData constructor을 사용하여 지정한 색으로 구형을 작성할 수 있고 그 BitmapData 오브젝트를 새로운 Bitmap 오브젝트에 할당할 수 있는 것을 보여준다.






var bdWidth:Number = 100;
var bdHeight:Number = 100;
var bdTransparent:Boolean = true;
var bdFillColorARGB:uint = 0xFF007090;
var myBitmapData:BitmapData = new BitmapData(bdWidth,
bdHeight,
bdTransparent,
bdFillColorARGB);
var myBitmap:Bitmap = new Bitmap(myBitmapData);
addChild(myBitmap);


그러나 통상은 로드된 이미지 파일의 비트맵 데이터를 조작하기 위해 사용된다. 어느 경우도BitmapData 클래스에는 BitmapData를 조작해 변경하기 위한 메소드가 포함된다. 예를 들어, setPixel() 메소드를 사용하여 픽셀의 특정의 RGB 값으로 설정할 수 있다.

    

설정

트랙백

댓글

[AS3] 컨텐츠의 동적 로드 - Loader 클래스

Programming/ActionScript 3.0 2007. 6. 15. 17:30
Loader 클래스

Loader 오브젝트를 사용하여 어플리케이션에 SWF 파일 및 그래픽 파일을 로드 할 수 있다. Loader 클래스는 DisplayObjectContainer 클래스의 서브 클래스이므로 Loader 오브젝트에는 표시 리스트 표시 오브젝트를 사용할 수 있다. SWF 파일 또는 그래픽 파일을 나타내는 표시 오브젝트는 Loader로 작성된 인스턴스 1개당 1 개만 포함할 수 있다. 표시 리스트에 Loader 오브젝트를 추가할 때는 다음의 코드와 같이 표시 오브젝트의 로드가 완료하면 로드 된 표시 오브젝트도 표시 리스트에 추가해야 화면에서 확인이 가능하다







var pictLdr:Loader = new Loader();
var pictURL:String = "banana.jpg"
var pictURLReq:URLRequest = new URLRequest(pictURL);
pictLdr.load(pictURLReq);
this.addChild(pictLdr);
SWF 파일 또는 이미지가 로드 되면 로드 된 표시 오브젝트를 아래 코드처럼 container DisplayObjectContainer 오브젝트등의 다른 표시 오브젝트 컨테이너로 이동할 수 있다

import flash.display.*;
import flash.net.URLRequest;
import flash.events.Event;
var container:Sprite = new Sprite();
addChild(container);
var pictLdr:Loader = new Loader();
var pictURL:String = "banana.jpg"
var pictURLReq:URLRequest = new URLRequest(pictURL);
pictLdr.load(pictURLReq);
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
function imgLoaded(e:Event):void {
container.addChild(pictLdr.content);
}
LoaderInfo 클래스

파일이 로드 되면 LoaderInfo 오브젝트가 작성된다. 이 오브젝트는 Loader 오브젝트 및 로드 된 표시 오브젝트 양쪽 모두의 프롭퍼티다. 즉, LoaderInfo 오브젝트는 Loader 오브젝트의 contentLoaderInfo 프롭퍼티를 경유하는 Loader 오브젝트의 프롭퍼티이며 또, 표시 오브젝트의 loaderInfo 프롭퍼티도 로드된 표시 오브젝트의 프롭퍼티이다. 로드 된 표시 오브젝트의 loaderInfo 프롭퍼티는 Loader 오브젝트의 contentLoaderInfo 프롭퍼티와 같다. 즉, LoaderInfo 오브젝트는 로드 된 오브젝트와 로드하는 Loader 오브젝트간 ( 로드 되는 측과 로드하는 측) 공유하게 된다.

LoaderInfo 클래스는 로드의 진행 상황 로드하는 측과 로드 되는 측의 URL  미디어의 총바이트수, 미디어의 규격, 높이와 폭등의 정보를 제공한다. LoaderInfo 오브젝트는 로드의 진행 상황을 감시하기 위한 이벤트를 송출한다.

로드 된 컨텐츠의 프롭퍼티에 액세스 하려면 다음의 코드와 같이 LoaderInfo 오브젝트에 이벤트 청취자를 추가해야 한다.

import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;

var ldr:Loader = new Loader();
var urlReq:URLRequest = new URLRequest("eventDispatcher.swf");
ldr.load(urlReq);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
addChild(ldr);

function loaded(event:Event):void {
trace("loaded");
}

LoaderContext 클래스

Loader 클래스의 load() 또는 loadBytes() 메소드를 사용해 Flash Player 에 외부 파일을 로드하는 경우, context 파라미터를 지정할 수도 있다. 이 파라미터는 LoaderContext 오브젝트이다.

LoaderContext 클래스에는 로드 된 컨텐츠의 사용 방법의 문맥을 정의할 수 있는 다음과 같은 프롭퍼티가 포함되어 있다.

checkPolicyFile-- 이미지 파일을 로드하는 경우에게만 이 프롭퍼티를 사용한다. 이 프롭퍼티를 true로 설정하면 Loader 에 의해서 오리지날 서버로 크로스 도메인 폴리시 파일의 유무가 체크된다.  이것은 Loader 오브젝트를 포함하는 SWF가 있는 도메인 이외의 다른 도메인에 있는 컨텐츠를 로드할 경우에만 사용된다. 서버로부터 Loader 도메인에 액세스 허가가 주어지고 있는 경우라면 Loader 도메인 내의 SWF 파일의 ActionScript는 로드 된 이미지내의 데이터에 액세스 할 수 있다. 즉, BitmapData.draw() 커멘드를 사용하여 로드 된 이미지내의 데이터에 액세스 할 수 있다.
Loader 오브젝트의 도메인 이외의 다른 도메인에 SWF가 있을 경우에 Security.allowDomain()을 호출해 특정의 도메인을 허가할 수가 있다.

securityDomain - SWF 파일을 로드하는 경우에게만 이 프롭퍼티를 사용한다. Loader 오브젝트를 포함한 파일이 있는 도메인 이외의 도메인에 있는 SWF 파일에 대해서 이 프롭퍼티를 지정한다.이 옵션을 지정하면 Flash Player는 크로스 도메인 폴리시 파일이 존재할지를 체크하게 된다. 파일이 존재하는 경우는 크로스 도메인 폴리시 파일로 허가되고 있는 도메인의 SWF 파일은 로드된 SWF 컨텐츠를 크로스 스크립트 할 수 있다. 이 파라미터로서 flash.system.SecurityDomain.currentDomain을 지정할 수 있다.

다음은 다른 도메인으로부터 비트 맵을 로드할 때, 크로스 도메인 폴리시 파일의 유무를 체크하는 예를 나타낸다.

var loaderContext:LoaderContext = new LoaderContext();
loaderContext.checkPolicyFile = true;
var urlReq:URLRequest = new URLRequest("photo11.jpg");
var ldr:Loader = new Loader();
ldr.load(urlReq, loaderContext);
다음은 SWF 파일을 Loader 오브젝트와 같은 시큐러티 샌드 박스에 두기 위해서 다른 도메인으로부터 SWF 파일을 로드할 때 크로스 도메인 폴리시 파일의 유무를 체크하는 예를 나타낸다. 또, 이 코드는 로드된 SWF 파일의 클래스를 Loader 오브젝트와 같은 어플리케이션 도메인에 추가한다.

var loaderContext:LoaderContext = new LoaderContext();
loaderContext.securityDomain = SecurityDomain.currentDomain;
loaderContext.applicationDomain = ApplicationDomain.currentDomain;
var urlReq:URLRequest = new URLRequest("library.swf");
var ldr:Loader = new Loader();
ldr.load(urlReq, loaderContext);
    

설정

트랙백

댓글

[AS3] Bound methods

Programming/ActionScript 3.0 2007. 6. 15. 11:38
ActionScript 3.0는 오브젝트 인스턴스를 자동적으로 기억하는 Bound methods를 제공한다. 이 기능은 이벤트 처리에 도움을 줄 수 있는데 기존의 ActionScript 2.0에서는 Bound methods에 추출원의 오브젝트 인스턴스가 기억되지 않아서 Bound methods가 불려 갔을 때에 예기치 않은 동작이 발생했다. 이를 해결하기 위해서 mx.utils.Delegate 클래스를 사용하는 것이 일반적인 방법이었지만, ActionScript 3.0부터는 불필요한 과정이 되었다.









class ThisTest {
private var num:Number = 3;
function foo () { // 정의된 Bound methods
trace ("foo's this: " + this);
trace ("num: " + num);
}
function bar () {
return foo; // 돌려주는 Bound methods
}
}

var myTest:ThisTest = new ThisTest();
var myFunc:Function = myTest.bar();
trace(this);
myFunc();
출력 :
[object global]
foo's this:[object ThisTest]
num: 3

Bound methods foo() 의 this 참조가 그 직전의 행의 this 참조가 글로벌 오브젝트를 가리키고 있지만 여전히 ThisTest 클래스의 인스턴스를 가리키는 것을 나타내고 있다. 게다가 myFunc 변수에 속하고 있는 Bound methods는 계속 ThisTest 클래스의 멤버 변수에 액세스 할 수 있다. 이 같은 코드를 ActionScript 2.0에서 실행하면 this 참조가 일치하기 때문에 num 변수는 undefined 가 된다.

    

설정

트랙백

댓글

[AS3] 파일 내에 복수 클래스

Programming/ActionScript 3.0 2007. 6. 15. 04:11
ActionScript 2.0에서는 클래스 파일을 작성하는 경우 클래스와 같은 이름의 파일을 만들게 된다.  예를 들어 Rec이라는 클래스가 있을 때 클래스의 원시 코드는 "Rec.as" 와 같은 파일명으로 저장이 되어야 한다. "Rec.as" 파일에 존재할 수 있는 클래스는 Rec클래스만 가능한 일이었다.

하지만 ActionScript 3.0 에서는 1개의 파일 내에 복수의 클래스를 저장할 수 있도록 설계되었다. Flash 9 alpha 버전에서는 package{} 내에서도 internal class로 여러 개의 클래스가 package내에서 사용가능하도록 하였으나 CS3로 만들면서 이러한 기능은 제외되었다. 하지만 package 외에는 여러개의 클래스를 정의할 수가 있도록 되어 있다. 1 개의 원시 소스 파일에 복수의 클래스를 보존하는 것이 편리할 수도 있지만 남용하면 OOP형태의 언어에서 바람직하지 않은 문제를 양산할 우려가 있다. 문제는 다음과 같은 경우이다.

1.    복수의 클래스가 1 개의 소스파일에 보존되고 있는 경우, 각각의 클래스를 재이용하는 것이 곤란하게 된다.

2.    파일명과 클래스명이 대응하고 있지 않는 경우, 특정의 클래스의 원시 소스코드를 찾아내는 것이 곤란하다.

이러한 문제점으로 인하여 Adobe에서는 각각 하나의 클래스는 하나의 원시소스파일로 저장하는 것을 권장하고 있다. Alpha 버전에서 package 내에서 복수 클래스를 정의할 수 있었던 것을 제외시킨 이유 또한 이러한 문제점 때문일 것이라는 생각이다.

다시 생각해보면 기존 ActionScript 2.0에서 디렉토리 형태로만 패키지 영역을 정의했던 것을 벗어나 package에서 명시적으로 패키지 영역을 정의하고 그 영역 안에서 복수의 클래스를 정의할 수 있도록 하는 방향으로 검토하였으나 위와 같은 두가지 문제로 인하여 언어적 비판을 벗어나기 위해 CS3 제품에서 package 내 복수 클래스 정의 부분을 제외한 것이 아닌가 생각된다. 개념적 접근에서 실의[實義]를 추구했다고 보여진다.

    

설정

트랙백

댓글

[AS3] Object 형의 독립

Programming/ActionScript 3.0 2007. 6. 15. 03:24
ActionScript 2.0에서는 아래의 경우 1번과 2번은 같은 형으로 정의하게 되는데 이는 형을 지정하지 않은 변수의 경우는 Object 형으로 치환되기 때문이었다.

1.    var obj:Object;
2.    var obj;

하지만 ActionScript 3.0에서는 형을 지정되어 있지 않은 변수라고 하는 개념이 도입되었다. 이는 다음의 1, 2번과 같이 2 개의 방법으로 지정할 수 있다.

1.    var obj:*;
2.    var obj;
3.    var obj:Object;

형이 지정되어 있지 않은 1번과 2번은 3번의 Object 형태의 변수와 같지는 않다. 주된 차이는 형이 지정되어 있지 않은 변수는 특별한 값 undefined 를 담을 수 있지만 Object 형태의 변수는 그 값을 보관 유지할 수 없다는 것이다. 오직 null값만이 존재할 수 있다. 이를 다시 말하면 ActionScript 3.0에서는 더 이상 형을 지정하지 않은 변수는 Object형이 아니라는 것이다. 이는ActionScript 2.0보다 형 변환에 따른 엄격한 규칙을 적용하고 있다고 할 수 있겠다.

    

설정

트랙백

댓글

[AS3] Understanding garbage collection in Flash Player 9

Programming/ActionScript 3.0 2007. 6. 13. 11:17

I've been playing around with ActionScript 3.0 for a while now, and I'm really excited by its capabilities. The raw execution speed by itself provides so many possibilities. Toss in E4X, sockets, byte arrays, the new display list model, RegEx methods, a formalized event and error model, and a few dozen other features for flavor, and you have a pretty heady brew.

With great power comes great responsibility, and this is very true for ActionScript 3.0. A side effect of all this new control is that the garbage collector is no longer able to make as many assumptions about what it should automatically tidy up for you. This means that Flash developers moving to ActionScript 3.0 will need to develop a very strong understanding of how the garbage collector operates, and how to work with it effectively. Building even seemingly simple games or applications without this knowledge could result in SWFs that leak like a sieve, hogging all of a system's resources (CPU/RAM) and causing the user's system to hang—potentially even forcing them to hard reboot their computer.

To understand how to optimize your code for ActionScript 3.0, you'll first need an understanding of how the garbage collector works in Flash Player 9. Flash has two processes for finding objects that are not in active use and removing them. This article looks at both techniques and describes how they are relevant to your code.

At the end of this article you can find a simulation of the garbage collector in Flash Player 9 that visually demonstrates the concepts explained herein.

About the garbage collector

The garbage collector is a behind-the-scenes process that is responsible for deallocating the memory used by objects that are no longer in use by the application. An inactive object is one that no longer has any references to it from other active objects. In order to understand this, it is very important to realize that when working with non-primitive types (anything other than Boolean, String, Number, uint, int), you are always passing around a reference to the object, not the object itself. When you delete a variable you remove the reference, not the object itself.

This is easily demonstrated in the code below:

// create a new object, and put a reference to it in a:
var a:Object = {foo:"bar"}
// copy the reference to the object into b:
var b:Object = a;
// delete the reference to the object in a:
delete(a);
// check to see that the object is still referenced by b:
trace(b.foo); // traces "bar", so the object still exists.

If I were to update the code in the example above and delete "b" as well, it would leave my object with no active references and free it for garbage collection. The ActionScript 3.0 garbage collector uses two methods for locating objects with no active references: reference counting and mark sweeping.

Reference counting

Reference counting is one of the simplest methods for keeping track of active objects, and has been used in Flash since ActionScript 1.0. When you create a reference to an object, its reference count is incremented. When you delete a reference, its reference count is decremented. If the reference count of an object reaches zero, it is marked for deletion by the garbage collector.

Here's an example:

var a:Object = {foo:"bar"}
// the object now has a reference count of 1 (a)
var b:Object = a;
// now it has a reference count of 2 (a & b)
delete(a);
// back to 1 (b)
delete(b);
// the reference count down is now 0
// the object can now be deallocated by the garbage collector

Reference counting is simple, it doesn't carry a huge CPU overhead, and it works well in most situations. Unfortunately, the reference counting method for garbage collection is not optimal when it comes to circular referencing. Circular referencing is the situation when objects cross-reference each other (directly, or indirectly via other objects). Even if the application is no longer actively using the objects, their reference counts remain above zero, so the garbage collector never removes them. The code below illustrates how this works:

var a:Object = {}
// create a second object, and reference the first object:
var b:Object = {foo:a};
// make the first object reference the second as well:
a.foo = b;
// delete both active application references:
delete(a);
delete(b);

In the code shown above, both of the active application references have been deleted. I no longer have any way of accessing the two objects from my application, but the reference counts of both objects are 1 because they reference each other. This situation can become much more complex (a references c, which references b, which references a, etc.) and can be difficult to deal with in code. Flash Player 6 and 7 had issues relating to circular referencing in XML objects: each XML node referenced both its children and its parent, so they were never deallocated. Fortunately, Flash Player 8 added a new garbage collection technique called mark and sweep.

Mark sweeping

The second strategy employed by the ActionScript 3.0 (and Flash Player 8) garbage collector to find inactive objects is a method called mark and sweep. Flash Player starts at the root object of your application (which is conveniently called the "root" in ActionScript 3.0) and walks through every reference in it, marking each object it finds.

Next, Flash Player iterates through each of the marked objects. It continues this behavior recursively until it has traversed the entire object tree of your application, marking everything it can reach through an active reference. At the end of this process, Flash Player can safely assume that any objects in memory that are not marked no longer have any active references to them and can be safely deallocated. Figure 1 illustrates how this works: The green references were followed by Flash Player during marking, the green objects are marked, and the white objects will be deallocated.

Objects that no longer have active references are identified by Flash Player using the mark and sweep method

Figure 1. Objects that no longer have active references are identified by Flash Player using the mark and sweep method

Mark and sweep is very accurate. However, because Flash Player has to traverse your entire object structure, the process is costly in terms of CPU usage. Flash Player 9 reduces this cost by carrying out iterative mark and sweep—the process occurs over a number of frames, instead of all at once—and by running this process only occasionally.

Deferred garbage collector and indeterminacy

In Flash Player 9, the garbage collector's operations are deferred. This is a very important thing to understand. Your objects will not be removed immediately when all active references are deleted. Rather, they will be removed at some indeterminate time in the future (from a developer standpoint). The garbage collector uses a set of heuristics that look at the RAM allocation and the size of the memory stack, among other things, to determine when to run. As a developer, you must accept the fact that you will have no way of knowing when, or even if, your inactive objects will get deallocated. You must also be aware that inactive objects will continue to execute indefinitely, until the garbage collector deallocates them, so your code will keep running (enterFrame events will continue), sounds will keep playing, loads will keep happening, other events will keep firing, and so on.

It's very important to remember that you have no control over when the garbage collector in Flash Player will deallocate your objects. As a developer, you will want to make the objects in your games and applications as inert as possible when you are finished with them. Strategies to manage this process will be the focus of my companion article, Resource management strategies in Flash Player 9.

Notice the sawtooth pattern of the total memory in the following garbage collection simulation (click Figure 2 or the link below it). The dips are caused when the collector carries out a sweep. Click on the chart to focus it, then press Spacebar to pause or restart, and hold the up/down arrows to change the memory usage trend as it runs.

Garbage collection simulation

Figure 2. Garbage collection simulation

As shown in the following simulation (click Figure 3 or the link below it), drag out objects (round rectangles) and references to those objects. Then run reference counts or mark and sweep to see which objects would be collected. The number in an object indicates the number of references to that object.

Garbage collection simulation: mark and sweep

Figure 3. Garbage collection simulation: mark and sweep

Where to go from here

Understanding garbage collection is going to be one of the most important steps for writing optimized code that ensures that your Flash project runs with minimal impact on the user's computer. Read my companion article, Resource management strategies in Flash Player 9, and visit the Flash Developer Center and Flash Player Developer Center.

Also check out my blog at gskinner.com to read more about weak references and download helper classes that I've written.

About the author

Grant Skinner is the CEO and chief architect of gskinner.com, a Flash development and consulting company. He works with leading new media agencies and progressive corporate clients to create cutting-edge applications, games, and multimedia pieces. His expertise in fusing coding with interface design, usability, marketing, and business logic has garnered him international acclaim and resulted in a number of prestigious industry awards, including Best Canadian Developer at FITC 2005. Grant maintains an active blog at gskinner.com/blog/ and an exhibit of his experimental work at incomplet.org.


국문 : http://www.adobe.com/kr/devnet/flashplayer/articles/garbage_collection.html
    

설정

트랙백

댓글

[AS3] ActionScript 3 Tip of the Day

Programming/ActionScript 3.0 2007. 6. 13. 10:03
ActionScript 3 Tip of the Day

The release of Flex Builder 2 is around the corner and though the next version of Flash is still a ways away, ActionScript 3 will be a big part of Flex 2 and the impending release of Flash Player 9 (which arrives with Flex). ActionScript 3 is the next step forward and to help with the transition (for those of you deciding to make it), I thought, since I've been working with AS3 a bit lately, I'd make a new Tip of the Day thread for ActionScript 3.0 to help people prepare. So here we go:

ActionScript 3 Tips and Tricks:
  1. 06-19-06: Change the frame rate of your movie
  2. 06-20-06: Class scope is now bound to class methods
  3. 06-21-06: Graphics Object and the Drawing API
  4. 06-22-06: New Variable Types
  5. 06-23-06: Display Objects
  6. 06-24-06: New Import Directive
  7. 06-25-06: Type Casting and the as Operator
  8. 06-26-06: Unique Class Variables
  9. 06-27-06: New MouseMove Behavior
  10. 06-28-06: The delete Keyword and Class Members
  11. 06-29-06: The Dictionary Class
  12. 06-30-06: Label Statements
  13. 07-01-06: Detecting When the Mouse Leaves the Movie
  14. 07-02-06: SimpleButton Instances
  15. 07-03-06: Commas in Shorthand Array Definitions
  16. 07-04-06: Package Block
  17. 07-05-06: Same-file Helper Classes
  18. 07-06-06: Access Attributes
  19. 07-07-06: Abstract Classes
  20. 07-08-06: The override Keyword
  21. 07-09-06: Using prototype
  22. 07-10-06: Regular Expression (RegExp) Support
  23. 07-11-06: Approach to Depth Sorting
  24. 07-12-06: Deep Object Copies with ByteArray
  25. 07-13-06: Similarly Named Instance and Static Properties
  26. 07-14-06: EventDispatcher
  27. 07-15-06: Events and Event Types
  28. 07-16-06: Writing Inline XML
  29. 07-17-06: Determine Instance Class or Superclass
  30. 07-18-06: super() Placement (Now Anywhere)
  31. 07-19-06: Determining Current Frame Label
  32. 07-20-06: Multiple Arguments in trace()
  33. 07-21-06: Calling Event Handlers without Events
  34. 07-22-06: URLRequest for URL Strings
  35. 07-23-06: XML vs. XMLDocument
  36. 07-24-06: Loading Text and XML with URLLoader
  37. 07-25-06: is Operator (vs instanceof)
  38. 07-26-06: Flash 9: Timelines as Classes
  39. 07-27-06: RegExp: Email Validation
  40. 07-28-06: Render Event
  41. 07-29-06: XML: @ Operator for Attributes
  42. 07-30-06: Event Propagation Support
  43. 07-31-06: Get Sound Spectrum Information
  44. 08-01-06: Number() Conversion No Longer Interprets Octals
  45. 08-02-06: Garbage Collection: Reference Counting & Mark and Sweep
  46. 08-03-06: Weak References
  47. 08-04-06: Flash 9: BitmapData and Bitmaps from the Library
  48. 08-05-06: Changes in typeof
  49. 08-06-06: getBounds() vs getRect()
  50. 08-07-06: for..in and for each..in
  51. 08-08-06: Default Values for Function Parameters
  52. 08-09-06: Undetermined Number of Arguments With ...(rest)
  53. 08-10-06: arguments
  54. 08-11-06: Support for Namespaces
  55. 08-12-06: Namespaces: Name Qualifier Operator (::)
  56. 08-13-06: dynamic is Not Inherited
  57. 08-14-06: Creating a mouseWithin Event
  58. 08-15-06: Prevent Overriding and Subclassing with final
  59. 08-16-06: MXMLC: SWF Metadata Tag
  60. 08-17-06: Proxy Class
  61. 08-18-06: in Operator
  62. 08-19-06: Proxy: getProperty and setProperty
  63. 08-20-06: Flash 9: Display Object Variables and Instance Names
  64. 08-21-06: XML: XML and XMLList
  65. 08-22-06: Constants
  66. 08-23-06: duplicateMovieClip Replacement
  67. 08-24-06: Proxy: callProperty
  68. 08-25-06: Creating graphics Copies
  69. 08-26-06: TextField.appendText()
  70. 08-27-06: include Directive
  71. 08-28-06: Duplicate Variable Definitions
  72. 08-29-06: mouseEnabled and Event Blocking
  73. 08-30-06: mouseChildren with Event Propagation
  74. 08-31-06: rollOver and rollOut vs. mouseOver and mouseOut
  75. 09-01-06: DisplayObjectContainer contains()
  76. 09-02-06: Cleaning Up Event Listeners
  77. 09-03-06: Detecting Addition to or Removal from Stage
  78. 09-04-06: Event Phases and Event Capturing
  79. 09-05-06: Determining Event Phase
  80. 09-06-06: Preventing Event Propagation
  81. 09-07-06: Global Events
  82. 09-08-06: Detecting a mouseUp Outside
  83. 09-09-06: Flash 9: Document Class
  84. 09-10-06: Access to stage and root
  85. 09-11-06: Namespaces: use namespace Directive
  86. 09-12-06: No More Color Class; Use ColorTransform
  87. 09-13-06: Runtime Errors; Error Class
  88. 09-14-06: Errors: try..catch..finally and Exception Handling
  89. 09-15-06: Errors: Asynchronous Exception Handling
  90. 09-16-06: XML: Children (.) and Decendants (..)
  91. 09-17-06: Array.indexOf (Array.lastIndexOf())
  92. 09-18-06: asfunction: Now event:
  93. 09-19-06: Proxy: Property Enumeration (nextName(), nextValue(), and nextNameIndex())
  94. 09-20-06: Event Capturing and mouseEnabled
  95. 09-21-06: Flash 9: Strict Mode
  96. 09-22-06: System.totalMemory
  97. 09-23-06: Closing Net Connections
  98. 09-24-06: Timer Class
  99. 09-25-06: AVM2 (AS3) to AVM1 (AS2/AS1) Communication via LocalConnection
  100. 09-26-06: ByteArray Class


100 AS3 tips! After tip 100, no longer will they be added daily

    

설정

트랙백

댓글

플래시를 느끼며...

Miscellaneous/Story 2007. 6. 12. 02:31

오랜만에 포스트를 쓰게 된다.
플래시라는 툴을 알게 된지 벌써 10년 가까이 되어가는 듯 하다. 그때는 액션스크립트라는 개념 보다는 웹디자인을 위한 저작도구로서의 가치가 급부상 하던 시절이었기 때문에 언어 형태의 작업을 할 일은 거의 없었다.

대학시절 내가 졸업을 하고 무엇을 하며 살 것인가를 고민할 때 플래시는 안중에도 없었다. 단지 개인 홈페이지를 만들 때 보기 좋게 하기 위한 방법에 불과했고 그런 작업 자체가 그냥 나의 작은 즐거움이었기에 관심만 갖고 있을 뿐이었다.

대학 졸업과 여러가지 우여곡절 끝에 난 지금의 회사에서 자리를 잡게 되었다. 집에서 개인 홈페홈페이지를 만들 때 사용했던 MX는 더 이상 실무에서는 사용되지 않고 있었다. 한번도 사용해 보지 않았던 Mx 2007 플래시를 열어보고 툴 사용법부터 하나하나 책을 뒤져가며 다시 공부해야 했고 그 과정속에서 짧지만 좌절도 겪었다.

혼자 서울로 상경하여 두번째 직장인 이곳에서 과연 내가 살아남을 수 있을 까 하는 의구심도 들었고 무엇보다도 내가 하는 작업 자체에 만족할 수 없는 경험의 연속이었기 때문에 더더욱 내가 작게만 느껴졌었다.

2년 3개월이라는 시간은 적으면 적은 시간이고 길다고 하면 긴 시간이다. 그 기간동안 내가 할 수 있는 최선의 노력을 다 했는가라는 질문을 스스로 던져보면 쉽게 ‘예’라고 대답할 수가 없다. 마땅히 집에서 할일 없어서, 또는 해야하는 일이였던 경우가 많았다. 물론 그 속에서 재미를 느꼈기 때문에 지금까지 플래시를 만지고 있지만 그것만으로 부족한 것이 사실이다.

얼마전에 플래시 모임에 처음으로 나가게 되었다. 회사내 팀 회식이 같은 날에 잡혔었는데 두 모임 모두 공교롭게도 1주가 밀리면서 같은 날자에 잡혔으나 약간의 슬럼프에 빠져있는 나에게 조금이나마 돌파구를 찾아보고자 플래시 모임에 참가를 했다.

온라인 상에서 안면이 있던 많은 분들을 만날 수 있었다. 나보다 나이 많은 형님들도 있었고 나보더 나이어린 동생들도 볼 수 있었는데 그 두 부류 모두 하나의 공통점은 배울점이 있다는 것이다.

나는 항상 배움이라는 것을 생각하면 눈에 보이고 머리로 익혀야 하는 배움 보다는 눈으로 보이지 않지만 느낌으로 배우는 배움이 더 중요하다고 생각한다. 눈에 보이는, 머리로 배우는 배움은 단편적인 영화라고 한다면 눈이 보이지 않으나 느낌으로 배울 수 있는 배움은 소설과도 같다.

후자는 시간과 장소를 떠나서 언제 어느 때나 배울 수 있다. 다만 그 배움이란 것은 남이 알려주는 것이 아니라 내 안에서 느끼는 것이기에 자신의 것으로 만들기 위해서는 긍정적인 생각속에서 살아갈 필요가 있을 듯 싶다.

나는 한참 플래시를 공부하는 후배들에게 하고싶은 말이 있다면 이것 하나만 기억했으면 좋겠다.플래시라는 툴은 공부하는 것이 아니라 느끼는 것이라고 말이다.

오랜만에 좋은 분들과 즐거운 이야기 속에서 작지만 큰 배움을 얻었던 하루였다. 그날 참석했던 모든 분들에게 고마움을 전한다.


    

설정

트랙백

댓글

Flickr Searcher 1.8 업로드

Project/Programming 2007. 5. 13. 13:49

사용자 삽입 이미지


사용자 삽입 이미지

사용자 삽입 이미지


Flickr의 Open API를 이용한 사진 검색 어플리케이션 'FlickrSearcher'
version 1.8

http://dicaland.cafe24.com/flickr/FlickrSearcher1_8.swf
====================================================================================================

FlickrSearcher1_8.exe

Version 1.8  Release date : 2007/05/13
Change log
1. photo 썸네일 클릭시에 나타나는 왼쪽 중앙에 있는 information 버튼의 가독성을 위하여 색 변경
2. Search history 기능 추가 : 특정 모드(tags, name, email, nsid)를 통해 검색한 history를 저장할 수 있도록 함.
(최근 검색한 검색어와 페이지 수를 통해서 되돌아 갈 수 있도록 함)
====================================================================================================


    

설정

트랙백

댓글

Flickr Searcher 1.7 업로드

Project/Programming 2007. 5. 10. 11:45
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

Flickr의 Open API를 이용한 사진 검색 어플리케이션 'FlickrSearcher'
version 1.7

====================================================================================================
Version 1.7  Release date : 2007/05/10
Change log
1. 1.6에서 'VIEW AUTHOR PHOTOS'로 검색을 할때 search mode 'name'으로 이동하면서 textField 길이가 불규칙하게 변했던 버그 수정.
2. 정보 TextField를 선택가능 하도록 변경.
3. Photo Information에서 이미지의 exif 정보를 볼 수 있도록 기능 추가.
====================================================================================================
    

설정

트랙백

댓글

Flickr의 Open API를 이용한 사진 검색 어플리케이션

Project/Programming 2007. 5. 9. 09:23



Flickr의 Open API를 이용한 사진 검색 어플리케이션 'FlickrSearcher'


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

====================================================================================================
Version 1.6  Release date : 2007/05/08
Change log
1.    search mode를 tag, name, email, nsid와 같이 4개 모드로 검색 가능하도록 기능 추가.
2.    tag로 검색할 경우에는 ‘,’ 구분자를 통해 복수 tag 검색 가능 추가. ex) quality, blue, yellow
3.    author & photo information 확인 가능.
4.    author의 정보에 있는 “VIEW AUTHOR PHOTOS” 버튼을 통해 author의 사진들을 볼 수 있는 기능 추가.
5.    photo information에서 이미지의 크기별로 view가 가능하며 해당 이미지를 download하는 기능 추가.
6.    license 적용(크리에이티브 커먼즈의 저작권 규약 표시)
7.    author의 icon 이미지 표시(이미지에 대한 모든 정보를 사전에 습득할 시, 속도 문제를 감안하여 해당 이미지를 클릭한 이후 적용됨).
8.    편의성을 고려하여 1.0버전에 있던 fullscreen 모드 삭제,
9.    기타 1.0버전에 없는 다수 기능 추가.
====================================================================================================
Version 1.0  Release date : 2007/05/03
Change log
최신 버전 업데이트시 자동 알림 기능 추가 ====================================================================================================

    

설정

트랙백

댓글

블로그의 올플래시 페이지 infinite 메뉴 추가

Project/Web 2007. 4. 15. 02:26
예전 방문자 카운터 기능을 추가하면서 생각한 것이 있었다. div로 iframe을 잡고 상위 레이어를 올리면 올플래시 형태의 페이지를 만들 수 있을 거라는 생각에서 시도해 보았다.

이 구조를 넣으면서 여러가지 문제점이 생겼는데 문제점들은 아래와 같다.


1. 자바스크립트에서 플래시로 값을 넘겨주기 위해서는 플래시에서 ExternalInterface 클래스를 사용하게 된다. 이 클래스를 이용하면 html에 삽입된 javascript와 플래시간 상호 지정한 function을 호출할 수 있으며 return값도 전달 할 수 있다.
하지만 배경 화면에 해당하는 플래시에서 티스토리 스킨에 제공하고 있는 skin.html안에 삽입된 자바스크립트를 호출하는 것은 가능하나 그 자바스크립트에서 플래시로 값을 넘겨주지 못하는 문제점이 있다. 아마도 크로스 도메인 문제인 듯 싶다.

하루정도 고민 하다가 결국은 우회하기로 결정했다. 일단 하단에 있는 메뉴플래시에서 infinite 버튼을 클릭할 시에 상위에 있는 레이어를 display = block을 적용하고 플래시의 LocalConnection을 이용하여 레이어 안에 있는 플래시와 통신을 하는 방법이다.
여기도 또다시 문제점이 발생했는데 하위 플래시에서 레이어를 살리는 동시에 상위 플래시와 통신을 할 경우에는 기존에 있던 플래시가 포함된 레이어가 작동을 정지하면서 제대로 호출해주지 않는 문제가 발생했다. Display를 대신해 visibility을 이용해 보았지만 마찮가지였다.

상위 레이어가 살아났을 때 플래시에 레이어가 나타났다는 메시지를 전달함으로써 infinite의 초기 시작 모션을 적용해야 하는데 그 문제가 해결되지 않아서 발생하는 문제점이다.

익스플로러와 파이어폭스 두 브라우저에서 테스트해본 결과 두 브라우저 간의 약간의 차이가 발생했다.

그래서 LocalConnection으로 플래시간 통신을 하되 약간은 딜레이 타임을 적용하기로 하고 레이어를 살리고 초기 시작 모션들 들어가기 전에 0.5초간 로딩바를 보여주는 형태로 LocalConnection의 문제점을 해결했다. 사실 해결이라기보다는 궁여지책이다.


2. 두번째 문제는 익스플로러와 파이어폭스의 호환 문제다. document.all는 IE에서만 먹는 코딩 방식이라는 것을 알게 되었다.
보 통 IE에서 div의 style이나 레이어에 접근하기 위한 접근자 방식을 document.all.ID.style.display이런 형태로 썼는데, 이러한 코딩방식은 파이어폭스나 타 브라우저에서는 먹히지 않는 방식이다. MSDOM에서만 사용하는 것이며 W3C에서도 권하지 않는 방법이라고 한다. 우리나라의 경우는 90% 가량이 IE를 사용하고 있는 상황이기 때문에 IE를 사용하고 있다면 별 문제가 되지 않겠지만 타 브라우저를 사용하는 사용자에게는 치명적인 문제를 발생시킨다. 공든 탑이 이러한 표준 문제에서 무너질 수 있다.

W3C에서 권장하는 표준형은 document.getElementById("ID").style.display 이러한 형태로 접근하는 것이다.


3. 세번째 문제는 티스토리에 로그인한 상태에서 블로그에 접근했을 때는 오른쪽 상단에 티스토리 툴바가 보이게 된다.  테스트 과정에서 레이어의 index값을 아무리 올려도 상위에 있는 레이어보다 티스토리 툴바가 상위에 떠있는 것이다. 그래서 블로그 소스를 뒤져보니 상위에 뜨는 툴바의 index값이 무려 1000000라는 사실… 그래서 상위에 뜨는 레이어의 index 값을 1000001로 잡아서 해결했다.


4. 네번째는 문제라기 보다는 레이어를 올리는 과정에서 생겨난 부가적인 노동이다. 블로그에서 음악이 흘러나오도록 play를 시켜놓은 상태에서 infinite 페이지로 들어갔을 때는 끄고, play되고 있던 사용자라면 다시 나올 때 play를 시켜주는 것이다. 그리고 음악을 듣지 않고 있던 사용자라면 그대로 음악이 흘러나오지 않는 기능을 추가해야 했다. 그리고 블로그의 배경에서 랜덤으로 생겨나는 나비의 움직임이 infinite 페이지를 접근했을 때에 불필요하게 CPU의 낭비를 가져오고 있어서 infinite메뉴로 들어갔을 때는 나비들이 생성하지 않도록 interval을 clear시켜주고 다시 블로그로 나갔을 때는 생성하도록 설정해 놓았다.


Infinite메뉴를 추가하면서 가장 큰 문제는 자바스크립트에서 플래시로 통신하기가 어렵다는 것이 가장 큰 문제였던 것 같다. 일단 지금은 LocalConnection을 이용하여 플래시 간에 주거니 받거니 하고 있으니 나중에 알게 되면 수정해야 겠다.

Infinite 메뉴는 아직 구체적은 내용 구성과 구현 방법에 대해서는 생각해 둔 것은 없다. 일단 블로그에서 새로운 시도를 해본 것이고 캠버스에 어떤 것들을 담아갈지는 앞으로 시간 날 때 고민해 봐야 하겠다.

사용자 삽입 이미지


    

설정

트랙백

댓글

trace 예찬론

Programming/Etc 2007. 3. 9. 00:48
action script를 코딩하다 보면 중간 중간 내가 작성하는 코드가 syntax error가 없는지 수시로 체크를 하게 되는데 그 단위는 코드 100줄을 넘지 못한다. 코딩을 하면서 중간에 딴 생각을 하다가 엉뚱한 방향으로 흐르는 경우도 있고 손가락의 강약 조절과 위치 파악을 제대로 하지 못한 손가락의 잘못도 있다.(결코 내 잘못 아니란다 쿠쿠)

대부분 syntax error로 수정이 가능한 것들이나 가끔은 overflow의 문제로 한참을 헤매는 경우도 종종 있다. Overflow의 경우는 컴파일러가 정확히 어느 위치에서 overflow가 발생했는지를 알려주지 않는 과계로 중간 체크를 하지 않고 코드를 길게 늘리다 보면 쉽게 문제가 되는 부분을 찾기가 어려울 경우가 있다.

더군다나 overflow가 발생했다는(플래시는 255번 이상 스택이 쌓이면 overflow가 발생한다.) 것을 output 패널 창에 보여주면 그나마 다행이지만 컴파일러가 한참을 계산하고서야 문제를 알려줄 때면 가뜩이나 바쁜 와중에 뒷골이 땡긴다.

이런 문제는 반복문에서의 조건문이 무한하거나 undefined일 경우 흔히 발생하게 된다. 가끔 사이트를 돌아다니다 보면 이런 문제로 브라우저를 종료해야 되는 경우가 종종 보이는데 외부에서 xml 데이터를 받아와서 처리해야하는 구문이 있다면 xml이 로드된 시점에서 처리해야 하는데 그것을 간과한 듯 하다.

이런 문제를 미연에 방지하기 위해서는 수시로 단위별로 체크를 해야 한다. 어느 언어나 기본적으로 특정 값을 확인 할 수 있도록 print 내장 메소드를 제공하는데 플래시도 trace라는 구문을 제공한다. 언제나 감사함을 느끼는 놈이다.

개인적으로 생각해 볼 때 논리적인 error를 잡아내는 데는 trace 하나면 충분하다. 중간 중간 확인을 하고 진행한 코드라고 했을 때 문제가 발생하지 않은 시점과 문제가 발생한 시점을 파악하고 그 문제가 발생했던 부분을 훑어봐도 어디가 문제인지를 모를 때는 최초 문제가 발생한 부분의 상위부터 단계별로 trace로 문제가 될만한 변수들을 확인하고 넘어가면 어느 시점에서는 문제의 변수를 잡아낼 수 있다.

가끔 프로그래밍에 발을 들여놓은 분들을 보면 이러한 확인 절차 없이 무턱대고 코드를 작성하고 한꺼번에 컴파일을 하는 경향이 있는데, 이럴 경우에는 문제가 발생할 만한 곳을 찾기란 쉽지가 않다. 문제가 없는 부분과 문제가 발생한 부분을 쉽게 파악하지 못하기 때문이다.

물론 oop 개념의 프로그래밍을 한다면 이러한 문제를 파악하는데도 많은 도움을 받게 된다. 하나의 독립된 class로 문제를 최대한 잘게 쪼개놓으면 문제가 된 class를 쉽게 알아 낼 수가 있기 때문이다. 플래시 액션스크립트도 2.0으로 넘어오면서 어느 정도 oop개념을 도입했지만 실무에서 완벽한 oop 프로그래밍을 하기에는 쉽지가 않다. Oop 개념을 완전하게 이해하지 못한 이유도 있지만 큰 프로젝트가 아닌 경우에는 사실 그러한 개발 노력보다 시간이 더 중요한 경우가 허다하게 발생하기 때문이기도 하다.

그래서 나 또한 실무에서는 oop반 막무가내 코드 반을 섞어서 사용하고 있고 개인적인 놀이나 작업을 할 때는 되도록 oop에 신경을 쓴다. 물론 개인적인 놀이에서 그러한 것을 하다 보면 실무의 실질적인 프로젝트에서도 기억을 되살려 사용하기도 하니 그러한 놀이를 통해서 점점 oop의 필요성과 유용성을 인정하게 된다.

이야기를 하다 보니 이야기가 엉뚱하게 흐르고 있다. 이쯤에서 trace 한번 찍어보자.

var 엉뚱한변수:String = “#@$#@$@#@$#”;
trace(“엉뚱하게 이야기가 흐른 변수 = ” + 엉뚱한변수);

액션 스크립트를 떠나 존재하는 모든 프로그래밍 언어에서 print 구문이 없었다면 아마도 지금도 어셈블리어로 코딩을 하고 있을지도 모르겠다. 생각해 보니 프로그래밍도 커뮤니케이션이다.

trace(“나 여깄어…너 거기있니”);
trace(“나 여기있고 너 거기있구나”);

trace를 사랑합시다. ^^
    

설정

트랙백

댓글

TemplateMethod

Programming/Design Patterns 2007. 2. 21. 11:09
 1 class CaffeineBeverage{
2         public function prepareRecipe():Void{
3                 boilWater();
4                 brew();
5                 pourInCup();
6                 if(hook()){
7                         addCondiments();
8                 }
9         }
10         public function brew():Void{
11
12         }
13         public function addCondiments():Void{
14
15         }
16         public function boilWater():Void{
17                 trace("물 끓이는 중");
18         }
19         public function pourInCup():Void{
20                 trace("컵에 따르는 중");
21         }
22         public function hook():Boolean{
23                 return true;
24         }
25 }

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

 1 class Coffee extends CaffeineBeverage{
2         public function brew():Void{
3                 trace("필터로 커피를 우려내는 중");
4         }
5         public function addCondiments():Void{
6                 trace("설탕과 커피를 추가하는 중");
7         }
8         public function hook():Boolean{
9                 return false;
10         }
11 }

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

 1 class Tea extends CaffeineBeverage{
2         public function brew():Void{
3                 trace("차를 우려내는 중");
4         }
5         public function addCondiments():Void{
6                 trace("레몬을 추가하는 중");
7         }
8 }

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

 1 class TemplateTest{
2         public function TemplateTest(){
3                 init();
4         }
5         private function init():Void{
6                 var tea:CaffeineBeverage = new Tea();
7                 var coffee:CaffeineBeverage = new Coffee();
8
9                 trace("Tea Test..............");
10                 tea.prepareRecipe();
11
12                 trace("Coffee Test...........");
13                 coffee.prepareRecipe();
14         }
15 }
    

설정

트랙백

댓글

Adapter

Programming/Design Patterns 2007. 2. 21. 11:08
 1 interface Duck{
2         public function quack():Void;
3         public function fly():Void;
4 }

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

 1 class MallardDuck implements Duck{
2         public function quack():Void{
3                 trace("Quack");
4         }
5         public function fly():Void{
6                 trace("I'm flying");
7         }
8 }

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

 1 interface Turkey{
2         public function gobble():Void;
3         public function fly():Void;
4 }

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

class TurkeyAdapter implements Duck{
        private var turkey:Turkey;
        public function TurkeyAdapter(turkey:Turkey){
                this.turkey = turkey;
        }
        public function quack():Void{
                turkey.gobble();
        }
        public function fly():Void{
                for(var i=0;i<5;i++){
                        turkey.fly();
                }
        }
}


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

 1 class WildTurkey implements Turkey{
2         public function gobble():Void{ 3 trace("Gobble gobble");
4         }
5         public function fly():Void{
6                 trace("I'm flying a short distance");
7         }
8 }

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

 1 class DuckTestDrive{
2         public function DuckTestDrive(){
3                 initialize();
4         }
5         public function initialize():Void{
6                 var duck:MallardDuck = new MallardDuck();
7
8                 var turkey:WildTurkey = new WildTurkey();
9                 var turkeyAdapter:Duck = new TurkeyAdapter(turkey);
10
11                 trace("The Turkey says...");
12                 turkey.gobble();
13                 turkey.fly();
14
15                 trace("The Duck says...");
16                 testDuck(duck);
17
18                 trace("The TurkeyAdapter says...");
19                 testDuck(turkeyAdapter);
20         }
21         private function testDuck(duck:Duck):Void{
22                 duck.quack();
23                 duck.fly();
24         }
25
26 }
    

설정

트랙백

댓글

Command

Programming/Design Patterns 2007. 2. 21. 11:08
 1 interface Command{
2         public function execute();
3 }

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

 1 class Light{
2         private var name:String;
3         public function Light(name:String){
4                 this.name = name;
5         }
6         public function lightOn():Void{
7                 trace(name+" : 불을 켜다");
8         }
9         public function lightOff():Void{
10                 trace(name+" : 불을 끄다");
11         }
12 }

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

 1 class LightOffCommand implements Command{
2         private var light:Light;
3
4         public function LightOffCommand(light:Light){
5                 this.light = light;
6         }
7         public function execute(){
8                 light.lightOff();
9         }
10 }

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

 1 class LightOnCommand implements Command{
2         private var light:Light;
3
4         public function LightOnCommand(light:Light){
5                 this.light = light;
6         }
7         public function execute(){
8                 light.lightOn();
9         }
10 }

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

 1 class RemoteControl{
2         private var onCommands:Array;
3         private var offCommands:Array;
4
5         public function RemoteControl(){
6                 onCommands = new Array();
7                 offCommands = new Array();
8         }
9         public function setCommand(slot:Number, onCommand:LightOnCommand, offCommand:LightOffCommand):Void{
10                 onCommands[slot] = onCommand;
11                 offCommands[slot] = offCommand;
12         }
13         public function onButtonWasPressed(slot:Number):Void{
14                 onCommands[slot].execute();
15         }
16         public function offButtonWasPressed(slot:Number):Void{
17                 offCommands[slot].execute();
18         }
19 }

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

 1 class RemoteControlTest
2 {
3         public function RemoteControlTest ()
4         {
5                 init ();
6         }
7         public function init () : Void
8         {
9                 var remote : RemoteControl = new RemoteControl ();
10                 var light : Light = new Light ("스텐드");
11                 var lightOn : LightOnCommand = new LightOnCommand (light);
12                 var lightOff : LightOffCommand = new LightOffCommand (light);
13                 remote.setCommand (0, lightOn, lightOff);
14                 remote.onButtonWasPressed (0);
15                 remote.offButtonWasPressed (0);
16         }
17 }

    

설정

트랙백

댓글

[UI&C Lab] Clip Navigation

Project/UI&C Lab 2007. 2. 21. 11:02

사용자 삽입 이미지
 
무비클립 생성 화면
 
클립 형태의 네비게이션을 만들어볼 생각으로 만든 기본적인 무비클립 생성이다. 생성된 무비클립들의 _rotation을 통해서 모션을 적용하였다.
 
사용자 삽입 이미지
스케일 조정 화면

사용자 삽입 이미지
네비게이션 무비클립 생성
 
앞에서 만든 기본적인 무비클립 생성을 통해서 각각의 무비클립에 event를 적용하였다.
각 무비클립을 클릭했을 때의 모션으로 선택된 무비클립의 rotation을 0으로 하며 나머지는 특정 rotation값을 적용하고 무비클립이 포함된 무비클립의 좌표를 왼쪽 상단으로 위치시켰다.
Back 버튼을 통해서 다시 펼쳐진 형태로 되돌아 가는데 클릭할 때 적용했던 scale을 그대로 적용함으로서 클릭하기 전의 형태를 유지하도록 하였다.

사용자 삽입 이미지
특정 무비클립 클릭시 모션 적용

사용자 삽입 이미지
컨텐츠 view 화면 back 버튼을 누르면 초기화면으로 모션 적용

사용자 삽입 이미지
네이게이션 무비클립 생성
 

사용자 삽입 이미지
특정 무비클립 클릭시 모션 적용

사용자 삽입 이미지
컨텐츠 view 화면 scale을 통해서 줌인 형태로 화면을 채움

사용자 삽입 이미지
 
BACK 버튼을 눌렀을때 화면으로 되돌아 가는 모션
 
 
clip_navi_2번과 같은 로직으로 구성하였으나 무비크립을 클릭했을 때 무비클립 전체가 scale이 커지면서 보여지는 화면을 채우는 형태로 제작하였다.
이것 또한 2번과 같이 back 버튼을 누르면 기존의 형태로 되돌아 간다.
 
이로써 간단한 _rotation의 Tween을 통한 재미있는 네비게이션이 만들어진듯 하다.
    

설정

트랙백

댓글

[UI&C Lab] Create Random MovieClip

Project/UI&C Lab 2007. 2. 21. 11:01
사용자 삽입 이미지

Create Random MovieClip_1

stage의 특정 random 영역에 무비클립을 생성한다. 생성할 때는 중심점이 되는 new Point(x,y)좌표점을 rnadom으로 설정하므로써 그룹단위로 무비클립을 생성하게 된다. 여기서의 문제점은 무비클립이 많아지면 많아질수록 CPU의 과부화 문제가 발생한다. 노트북에서는 무비클립 300개 이상이되면 그때부터 현저하게 속도 저하가 발생한다.

사용자 삽입 이미지

Create Random MovieClip_2

앞의 버전에서 발생한 CPU 문제점을 BitmapData를 통해서 해결한 버전이다. 생성 방법은 앞과 동일하며 그룹단위(무비클립이 30개 단위로 그룹으로 묶는다 if count%30 == 0)

한 그룹이 완료되었을 때 BitmapData를 통해서 화면에 보여지는 무비클립들을 빈 무비클립으로 생성한 무비클립에 draw하고 생성했던 30개의 무비클립을 remove 시킨다. 그리고 다시 30개의 그룹이 완료되면 또다시 밑에 있는 BitmapData로 그린 무비클립과 새로 생성한 무비클립을 다시 BitmapData로 draw시킨다.

이렇게 진행하면 쌓이는 무비클립이 30개 이상을 넘지 않기 때문에 생성하는 무비클립의 갯수가 무한정 늘어난다고 하여도 CPU의 문제는 없다.

진행을 하면서 오류를 범했던 부분은 BitmapData를 draw시키는 무비클립을 draw 시킬때 마다 새로 생성하지 않고 같은 무비클립에 draw시킬 경우에 기존의 draw시킨 무비클립이 메모리에 쌓이는 문제로 인하여 CPU문제가 그대로 존재한다는 것이었다. 이는 30개 그룹단위로 draw시킨때 같은 depth에 새로 무비클립을 생성하여 기존의 무비클립을 삭제하는 형태로 해결하였다.

BitmapData로 draw시킬때 alpha 값을 50%으로 설정하여 draw시키는 시점과 30개의 무비클립이 삭제되는 시점을 화면에 보여주고 있다

사용자 삽입 이미지
Create Random MovieClip_3
 
앞의 구조와 같다. 앞의 경우는 draw시키는 시점을 alpha = 50으로 보여주었으나 여기서는 Bitmap에 blur 필터를 적용한 것이다.
var filter = new BlurFilter (2, 2, 1);
bitmap.applyFilter (bitmap,bitmap.rectangle, new Point (0, 0) , filter);
 

사용자 삽입 이미지
 
Create Random MovieClip_4
 
앞에서 연구한 결과를 가지고 비주얼적으로 표현할 수 있는 방법으로 이와 같은 형태로 작업을 진행하였다.
 
이것은 앞의 것들과 무비클립의 생성과정은 동일하다. 여기서 해당 무비클립이 그룹단위로 생성할때 자신의 고유색을 가지고 생성을 하는데 그 색은 Shift버튼을 누르면 나타나는 background 이미지의 pixel단위 RGB를 축출하여 적용하였다.이미지의 사이즈가 작기 때문에 앞의 것들보다 무비클립을 작게 하였다.
 
사용자 삽입 이미지
 
Shift 버튼을 눌렀을때 배경을 볼 수 있다.
 
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

Create Random MovieClip의 가장 중요한 부분은 화면에 나타난 무비클립이 변형되지 않는다는 전제조건이 있을 경우에는 해당 무비클립을 stage에 남겨두는 것이 아니라 remove 시키되 기존의 이미지가 그대로 남도록 BitmapData를 사용하여 특정 무비클립에 draw시키므로써 수많은 무비클립의 생성으로 발생하는 플래시의 전체적인 cpu 문제점을 해소하는 것에 중점을 두었다.
    

설정

트랙백

댓글

[UI&C Lab] graph

Project/UI&C Lab 2007. 2. 21. 11:01
예전 모 클라이언트가 그래프를 플래시로 제작하고자하여 만들었던 그래프다. 기본적인 형태는 xml을 로그하여 데이터를 보여주게 되는데 그래프가 나타날때 다이나믹한 모션 효과를 주었다. 시간이없어서 재사용성을 고려하지 않고 만들었던 아쉬움이 있는데 나중에 다용도로 사용할 수 있는 그래프 컴포넌트를 만들어볼 생각이다.
사용자 삽입 이미지


    

설정

트랙백

댓글

[UI&C Lab] trapezoid navigation

Project/UI&C Lab 2007. 2. 21. 11:00
사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

trapezoid navigation 은 좌우로 슬라이드되는 형태의 네비게이션을 만들기 위해 만들었는데 여러장을 적용했을 경우 CPU문제가 있어서 잠시 보류중이다. 이것은 무비클립을 좌우로 사다리꼴모양으로 외곡시켜기 중앙에 위치했을 때는 무비클립을 사용할 수 있도록 만들어 졌다.
 
    

설정

트랙백

댓글

[UI&C Lab] BitmpData Characters...

Project/UI&C Lab 2007. 2. 21. 10:59
이번은 BitmapData를 이용하여 배경 이미지의 색을 축출하여 문자가 포함된 무비클립의 색을 변경하는 작업을 해봤다. 이미지의 윤곽을 잘 보이도록 하기 위해서 무비클립의 갯수를 늘려 6000개가 넘어가니 무비클립을 생성할 때와 색을 입힐때 다소 처리 시간이 지연되는 경향이 있다...
사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지


    

설정

트랙백

댓글