Monthly Archive for August, 2006

Classes in As and Java or C++

[퍼온글] 출처 : <Flex 2 language Reference 36 page>

Programmers familiar with object-oriented programming (OOP) in Java or C++ may think of objects as modules that contain two kinds of members: data stored in member variables or properties, and behavior accessible through methods. The ECMAScript edition 4 draft, the standard upon which ActionScript 3.0 is based, defines objects in a similar but slightly different way. In the ECMAScript draft, objects are simply collections of properties. These properties are containers that can hold not only data, but also functions or other objects. If a function is attached to an object in this way, it is called a method.
While the ECMAScript draft definition may seem a little odd to programmers with a Java or C++ background, in practice, defining object types with ActionScript 3.0 classes is very similar to the way classes are defined in Java or C++. The distinction between the two definitions of object is important when discussing the ActionScript object model and other advanced topics, but in most other situations the term properties means class member variables as opposed to methods. The Flex 2 Language Reference, for example, uses the term properties to mean variables or getter-setter properties. It uses the term methods to mean functions that arepart of a class.

One subtle difference between classes in ActionScript and classes in Java or C++ is that in ActionScript, classes are not just abstract entities. ActionScript classes are represented by class objects that store the class’s properties and methods. This allows for techniques that may seem alien to Java and C++ programmers, such as including statements or executable code at the top level of a class or package.

Another difference between ActionScript classes and Java or C++ classes is that every ActionScript class has something called a prototype object. In previous versions of ActionScript, prototype objects, linked together into prototype chains, served collectively as the foundation of the entire class inheritance hierarchy. In ActionScript 3.0, however, prototype objects play only a small role in the inheritance system. The prototype object can still be useful, however, as an alternative to static properties and methods if you want to share a property and its value among all the instances of a class.

In the past, advanced ActionScript programmers could directly manipulate the prototype chain with special built-in language elements. Now that the language provides a more mature implementation of a class-based programming interface, many of these special language elements, such as __proto__ and __resolve, are no longer part of the language.

Moreover, optimizations of the internal inheritance mechanism that provide significant Flash Player performance improvements preclude direct access to the inheritance mechanism.
actionscript 와 java or c++ 의 class 간의 개념이 약간 다르다.
어찌보면 다아나믹한 움직임을 구현하기 위해선 필요한 차이점인지 모른다.
그래도 ECMAScript 기반의 언어라 그런지 java 와는 외향이 거의 흡사해진다는 느낌이다.

prototype 은 뭔가 꺼림직해서 이전부터 건드리지 않은 부분이지만 아니나 다를까 성능에 문제가 있을 수 있다고 하니 protoype object 는 터치하지 말아야 겠다…

FileReference Class Tip

현재 flash8 에서 지원하는 파일 업로드 클래스인 FileReference 는 어쩌면 반쪽짜리 업로드 클래스이다. 왜냐하면 파일업로드 완료시 서버와의 어떤 변수 값도 받을 수 없기 때문이다.

물론 onComplete 가 업로드 완료시에 플래시 쪽에서 호출되지만 이는 단순히 업로드 완료만 알수 있는것이다.

특별히 안정적으로 업로드를 구성하지 않는다면 다시말해, 개인이 업로드를 관리하고 사용자가 많지 않을경우 물론 업로드가  완료되는 이벤트만 발생되어도 문제가 없다.

하지만 사용자가 많은 경우, 예를 들어 사용자가 사진을 업로드하는 사이트를 만들경우,

이런 경우에는 반드시 업로드하는 클라이언트 파일명을 바꾸어야 할 필요가 있다.

중복의 여지가 있기 때문이다. 만약 이런 파일 필터링을 거치지 않는다면 분명히 파일이름이 같게되어 이전 파일이 덮어써지는 현상이 발생할 것이다.

따라서 좀더 안정적인 파일 업로드 구현을 원한다면 파일 생성 일자나 일련의 첨자를 붙여 파일 이름을 변경하는 것은 필수이다.

이때 문제가 되는 것이 바로 위에 언급한 서버와 플래시간의 변수 교환문제이다.

FileReference class 에서의 upload()  method의 파라미터에는 서버파일의 데이타를 받을수 없다.

따라서 서버에서 파일 이름을 임의로 변경해 버리면 플래시에서 알 수 있는 방법이 없다.

물론 약간의 팁을 사용하면 가능하다.

다행이도 upload url에 매개변수를 첨부하여 서버에 전송할 수 있다.

바로 이런방법으로 서버에서 파일명을 저장하는 것이 아니라 플래시에서 정한 파일명을 서버로 보내 그걸 파일명으로 저장하면 위와 같은 문제를 해결할 수 있다.

<upLoad.as>

private function upload():Void

{

var success:Boolean;

noRep=new Date().getTime();

success = this._fileRef.upload(UploadExample.URL+“?noRep=”+noRep);

// url에 중복을 피하기 위한 현재 시간 정보를 첨부한다.

}

private function onComplete(fileRef:FileReference):Void

{

trace(file Name—>”+noRep+”_”+fileRef.name);

//업로드 완료시 서버에 저장완료된 파일명을 알수 있다.

}
<upload.php>

<?php

//path to storage

$storage = ‘uploadedFiles’;

$upFile=”$storage/”.$noRep.’_’.$_FILES['Filedata']['name'];

//if the file is moved successfully

if ( move_uploaded_file( $_FILES['Filedata']['tmp_name'] , $upFile ) ) {

echo( ’1 ‘ . $_FILES['Filedata']['name']);

//file failed to move

}else{

echo( ’0′);

}

?>

AS3.0 에서 업로드 데이타 필드명을 따로 플래시에서 지정할 수 있게 바뀌었지만 서버에서의 변수 문제는 제공해 주질않았다.

Mouse Event in AS3.0

기존에 AS2.0 까지는 MovieClip 안에 버튼을 넣고 MovieClip 에 마우스 이벤트를 걸면 작동이 되질 않았다. 즉 버튼안에 버튼이 있는 상태는 마우스 이벤트가 발생하지 않아 네비게이션 같은 작업을 할때 정말 쉽지 않았다.

편법으로 hitTest 를 통해 이벤트를 체크했지만 리소스 측면에서 별로 바람직하지 못한 방법이다.

<AS2.0>

clip.onRollOver=function()

{

trace(“rollOver “+ this);

}

clip 이라는 무비클립안에 버튼이 들어가 있는 상태. 무비클립에 마우스 이벤트를 설정해도 작동하지 않는다.

<AS3.0>

function onRollOver(objEvent:Event)

{

trace(“RollOver “, objEvent.target, objEvent.target.name);

}

clip.addEventListener(MouseEvent.MOUSE_OVER, this.onRollOver);

버튼으로 작동하는 clip 무비클립 안에 버튼이 있어도 이벤트를 발생시킨다.

download sample

MD5 and SHA1 in AS3

javascript 버전으로 나온 MD5 와 SHA1 을 컨버팅…
점점더 flash가 application tool 로써 부각되는 만큼 보안에 신경써서 암호화시키는 방법을 좀더 고려해야겠다.

import com.dstrict.UB.util.system.security.MD5;
import com.dstrict.UB.util.system.security.SHA1;

trace(MD5.encrypt(“kimkijeung”)); //8447d508fb3dc5987853d6b2eb8a752f
trace(SHA1.encrypt(“kimkijeung”)); //c6fe97a875b287751d6d8c33256d4277fe1e2ee2

>Paj’s Home: Cryptography: JavaScript MD5

Label Statements

ActionScript 3 introcuduces labels, new identifiers that can be associated with loop blocks. Why would you want to identify a loop block? Because you can use that identifier as a target for break and continue commands. Consider two loops where one is nested in the other. If at some point you want to exit both loops while in the nested loop, you can’t. The break command only exits the current block. A common workaround is to use a flag variable to be able to check that, when in the first loop, if that should be exited as well

중첩된 loop의 경우 기존에는 한번에 loop를 벗어나는것은 할수 없었다.

다만 flag를 이용해 벗어나는 경우가 유일한 방법이다. 이젠 그럴필요 없다.

As3.0 에서는 Label Statements 를 이용해 전체 루프를 빠져나올수가 있다.

As 2.0 ActionScript Code:

var i:Number;
var j:Number;
var exit:Boolean = false;
 
for (i=0; i<10; i++) {
	for (j=0; j<10; j++) {
          if (i >3 && j> 3) {
		  exit = true;
		  break;
          }
     }
	if (exit) {
	   break;
	}
 
}

—–> exit 라는 flag 변수를 이용해 체크한다.

As 3.0 ActionScript Code:

var i:Number;
var j:Number;
 
mainLoop: for (i=0; i<10; i++) {
	for (j=0; j<;10; j++) {
		if (i > 3 && j > 3) {
          break mainLoop;
		}
    }
}

——> mainLoop 의 label 을 지정해 한번에 loop 탈출…..지저분하게 변수를 사용하지 않는 명확한 방법이다.

Easing motion in Frame

프레임 모션에 easing 값을 넣어서 적용하는 방법…
프레임의 길이가 적어도 200 frame 이상이 되여야만 어느정도 부드러운 효과를 기대할수 있다.
일반적인 트윈같은 경우 action 으로 하는 경우가 훨씬 자연스럽지만 프레임 모션을 사용해야할경우
이 방법을 사용하면 action 같은 frame 모션이 가능하다.

import mx.transitions.Tween;
import mx.transitions.easing.*;
 
mc._frame = mc._currentframe;
 
var myTween:Tween = new Tween(mc, "_frame", Strong.easeOut, mc._currentframe, 300, 1, true);
 
myTween.onMotionChanged = function() {
mc.gotoAndStop(Math.round(mc._frame));
};
myTween.onMotionFinished = function() {
this.yoyo();
};

프레임 속성을 동적으로 할당해서 Tween class 를 사용하여 easing function 를 적용하여 구현.

The delete Keyword

The delete keyword in Flash is used to remove variable definitions. It doesn’t delete objects from memory (this happens behind the scenes using something called the “Garbage Collector”), it just takes a variable you’ve created and gets rid of it so that it is no longer accessible and is no longer present through iteration (for..in loops, etc.).

Internally, the Garbage Collector, or GC for short, knows when to physicially delete objects in memory when they no longer have any variables that reference them. So, for example, if you have two variables A and B and they both reference ObjectX, deleting variable A will not cause ObjectX to be removed from memory by the GC because variable B still references it. However, if you delete both variables A and B, there will be no more references to ObjectX and the GC will recognize that it needs to be removed from memory

ActionScript Code:

var a:Object = new Object();

var b:Object = a; // reference same new Object();

delete a;

trace(b); // [object Object] – still exists in memory

delete b; // GC will mark object for deletion from memory

This works practically the same way for Flash 8 and Flash 9 (ActionScript 1, 2, and 3), though some changes were made in 8 to improve the GC. (Note: GC deletion from memory is not immediate.)

Though the GC has not really changed much with ActionScript 3 and the new virtual machine that runs it, what has changed is the behavior of the delete keyword. Now, the delete keyword only works for dynamic properties of a class instance and not declared class memebers (variables or methods). With ActionScript 1 and 2, delete could be used for anything. ActionScript 3 only lets you delete dynamic variables and locks those which are not.

// ActionScript 2

class DeleteVarClass {

public var myVar:Number;

function DeleteVarClass() {

myVar = 1;

trace(myVar); // 1

delete myVar;

trace(myVar); // undefined

}

}

// ActionScript 3

package {

public class DeleteVarClass {

public var myVar:Number;

public function DeleteVarClass() {

myVar = 1;

trace(myVar); // 1

delete myVar;

trace(myVar); // 1

}

}

}

Because myVar in the above example was declared as part of the class definition, it cannot be deleted using delete in ActionScript 3.

Since you cannot delete class members in ActionScript 3, if you want to cause a variable to no longer reference an object or value in memory you should set your variable’s value to null instead of deleting it.

Garbage Collectors는 참조값이 없는한 사용되지 않는 변수에 대한 메모리를 자동으로 찾아서 소거해주는 메모리 소거 프로세스이다. 기능상으로는 AS2.0 이나 AS3.0 이나 크게  달라진 부분은 없지만 한가지, AS3.0 에서는 클래스 맴버변수로 선언된 변수는 제거할수 없게 바뀌었다.

ZenDoc 1.0 Released

ZenDoc 1.0 has been released.

ZenDoc is a free, open source ActionScript documentation utility for converting AS 2 class files commented with JavaDoc style comments into HTML documentation.

JavaDoc 형식으로 작성한 AS2.0 파일을 Html 형식의 문서로 전환해 준다.

로컬에서 작동하는 Application이 아니라 웹서버(PHP)에서 실행되는 형식이다.

개인적으로 작성한 클래스 파일을 이런형식으로 만들어 보는건 큰 의미는 없겠지만 제작한 클래스를 배포하거나 공동작업에 필요한 클래스를 공유할때 다른사용자에게 유용할듯 싶다.

주석을 JavaDoc형식으로 작성하긴 하지만 빠쁠땐 그냥 넘어가는 경우도 있는데 나중을 위해 좀더 부지런해져야 할 것같다.

Changing the frame rate in movie

Using ActionScript 3, you can dynamically change the frame rate of your movie using the Stage class.

The Stage class (flash.display.Stage) is the class assigned to the stage object which is accessible from your main movie sprite/movie clip (or others within the same security sandbox) using the stage property. The stage object has a frameRate property which can contain any value between 0.01 and 1000 and determines the frame rate at which the Flash player plays back your movie. Changing this value lets you change the frame rate at runtime.

// change frame rate to 12 fps:

stage.frameRate = 12;

이전 버전에서는 한번 정한 framerate 는 바뀔수가 없었다. 즉 동적으로 frame 속도를 조절할수 없었음.

근데 과연 frameRate 가 1000까지 지원할까?…. 지원하더라도 눈으로 확인은 불가능 할듯.

다만 각각의 swf 파일의 속도는 조절안되고 전체 stage 의 속도만 조절되는것 같다.

Detecting When the Mouse Leaves

One thing about previous versions of ActionScript was that you could never tell when the user no longer had his or her mouse over the Flash movie. This made it hard for people to know whether or not the user is still interacting with their movie or if they’ve given up and moved on to something more interesting. This was especially a problem for custom cursors where, if the user moved the cursor off the Flash movie, the custom cursor would still remain in the Flash movie not moving while the real cursor could be seen moving around every where else. ActionScript 3 now allows you to detect when the mouse has left the flash movie using the stage’s mouseLeave event. This event happens whenever the mouse exits the Flash movie. There is no mouseEnter event, but you can use mouseMove for that since mouseMove only occurs in Flash (for the stage, or really any, object) when the mouse is within the bounds of the movie.

html에서의 플래시 영역 밖으로 마우스 커서를 옮겼을경우 이전에는 정확히 그것을 알아낼 방법이 없었다. 마우스 커서가 안보인다 하더라도 엄연히 플래시 오브젝트 안에 남아서 실행되고 있었는데

이것을 as3.0 에서는 체크할수 있게 되었다.

package {
 
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Mouse;
 
    public class Test extends Sprite {
 
        private var cursor:Sprite = new Sprite();
 
        public function Test() {
 
            cursor.graphics.beginFill(0xFF);
            cursor.graphics.drawRect(0, 0, 25, 25);
 
            addChild(cursor);
 
            stage.addEventListener(Event.MOUSE_LEAVE, cursorHide);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorFollow);
 
            Mouse.hide();
        }
 
        public function cursorHide(evt:Event):void {
            cursor.visible = false;
        }
 
        public function cursorFollow(evt:MouseEvent):void {
 
            if (!cursor.visible) cursor.visible = true;
            cursor.x = stage.mouseX;
            cursor.y = stage.mouseY;
 
            evt.updateAfterEvent();
        }
    }
}