[카테고리:] AS3

  • 플래시 플레이어 버전 체크

    오랜만에 플래시 관련 포스팅이네요.
    동영상 플레이어를 만들면서 테스트 하다가 일부 컴퓨터에서 특정 이벤트가 발생하지 않는 문제를 발견했습니다. 동영상을 일시정지/재생을 반복할 때 NetStatusEvent.info.code에서 NetStream.Pause.NotifyNetStream.Unpause.Notify가 발생하지 않기 때문에, 일시정지/재생 상태를 파악하지 못한는 문제가 생기네요. 그래서 버전 정보로 분기하기 위해 검색하다 다음 코드를 찾았습니다.

    var versionString:String = Capabilities.version;
    var pattern:RegExp = /^(\w*) (\d*),(\d*),(\d*),(\d*)$/;
    var result:Object = pattern.exec(versionString);
    if (result != null){
    	trace("input: " + result.input);
    	trace("platform: " + result[1]);
    	trace("majorVersion: " + result[2]);
    	trace("minorVersion: " + result[3]);
    	trace("buildNumber: " + result[4]);
    	trace("internalBuildNumber: " + result[5]);
    }else{
    	trace("Unable to match RegExp.");
    }

    참고 URL
    Using the Capabilities class
    ActionScript 3.0 Reference: Capabilities

  • AS로 ProgressBar 그리기

    개인적으로 필요해서 만들게 된 코드입니다. 플래시 오쏘링 툴에서 그리지 않고, 액션스크립트 코드만 가지고 프로그레스 바를 만들 수 있습니다.
    Graphics.beginBitmapFill(), Graphics.drawRoundRect() 메소드로 BitmapData를 칠한 다음, BitmapData.scroll() 메소드로 비트맵을 조작하는게 포인트입니다.

    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.geom.Matrix;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    
    var g:Graphics;
    
    // bitmap
    var bd:BitmapData = new BitmapData(20, 40, false, 0xD6D6D6);
    bd.fillRect(new Rectangle(0, 0, 10, 40), 0x6699FF);
    // matrix
    var mat:Matrix = new Matrix();
    mat.rotate(45 / 180 * Math.PI);
    
    // progress bar
    var progress:Sprite = new Sprite();
    progress.x = progress.y = 20;
    addChild(progress);
    g = progress.graphics;
    g.beginFill(0x333333);
    g.drawRoundRect(0, 0, 300, 20, 20, 20);
    g.endFill();
    
    // bar
    var bar:Sprite = new Sprite();
    progress.addChild(bar);
    g = bar.graphics;
    g.beginBitmapFill(bd, mat);
    g.drawRoundRect(0, 0, 300, 20, 20, 20);
    g.endFill();
    
    // mask
    var msk:Sprite = new Sprite();
    progress.addChild(msk);
    g = msk.graphics;
    g.beginFill(0x0);
    g.drawRoundRect(0, 0, 300, 20, 20, 20);
    g.endFill();
    msk.x = -300;
    
    bar.mask = msk;
    
    // timer
    var timer:Timer = new Timer(25);
    timer.addEventListener(TimerEvent.TIMER, timerListener);
    timer.start();
    
    // filter
    var arr:Array = new Array();
    arr.push(new BevelFilter(3, 45, 0xFFFFFF, 1, 0x0, 1, 10, 10, 1, 3));
    arr.push(new DropShadowFilter(2, 45, 0x0, 0.75, 2, 2, 1, 3));
    progress.filters = arr;
    
    // timer listener
    function timerListener(e:TimerEvent):void
    {
    	bd.lock();
    	var c:uint = bd.getPixel(19, 0);
    	
    	bd.scroll(1, 0);
    	bd.fillRect(new Rectangle(0, 0, 1, 40), c);
    	bd.unlock();
    	
    	msk.x += 2;
    	if(msk.x > 0){
    		msk.x = -300;
    	}
    }
  • 점선, 쇄선 그리기

    액션스크립트의 Graphihcs클래스를 사용해서 선을 그릴 때, 점선이나 쇄선 등을 지원하지 않아서 만들어 봤습니다.
    전에 올린 ActionScript로 점선 그리기2: Marching Ants 글에서 사용한 것과 비슷한 방식으로 BitmapDataGraphics.beginBitmapFill()을 사용했습니다.

    var bd:BitmapData;
    var DASH:BitmapData			= new BitmapData(10, 1, true, 0x0);
    var DOT:BitmapData			= new BitmapData(4, 1, true, 0x0);
    var DASH_DOT:BitmapData		= new BitmapData(16, 1, true, 0x0);
    var DASH_DOT_DOT:BitmapData	= new BitmapData(20, 1, true, 0x0);
    
    
    var c:uint = 0xFF000000;
    var rect:Rectangle = new Rectangle(0, 0, 0, 1);
    rect.width = 5;
    DASH.fillRect(rect, c);
    
    rect.width = 2;
    DOT.fillRect(rect, c);
    
    rect.width = 10;
    DASH_DOT.fillRect(rect, c);
    DASH_DOT_DOT.fillRect(rect, c);
    rect.x = 12;
    rect.width = 2;
    DASH_DOT.fillRect(rect, c);
    DASH_DOT_DOT.fillRect(rect, c);
    rect.x = 16
    DASH_DOT_DOT.fillRect(rect, c);
    
    bd = DASH;
    
    
    var line:Sprite = new Sprite();
    addChildAt(line, 0);
    var g:Graphics = line.graphics;
    
    
    function draw():void
    {
    	line.x = p1.x;
    	line.y = p1.y;
    	
    	var xx:int = p2.x - p1.x;
    	var yy:int = p2.y - p1.y;
    	
    	g.clear();
    	g.beginBitmapFill(bd, null, true);
    	g.drawRect(0, 0, Math.sqrt(xx * xx + yy * yy), 1);
    	g.endFill();
    	
    	line.rotation = Math.atan2(yy, xx) / Math.PI * 180;
    }
  • 타원 방정식을 이용한 타원 그리기

    타원 방정식을 이용해서 타원을 그려봤습니다.
    F1, F2 와 P 세개의 점을 가지고, 중심점(C)과 장축(a), 단축(b), 그리고 각도를 구합니다. 그리고 Graphics.drawEllipse() 메소드를 이용해서 타원을 그립니다. 이때 Graphics.drawEllipse()의 좌표는 타원의 중심점이 아닌 좌상단이 기준이라는 것에 주의합니다.
    참고 링크: Elements of an ellipse

    코드가 길어져서, 핵심 코드 부분만 발췌했습니다.
    F1, F2, P는 MovieClip이고, p, f1, f2, c는 Point 입니다.

    p.x = P.x;
    p.y = P.y;
    f1.x = F1.x;
    f1.y = F1.y;
    f2.x = F2.x;
    f2.y = F2.y;
    c.x = F1.x + (F2.x - F1.x) / 2;
    c.y = F1.y + (F2.y - F1.y) / 2;
    
    l1 = Point.distance(f1, p);
    l2 = Point.distance(f2, p);
    f = Point.distance(f1, c);
    a = (l1 + l2) / 2;
    b = Math.sqrt(a * a - f * f);
    angle = Math.atan2( (f2.y - f1.y), (f2.x - f1.x) );
    
    ellipse.x = c.x;
    ellipse.y = c.y;
    ellipse.rotation = angle / Math.PI * 180;
    
    g.clear();
    g.lineStyle(2, 0x6699FF);
    g.drawEllipse(-a, -b, 2*a, 2*b);
    g.endFill();
  • 반투명 마스크 활용

    키노트에서 이미지의 마스크를 편집할 때에 다음과 같이 화면에 보여지는 영역을 제외한 바깥쪽을 반투명하게 표시하는 효과가 있습니다.

    플래시에서 이미지 편집 기능을 개발할 때에도 이런 효과를 쉽게 적용할 수 있습니다.
    아래 플래시 무비에서, 이미지를 드래그 해 보세요.

    아래 코드와 같이 cacheAsBitmap 속성을 사용하면, 반투명한 마스크를 사용할 수 있습니다. 참 쉽죠잉?

    import flash.display.Sprite;
    import flash.display.Graphics;
    import flash.events.MouseEvent;
    
    var sp:Sprite = new Sprite();
    var grp:Graphics = sp.graphics;
    grp.beginFill(0x0, 0.4);
    grp.drawRect(0, 0, 600, 400);
    grp.beginFill(0x0);
    grp.drawRect(50, 50, 500, 300);
    grp.endFill();
    
    addChild(sp);
    
    sp.cacheAsBitmap = true;
    mc.cacheAsBitmap = true;
    mc.mask = sp;

    FLA 소스파일 다운로드