플래시의 타임라인에서 레이어 마스크를 사용하는 경우에, addChild() 메소드 사용 시에 주의가 필요합니다.
다음과 같이 레이어 마스크를 적용한 무비에, 액션스크립트로 생성한 무비클립을 애드해 보겠습니다.

1
2
3
4
5
6
var mc:MovieClip = new MovieClip();
var g:Graphics = mc.graphics;
g.beginFill(0xFF0000);
g.drawRect(50, 50, 200, 100);
g.endFill();
addChild(mc);

그러면 다음과 같이, 애드된 무비클립도 마스크가 적용되어 버리는 문제가 생깁니다.

아마도 Layer 2와 Layer 1 사이로 애드가 되면서, 마스크가 씌워지는 것으로 보입니다.

Layer 1 위에 다른 객체가 위치한 경우에는 마스크되지 않고 정상적으로 보여집니다. 또는 addChildAt(mc, 0)와 같이 사용해도 문제가 발생하지 않습니다.
레이어 마스크를 사용할 때에는 이런 부분을 염두에 두고 개발해야 겠네요.

 

Gapless sound looping in ActionScript 3.0

보통 사운드 루핑을 만들 때 Event.SOUND_COMPLETE 이벤트나 Sound.play(0, 999);를 사용할텐데요. 이 경우에 음악이 재생되는 사이에 약간의 틈이 발생합니다. 다음 플래시 무비처럼 말이죠.

이 파일은 아래의 코드와 같이, Event.SOUND_COMPLETE를 사용하여 사운드를 루프시키고 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import flash.media.*;
import flash.events.*;
import flash.utils.Timer;
 
var snd:Sound = new loop();
var chn:SoundChannel;
 
function playSound():void
{
	if(chn){
		chn.removeEventListener(Event.SOUND_COMPLETE, sndListener);
	}
	chn = snd.play();
	chn.addEventListener(Event.SOUND_COMPLETE, sndListener);
}
 
function sndListener(e:Event):void
{
	playSound();
}
 
lbl.text = "Loop with Event.SOUND_COMPLETE";
btn2.enabled = false;
btn1.addEventListener(MouseEvent.CLICK, clickListener1);
btn2.addEventListener(MouseEvent.CLICK, clickListener2);
function clickListener1(e:MouseEvent):void
{
	playSound();
	btn1.enabled = false;
	btn2.enabled = true;
}
function clickListener2(e:MouseEvent):void
{
	btn1.enabled = true;
	btn2.enabled = false;
	chn.stop();
}

Continue reading »

 

XML에 차일드 노드를 추가하는 것은 XML.appendChild() 메소드를 사용하면 되는데, 공식적으로 속성(attribute)을 추가하는 메소드는 없습니다.

그래서 구글로 검색해 보니, 다음과 같은 방법으로 간단히 속성을 추가할 수가 있네요.

var xml:XML = new XML(<root />);
xml.@newAtrb = "value";
trace(xml.toXMLString());
// output: <root newAtrb="value"/>
 

배열(Array)을 벡터(Vector)로 변환하는 것을 테스트 해봤습니다. 인터넷에서 검색해보면 거의 for나 for in을 사용해서 변환을 시키더군요. 그래서 Function.apply()를 사용하면 어떨까 하고 시험해 봤는데, apply 가 압도적인 속도를 보여주고, 코드 또한 간결하네요.

아래 코드로 테스트 해보면 대충 for는 80ms, for in은 90ms, apply는 15ms 정도의 속도를 보여줍니다. Function.apply()를 가끔 사용하긴 하는데, 이렇게 빠른지는 오늘 처음 알았네요.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import flash.utils.getTimer;
 
// original array
var arr:Array = new Array();
for(var i:uint=0; i<1000000; i++){
	arr.push(i);
}
 
// vector
var vec:Vector.<int> = new Vector.<int>();
 
var n:int = getTimer();
 
// for
/*var len:uint = arr.length;
for(i=0; i<len; i++){
	vec.push(arr[i]);
}*/
 
// for in
/*var num:uint;
for each(num in arr)
{
    vec.push(num); 
}*/
 
// Function.apply
vec.push.apply(null, arr);
 
trace(getTimer() - n);
trace(vec.length);
 

현재 진행중인 작업에서 텍스트 편집 기능을 만들다가 텍스트필드 관련 플래시 플레이어 버그를 하나 발견했습니다. 텍스트필드에서 Event.CHANGE 이벤트가 발생했을 때, 텍스트필드의 높이가 변하는 경우 scrollV나 maxScrollV값이 제때 반영되지 않습니다.
만일 CHANGE 이벤트를 사용하여 텍스트 스크롤바와 같은 기능을 개발한다고 하면, 이로 인해서 오류가 발생할 여지가 생기는 것이죠. 그래서, 일단 이 내용을 어도비에 버그로 신고해 두었습니다.
http://bugs.adobe.com/jira/browse/FP-7234

어도비의 담당자도 문제 재현했다고 코멘트를 단 것으로 보아, 언제가 될지는 모르지만, 향후 플래시 플레이어 업데이트에서 수정 될 것으로 기대됩니다.

그렇다고 그때까지 마냥 기다릴 수만은 없으므로, 이 문제를 우회하는 방법도 공유합니다. 해결책은 매우 간단한데, TextField.height와 TextField.textHeight를 호출해 주기만 하면 됩니다.
아래 샘플의 첫 번째 텍스트필드를 보면, 텍스트 편집 시에 엔터키를 눌러 텍스트필드의 크기가 변했을 때 scrollV와 maxScrollV가 제대로 반영되지 않는 것을 볼 수 있습니다.

세 번째의 경우처럼, height와 textHeight를 호출해 주기만 하면 두 속성이 모두 정상적으로 변경된 것을 확인할 수 있습니다. 아마도 스크롤 관련 값을 업데이트하는 코드가 높이를 설정하는 코드에 들어가 있기 때문인 것으로 추측되네요.
두 번째와 같이 height나 textHeight 중 하나만 호출해도 오동작을 하므로, 꼭 두 개의 속성을 함께 호출해 주어야 합니다.

© 2011 Hangun's World - Blog Suffusion theme by Sayontan Sinha