이거 솔직히 쓰기 전에 이 어마어마한 소스코드를 써야 하나 말아야 하나 망설였지만.. 결심했습니다. 노가다의 길을 걷기로 -_-.

자 오늘도 쿠나는 닥치고 뻘짓을 계속하도록 하겠습니다.

시작하기 전에 전체 스크린샷입니다.

설마 놀라시진 않으셨죠? 이정도는 굴러다니는 플래시겜 같은 것에 비하면 낄 턱도 못 됩니다 -_-.

그럼 이제 무비클립에 대한 해명 들어갑니다.


펼쳐두기..


아.... 여기까지 쓰기만 해도 손이 아파오는군요 ;ㅅ;..

소스가 너무 긴 관계로 모든 부분에 대하여 설명이 어려울 듯 합니다. 다만 주요 부분만 조금씩 설명하도록 할게요.

먼저 1프레임에는
Stage.scaleMode = "noscale";
System.useCodepage = true;
loadVariablesNum(urlData, 0);

stage.scalemode는 플래시를 크게 했을때 크기를 깨지지 않게 하고
system.usecodepage는 euc-kr의 텍스트파일을 읽을 때 한글이 깨지지 않게 하고
(주 : UTF-8 문서는 False처리 해야 합니다)
loadVariablesNum은 urlData 주소의 텍스트문서를 읽어오도록 합시다.

이제 9프레임의 액션을 설명해야 하는데, 그전에 여기서 읽어오는 urlData의 자료에 대해서 한번 알아볼  필요가 있습니다.

이게 바로 그 data.txt

여기에 들어있는 자료는.. 로고의 텍스트, 부제목, 오른쪽에 나올 이미지의 주소, 그 이미지들의 가로 크기, 로고의 색상, 배경 색상, 주크박스의 음악 주소 url, 주크박스의 음악 이름이 있습니다. 이것만 제대로 뜯어도 어지간한 조종은 다 되고 또 이식도 가능해집니다.. 그렇기 때문에 이번 프로젝트가 엄청나게 확장성이 크다는 거죠 ㅎㄷㄷ;


그렇게 해서 도달한 9 프레임에서의 액션은.. 촘 깁니다.
var imgArray:Array = new Array();
var imgwidthArray:Array = new Array();
var bgArray:Array = new Array();
var jbArray:Array = new Array();
var jbnameArray:Array = new Array();
var logoclrArray:Array = new Array();
var theme_num:Number;

if (loading=='ok')
{
    mv_navi._x = (Stage.width - mv_navi._width) / 2;
   
    // 불러온 데이터들 [imgs, img_widths, bgs, jburls, logotxt, subtitle, search_domain] 가공
    t_title.text = logotxt;
    t_title_sub.text = subtitle;
   
    // imgs 가공
    imgArray = imgs.split(",");
    // img_widths 가공
    imgwidthArray = img_widths.split(",");
    // bgs 가공
    bgArray = bgs.split(",");
    // jburls 가공
    jbArray = jburls.split(",");
    // jbnames 가공
    jbnameArray = jbnames.split(",");
    // jburls 가공
    logoclrArray = logoclrs.split(",");
   
    mv_bg._x = -10;
    mv_bg._y = 0;
    mv_bg._width = Stage.width + 10;
    mv_bg._height = Stage.height;
   
    // imgnum 변수가 있으면 그 번호로 그렇지않으면 Random
    theme_num = imgArray.length;
    if (imgnum==null)
    {
        imgnum = Math.floor(random(theme_num));
    } else {
        imgnum = parseInt(imgnum);
    }

    // 이미지 로드
    _root.createEmptyMovieClip("char_mv", 0);
    char_mv.loadMovie(imgArray[imgnum]);
    char_mv._x = Stage.width - parseInt(imgwidthArray[imgnum]);
   
    // z-index 재설정
    mc_juke.swapDepths(1);
    b_back.swapDepths(1);
    b_forward.swapDepths(1);
   
    b_back._x = (Stage.width - b_back._width) / 2
    b_forward._x = (Stage.width + b_forward._width) / 2
   
    // 배경색을 지정한다
    var clr:Color;
    clr = new Color("mv_bg");
    clr.setRGB(parseInt(bgArray[imgnum]));
    clr = new Color("t_title");
    clr.setRGB(parseInt(logoclrArray[imgnum]));
   
    gotoAndStop(10);
} else {
    gotoAndPlay(2);
}

야호, 이번엔 색깔도 못입히겠네 -_-.

그니까 위의 data.txt를 읽고, 가공하고, 만약 로딩이 안됬으면 다시 2프레임부터 돌아가서 잠시 기다리는 그런 액션스크립트입니다.

그리고 보라색 부분은 이미지를 로드하는 부분인데 여기서는  스즈미야 하루히 혹은 츠루야가 되겠네요. createEmptyMovieClip으로 빈 무비클립을 생성한 후 그 무비클립에 loadMovie로 이미지를 로드시킨 원리입니다.


그리고 10프레임에 들어간 액션.
// 무비클립 복제부분
import mx.transitions.Tween;
import mx.transitions.easing.*;
import flash.filters.GlowFilter;

var i = 0;
this.onEnterFrame = function() {
    // 무비클립 복제하고 눈오는효과 부분
    if (Math.floor(i % 10 / 9) == 1)    // 3프레임에 한번씩 눈내림
    {
        _mc=_root.snow.duplicateMovieClip(i, i); // 변수를 지정해서 복제된것을 넣는다.
        _mc._x = random(Stage.width) - Stage.height; // 복제된 변수값의 x값
        _mc._y = -_mc._height; // 복제된 변수값의 y값
       
        // 무비클립의 속도조정 (변수로 전달받음)
        _mc.xspeed = (random(30) + 10)/10;
        _mc.yspeed = (random(30) + 10)/10;
       
        // 무비클립의 크기조정
        _mc._xscale = Math.pow((random(1)+1),2) * 100;
        _mc._yscale = _mc._xscale
         
        // 광선 필터를 적용합니다 .
        var glow:GlowFilter = new GlowFilter();
        glow.color = 0xffffff;
        glow.alpha = 1;
        glow.blurX = 10;
        glow.blurY = 10;
        _mc.filters = [glow];
    }
   
    i++;
};

function skin_forward()
{
    imgnum++;
    if (imgnum>theme_num-1)
    {
        imgnum = theme_num-1;
    } else {
        // 이미지 로드
        char_mv.loadMovie(imgArray[imgnum]);
        new Tween(char_mv, "_x", Strong.easeInOut, char_mv._x, Stage.width - parseInt(imgwidthArray[imgnum]), 0.5, true);
   
        // 배경색을 지정한다
        var clr:Color;
        clr = new Color("mv_bg");
        clr.setRGB(parseInt(bgArray[imgnum]));
        clr = new Color("t_title");
        clr.setRGB(parseInt(logoclrArray[imgnum]));
    }
}

function skin_back()
{
    imgnum--;
    if (imgnum<0)
    {
        imgnum = 0;
    } else {
        // 이미지 로드
        char_mv.loadMovie(imgArray[imgnum]);
        new Tween(char_mv, "_x", Strong.easeInOut, char_mv._x, Stage.width - parseInt(imgwidthArray[imgnum]), 0.5, true);
   
        // 배경색을 지정한다
        var clr:Color;
        clr = new Color("mv_bg");
        clr.setRGB(parseInt(bgArray[imgnum]));
        clr = new Color("t_title");
        clr.setRGB(parseInt(logoclrArray[imgnum]));
    }
}

밑의 skin_forward와 skin_back 함수는 필요 없고 보라색 친 부분을 보세요. 바로 snow무비클립을 복제해서 눈을 내리게 하는 액션스크립트입니다.

소스를 보시면 xspeed, yspeed라는 임의의 변수를 복제된 무비클립에 전달해주고 glow필터를 적용합니다. 그러면 무비클립 snow에는 받아온 xspeed, yspeed를 처리하기 위해 어떤 액션스크립트가 들어있을까요.

onClipEvent (load)
{
    this.onEnterFrame = function() {
        this._x += xspeed;
        this._y += yspeed;
       
        // 스테이지 바깥으로 나가버리면 자동소멸시킨다
        if (this._x > Stage.width) { delete removeMovieClip(this); }
        if (this._y > Stage.height) { delete removeMovieClip(this); }
    };
}

예, 간단합니다. 자신의 좌표를 xspeed, yspeed에 각각 더하고 플래시의 과부하를 방지하기 위해서 좌표가 스테이지 밖으로 나가면 자기 자신을 삭제하는 소스입니다. 개인적으로는 이 예제와 비슷한 듯 하네요.

그러면 이제 남은 주요 부분은 RSS메뉴 부분의 애니메이션 효과 그리고 주크박스의 소리재생이 있겠네요. 먼저 rss부터 설명드리도록 하겠습니다.

mv_recentpost 무비클립의 2번째 프레임의 액션스크립트입니다.
// UTF-8이므로 usecodepage false
System.useCodepage = false;
var linkArray:Array = new Array();

function blogLoad ()
{
        var rss_xml = new XML ();
        rss_xml.ignoreWhite = true;
        rss_xml.onLoad = function ()
        {
                rss_0.t.text = this.childNodes[0].childNodes[0].childNodes[8].childNodes[0].childNodes[0].toString ();
                rss_1.t.text = this.childNodes[0].childNodes[0].childNodes[9].childNodes[0].childNodes[0].toString ();
                rss_2.t.text = this.childNodes[0].childNodes[0].childNodes[10].childNodes[0].childNodes[0].toString ();
                rss_3.t.text = this.childNodes[0].childNodes[0].childNodes[11].childNodes[0].childNodes[0].toString ();
                rss_4.t.text = this.childNodes[0].childNodes[0].childNodes[12].childNodes[0].childNodes[0].toString ();
                rss_5.t.text = this.childNodes[0].childNodes[0].childNodes[13].childNodes[0].childNodes[0].toString ();
                rss_6.t.text = this.childNodes[0].childNodes[0].childNodes[14].childNodes[0].childNodes[0].toString ();
                rss_7.t.text = this.childNodes[0].childNodes[0].childNodes[15].childNodes[0].childNodes[0].toString ();
                rss_8.t.text = this.childNodes[0].childNodes[0].childNodes[16].childNodes[0].childNodes[0].toString ();
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[8].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[9].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[10].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[11].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[12].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[13].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[14].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[15].childNodes[1].childNodes[0].toString ());
                linkArray.push(this.childNodes[0].childNodes[0].childNodes[16].childNodes[1].childNodes[0].toString ());
        };
        rss_xml.load ("http://kuna.wo.tc/rss");
        status.text = "로딩중...";
}

blogLoad ();

으악, 코드가 압박입니다 -_-;

그러니까..


이런 겁니다.

(............)


자 이제 애니메이션 부분의 효과. tween클래스를 이용했습니다.
import mx.transitions.Tween;
import mx.transitions.easing.*;

....
onRollOver = function() {
    new Tween(mv_bg, "_x", Strong.easeInOut, mv_bg._x, 10, 0.5, true);
    new Tween(mv_bg, "_width", Strong.easeInOut, mv_bg._width, 27, 0.5, true);
    new Tween(mv_bg, "_alpha", Strong.easeInOut, mv_bg._alpha, 20, 0.5, true);
}

onRollOut = function() {
    new Tween(mv_bg, "_alpha", Strong.easeInOut, mv_bg._alpha, 0, 0.5, true);
}

글씨 색 바뀌는 것은 setRGB로 처리했고, Tween클래스 이용법은 위 소스코드 참조하시면 될 듯 하네요.



그리고 주크박스의 소리재생.

먼저 mc_juke무비클립 안의 버튼들에는 이런 액션들이 입혀 있습니다.

    _root.mc_juke.sound_stop();
    _root.mc_juke.sound_play();
    _root.mc_juke.sound_ff();

즉 그러니까 음악 관련 함수들은 mc_juke로 다 몰아넣었다는 소리죠.

여기서 무비클립 mc_juke에 들어간 액션스크립트를 봅시다.

onClipEvent (load)
{
    var my_sound:Sound = new Sound();
    var isPlayed:Boolean = false;
   
    function sound_play()
    {
        if (!isPlayed)
        {
            selectmusic();
            isPlayed = true;
        }
        my_sound.start();
    }
   
    function sound_stop()
    {
        my_sound.stop();
    }
   
    function sound_ff()
    {
        selectmusic();
        isPlayed = true;
        my_sound.start();
    }
   
    function selectmusic()
    {
        var num = Math.floor(random(_root.jbArray.length + 1));
        this.t_name.text = _root.jbnameArray[num];
        my_sound.loadSound(_root.jbArray[num], true);
    }
}

그러니까 제일 중요한 부분은 loadSound가 되겠습니다.
var mysound:Sound = new Sound();
mysound.loadSound(url, true)

를 하면 url의 음악이 스트리밍으로 재생됩니다.
[단 url의 음악은 mp3형식이어야 합니다!]



이상 소스코드 분석을 마치도록 하고..

도움 되셨으면 좋겠습니다 (__)

댓글을 달아 주세요

  1. BlogIcon 카이토 2008/12/28 09:29
     addr - mod/del - rep

    쿠나님 대단하심

    스킨에서 로딩도 나오고 노래도 나오고..

    • BlogIcon 쿠나 2008/12/28 13:17
       addr - mod/del - rep

      너무 대단하게 보시지 않아도 됩니다;; 그냥 이 기능들을 한개로 묶어놓은 것 뿐이에요 ㅋㅋ

  2. BlogIcon 디파일러 2008/12/28 11:32
     addr - mod/del - rep

    알기 쉽게 설명 좀 ㅠㅠ

    • BlogIcon 이스나에 2008/12/28 12:25
       addr - mod/del - rep

      저게 최대한 일듯 ;;

      액션 스크립트는 그말대로 스크립트 ;

      알아서 다해야 된다는..

      플래시 라는게 노가다 놀이라서 >_<

    • BlogIcon 쿠나 2008/12/29 11:40
       addr - mod/del - rep

      음.. -_-;;

  3. BlogIcon Noel 2008/12/28 13:18
     addr - mod/del - rep

    플래시 gg 귀찮 ㄷㄷ

  4. BlogIcon 影猫 2008/12/28 22:08
     addr - mod/del - rep

    노가다의 힘은 위대하군요...;;;

    • BlogIcon 쿠나 2008/12/29 11:45
       addr - mod/del - rep

      ^^;.. 노가다도 노가다지만 나름 또 머리를 써야 하는지라 .. ㅠㅠ

  5. BlogIcon 알라 2008/12/28 22:57
     addr - mod/del - rep

    오오 역시 노가다의 힘은 무한이군요 =ㅁ=

  6. BlogIcon 진모씨 2009/07/28 22:08
     addr - mod/del - rep

    ㅎ... 프로그래머인 저로서는 별로 복잡하지 않스무니다(퍽!)

< 1 ... 546 547 548 549 550 551 552 553 554 ... 832 > Top