ActionScript 3.0裡的stage(舞台), root和MainTimeline(主時間軸)

ActionScript 3.0裡的stage(舞台), root和MainTimeline(主時間軸)
文∕趙英傑

本文旨在補充《碼上就會:Flash CS3動畫設計寶典》書籍11-20頁「調整物件的『深度』」,以及12-24頁「認識『顯示物件』與『顯示物件容器』」這兩節。

本文將透過一個簡單的範例說明stage(舞台)物件,以及MainTimeline(主時間軸)和root的概念。請按此連結下載範例檔

  1. MainTimeline和root:每個Flash影片都有一個「主時間軸」,也就是位於最上層舞台的時間軸,在程式中透過「顯示物件」(如:影片片段、文字欄位、按鈕…等等)的root屬性存取。
  2. stage:每個Flash影片也都有一個stage(舞台)物件,而且在Flash的執行環境(Flash Player)中,也僅有一個stage。程式透過「顯示物件」的stage屬性存取舞台。

「舞台」和「主時間軸」的關係如下,在播放Flash影片時,Flash Player會自動把影片的「主時間軸」掛載在「舞台」之下,換句話說,MainTimeline是stage的唯一子物件(child)。

stage和MainTimeline

若在空白的ActionScript 3.0影片檔的關鍵影格內輸入底下的程式敘述:

trace(this);

或者:

trace(this.root);

輸出面版將呈現如下的訊息,代表"this"或"this.root"指的是MainTimeline(主時間軸)物件:

[object MainTimeline]

底下的敘述將指向影片的「舞台」:

trace(this.stage);

stage的numChildren屬性將傳回1,代表「舞台」底下只有一個子物件,就是「主時間軸」。

trace("舞台的子物件數量:" + stage.numChildren);

因此,底下指向stage的第一個子物件(索引編號0)的敘述,也代表指向主時間軸:

trace(this.stage.getChildAt(0));

下圖是範例 b.fla 檔的舞台畫面,包含兩個靜態文字欄位、兩個動態文字欄位、一個按鈕和兩張圖片。

b.fla檔的畫面

從程式的角度來看,這個影片的物件階層架構如下(註:各個元素的索引編號是我隨便寫的,在此範例中,索引編號的前後順序不重要)。無論是徒手繪製在主時間軸,還是程式產生的「顯示物件」,都會被掛載在MainTimeline底下:

主時間軸的架構

主舞台上的動態文字欄位的實體名稱分別叫做stage_txt與root_txt,因此,底下的敘述將在stage_txt欄位中顯示"hello":

stage_txt.text = "hello";

或者,先建立一個明確指向「主時間軸」的參照,再透過它設定主舞台上的stage_txt欄位文字:

var r = this.root;
r.stage_txt.text = "hello";

舞台上的按鈕實體名稱叫做a_btn,底下的按鈕事件偵聽程式將在用戶按一下此按鈕時,分別透過stage與root參照設定stage_txt和root_txt欄位的文字:

a_btn.addEventListener(MouseEvent.CLICK, doClick);
function doClick(e:MouseEvent):void {
   // 指向「主場景」
   var c = this.stage.getChildAt(0);
   // 指向主場景上的 "stage_txt" 欄位
   var t = c.stage_txt;
   // 指向「主時間軸」
   var r = this.root;
   // 設定兩個動態欄位的文字
   t.htmlText = "<font color='#000000'>我來自 b.swf</font>";
   r.root_txt.text = "我是 B";
}

上面的程式執行結果如下:

程式執行結果

下圖是 a.fla 檔的舞台畫面,除了原有的欄位和按鈕之外,多了一個實體名稱為 b_mc 的影片片段。

a.fla檔的畫面

Flash Player可以載入多個.swf檔一起播放。此範例程式將透過Loader類別載入相同路徑底下的外部影片 b.swf 檔,並將它附加在 b_mc 實體中,影片的階層架構將變成:

透過Loader類別載入外部影片

請注意,載入的b.swf仍保有自己的「主時間軸」,但是不會有自己的stage物件。a.fla檔的關鍵影格程式如下:

// 載入b.swf檔
var fileURL:URLRequest = new URLRequest("b.swf");
var loader:Loader = new Loader();
loader.load(fileURL);
// 將載入的b.swf檔置入b_mc
b_mc.addChild(loader);
// 按鈕的事件偵聽程式
a_btn.addEventListener(MouseEvent.CLICK, doClick);
function doClick(e:MouseEvent):void {
   // 指向「舞台」的參照
   var c:DisplayObjectContainer = this.stage.getChildAt(0) as DisplayObjectContainer;
   // 指向舞台上的 "stage_txt" 欄位
   var t:TextField = c.getChildByName("stage_txt") as TextField;
   // 指向「主時間軸」
   var r = this.root;
   // 設定兩個欄位的文字
   t.htmlText = "<font color='#FF0000'>我來自 a.swf</font>";
   r.root_txt.text = "我是 A";
}

底下是按下a.swf檔裡的按鈕的結果:

按下A影片按鈕的結果

下面則是按下載入b_mc裡的b.swf檔的按鈕的結果,讀者可以看到,指向「舞台」(stage)的敘述,會把文字填入a.swf的欄位,而不是它自己內部的stage_txt。因為在執行階段,Flash Player只有一個stage物件

程式執行結果

Posts created 483

66 thoughts on “ActionScript 3.0裡的stage(舞台), root和MainTimeline(主時間軸)

  1. 老師,猶記得你之前有教過使用imageready作無接縫的背景圖,但我筆記有點搞丟,所以可以請你再教我一次嗎?

  2. 老師好 我是買了你的書的讀者
    看到這篇補充真的很高興
    我有個疑問想請問老師 老師在這篇文章說this 和this.root 都是指向主時間軸
    旦為何有this.stage這用法 翻譯成中文 ,不就是 “時間軸.舞台”
    可是時間軸不是在舞台之下的一個物件嗎
    這樣不是彼此矛盾嗎
    看了這篇文章,這個問題一直困擾我很久
    可以請老師幫我解惑一下嗎感激不盡

  3. hi ben:

    this和this.root「都是指向主時間軸」這個說法,只有像範例影片一樣,把程式寫在主舞台的時間軸時才成立;在影片片段的時間軸中,this指的是該影片片段的時間軸。

    root和stage都是「顯示物件」的屬性,語法格式為「顯示物件.root」及「顯示物件.stage」。例如,假設舞台上有個叫做 “a_btn” 的按鈕,我們可以透過它來指向主舞台:

    a_btn.stage;

    同樣地,”this” 所代表的時間軸,也是一種顯示物件,因此可以用 “this” 替換上面的 “a_btn”。

    thanks,
    jeffrey

  4. 我也有有看其他的書都沒交代清楚
    謝謝老師的解答 讓我有茅塞頓開的感覺

  5. 趙老師您好,從Flash4開始就受到您的啟蒙,到現在一直受用。
    這次的AS3.0弄的我七葷八素,有個觀念一直解不開,希望老師能抽空幫忙學生解惑。

    我在場景上放了個影片片段,實體名稱叫 box
    在主時間軸上寫了上以下的程式
    trace(box.x) 這個可以抓到 box 的x座標
    trace(root.box.x)這樣寫就出現錯誤了

    若照老師的寫法改成
    var myRoot = this.root;
    trace(myRoot.box.x);這樣又可以了

    myRoot不就是this.root嗎? 為什麼直接寫 this.root.box.x就不行呢?
    其中的觀念我一直弄不清楚
    其他地方有看過另一種寫法
    trace( root[“box”].x); 這樣也行,我實在不解

    誠請老師解惑,感謝老師

  6. hi justin:

    “root.box.x” 的寫法沒錯,只是必須關閉ActionScript 3.0的「嚴謹模式」。方法是點選「發佈設定」面版裡的Flash設定項目中,「ActionScript版本」設定右邊的「設定」按鈕,再取消勾選其中的「嚴謹模式」按鈕即可。

    使用點(.)語法時,編譯器不會在編譯階段找尋root上是否有”box”實體,所以會出現「存取可能未定義屬性」的錯誤。相反地,[ ] 語法原本就是用在指定「動態命名」的物件,例如:

    var index = 1;
    // 控制 a1 實體的 x 座標
    this[“a” + index].x = 100;

    所以 root[“box”].x 敘述並不會出現錯誤。

    jeffrey

  7. 感謝老師很簡短又清楚的解答,我終於了解原因了,又查了一些嚴謹模式中相關的規定,有更多了解啦,今天可以好好睡覺了,感恩

  8. 老师您好,在as3下在b.swf里面需要得到a.swf里面的某个变量的值,该怎么办呢?在as2下_root.name就可以得到;b.swf里面的this.stage为什么是空呢?为什么不是包括b.swf的整个舞台呢?谢谢!

  9. hi xiongkun:

    this.stage指向「主舞台」,如果你要取用位於root里的时间轴变量,可以这麽写:

    this.stage.getChildAt(0).变量名;

    因为root是stage底下的一个物件。

    jeffrey

  10. 您好
    我無意間找尋煩惱的解答來到這裡,我想請教
    在正常情況下
    stage 都可以取得值…比如trace(stage);都可以取得舞台值..
    可是只要利用載入(Loader)的方法去載入某SWF檔…被載入的SWF檔裡面要是有寫到stage的話…
    一定會出現錯誤…因為stage一定是空值(null)…所以一定會跑出TypeError: Error #1009: 無法存取 Null 物件參考的屬性或方法。

    您文章也提到說被載入的物件不會有第二個舞台存在

    那我想問的是….要怎樣才能在載入時…讓被載入的SWF用到的stage不會是空值..而能正常執行呢?

    難道被載入的物件遇到STAGE時都只能直接寫數值嗎,這樣不太符合大多數的程式原則呢(因為直接寫值)

    麻煩您解決困惑…謝謝您

  11. hi katsumi:

    trace(stage)並不是取得舞台值,而是它的參照(reference),它不會是空值,一定會參照到Flash Player中的唯一一個stage物件。煩請參閱之前的討論留言。

    jeffrey

  12. 老师您好,前一段时间有个难题请教了老师,非常感谢!现在我又遇到了一个问题,希望能够请教下老师:Flash与其容器间的通讯是用ExternalInterface 的addCallback方法和call方法来实现的。我现在是C#与Flash交互的。在第一轮的时候,通过addCallback方法可以从C#到Flash的通讯,没有问题。但是第二轮的时候(就是游戏,第一局完了,转到第二局,处理都是一样的),同一个用addCallback关联的方法要执行两次,第三轮就要执行3次,不知道是什么原因?我想是不是在ExternalInterface 里面注册了多次?可是ExternalInterface 里面也没有提供删除注册的接口,而且从网上看到addCallback关联的方法执行完了是会删除的。不知道是不是有别的原因?谢谢老师!

  13. 謝謝老師兩天的教學,學到了以前未曾注意過的小細節,順利通過Rich Media Communication using Adobe Flash CS3,
    您的包裝袋理論,真的淺顯易懂,讓每工背景的我搞懂as3語法到底是在講什麼。

    Thanks again !

  14. 趙老師您好
    請教一下
    我再AS下了這一段 _root.all_main.main_con.title_mc.publishDate_txt.text = this.publishDate;
    去抓資料庫的publishDate欄位的時間
    但是在動態文字欄位顯示出來的日期月份會自動減1
    請問可能是什麼樣的問題
    改成ActionScript 3.0可以解決這個問題嗎
    或是有其他的解決方式
    謝謝

  15. 趙老師您好~我想請教一下~
    下面語法是照某書範例 打在新開檔案的主場景影格上

    var bubbleNum:int=300;
    var angle:Number=Math.random()*360;
    for (var i:int=0; i

  16. 對不起~我再重貼一次
    下面語法是照某書範例 打在新開檔案的主場景影格上
    但運作時產生錯誤
    var bubbleNum:int=300;
    var angle:Number=Math.random()*360;
    for (var i:int=0; iBubble
    基底類別->flash.display.MovieClip

  17. 老師不好意思好像太長的關係~我直接寄檔案給你看可以嗎?
    不知您是否會很忙~所以等你回應後再寄~謝謝~

  18. hi mada:

    應該是ActionScript程式語言中的特殊字元造成的,能不能麻煩你直接和那本書的作者聯繫?

    thanks,
    jeffrey

  19. 為何一定要透過變數設定呢?
    var r = this.root;
    r.stage_txt.text = “hello”; //這是對的

    this.root.stage_txt.text = “hello”; //這是錯的

  20. 因為變數r並沒有宣告資料類型。若要宣告資料類型,程式敘述要寫成:

    var r:MovieClip = MovieClip(this.root);
    r.stage_txt.text = “hello”;

    或者:

    MovieClip(this.root).stage_txt.text = “hello”;

  21. 自動引用通知: Kcchao: ActionScript
  22. 自動引用通知: Kcchao: Actionscript 3
  23. 老師您好
    如果A要載入B,
    var fileURL:URLRequest = new URLRequest(“b.swf”);
    var loader:Loader = new Loader();
    loader.load(fileURL);
    缷載時要寫loader.unload();
    如果想要在B.swf寫一個按鈕關閉掉自己,該怎麼做呢?

  24. hi ellen:

    請在影片A的主時間軸加入底下的程式碼:

    var fileURL:URLRequest = new URLRequest(“b.swf”);
    var loader:Loader = new Loader();
    loader.load(fileURL);
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, movieLoaded);
    function movieLoaded(e:Event):void {
    addChild(loader);
    // 偵聽自定事件 ‘UNLOAD_ME’
    loader.content.addEventListener(‘UNLOAD_ME’, unloadClip);
    }
    // 移除載入物件的函數
    function unloadClip(e:Event):void{
    e.target.removeEventListener(‘UNLOAD_ME’, unloadClip)
    loader.unload();
    removeChild(loader);
    }

    假設影片B上有個關閉鈕,其實體名稱為 close_btn,關閉影片時,透過發佈自訂事件UNLOAD_ME,即可讓影片a上的程式收到事件,進而執行卸除影片的任務:

    close_btn.addEventListener(MouseEvent.CLICK, doClick);
    function doClick(e:MouseEvent):void {
    // 發佈自定事件 ‘UNLOAD_ME’
    dispatchEvent(new Event(‘UNLOAD_ME’, true));
    }

    就這樣,have fun!
    jeffrey

  25. 老師你好:

    我想請教個問題,
    我在做一個很一般的有主、次選單的東西,
    但不曉得次選單怎麼控制主畫面跳特定影格…

    主場景”場景1″上有:

    主選單(影片)mainmenu   次選單(影片)subshow
      |           |
    mainmenutext       submenutext
                  |
                 btn1/btn2/btn3

    希望按btn1、btn2、btn3可以讓主場景跳特定影格,
    現在我把as3寫在btn1裡,
    因為看其他參考書都是用URL連結網址,好像沒問題,
    但我要上最上層的主場景跳影格好像不行,
    請問我應該要怎麼運用root還是stage來寫呢?

    不好意思,我是自學,
    看了很多東西怎麼做都不行,
    找到這篇文很開心,可是看了很多遍還是不太懂該怎麼做>”

  26. 請問你試過 parent 嗎?parent代表「上一層」,parent.parent代表「上上一層」。

    have fun!
    jeffrey

  27. 老師你好 :

    我想在按鈕上寫一個關閉整個swf的程市該如何寫呢?
    stop();
    import flash.system.fscommand;

    exit_btn.addEventListener(MouseEvent.MOUSE_DOWN, closeApp);
    function closeApp(event:MouseEvent):void
    {
    fscommand(“quit”);
    }
    我是這麼寫的

    但是不成功

    麻煩了

  28. fscommand()無法用在網頁的Flash Player外掛程式,你若直接雙按匯出的.swf檔,透過獨立播放器版本Flash Player執行,就能關閉了。

    have fun!
    jeffrey

  29. 請問老師
    在AS中,宣告變數的方法是 var 變數名稱 : 資料型態 = 變數值;
    但是我有看過這一種宣告法

    for (var i=1 ;i<10;i++)
    {
    this["mydata"+i]=false;
    }
    請問這種宣告的方法是正統嗎?但是宣告後maydata的資料型態為何?這種方法跟利用陣列來宣告有差別嗎?
    它的優點和缺點為何?通常會運用在哪?
    感謝

    1. 看到這程式敘述的第一個想法(目前的唯一看法)是,它很像Flash 4時代的Actions指令思維;當時的Actions沒有陣列語法,必須透過eval()函數模擬來存取序列命名的變數,例如:

      eval(“mydata” + i);

      現在已經有Array, ArrayCollection, Vector, Object及自訂類別等複雜型資料結構可用,我不知道為何要這樣寫。

      thanks,
      jeffrey

  30. 老師我還有一個疑問
    用動態產生元件後,我該如何去控制這些元件,例如以下產生10個enemyShow_mc影片後,我要怎麼一一去控制它們
    if (var i:int=0;i<10;i++) {
    var enemyShow_mc:enemy_mc=new enemy_mc();
    parent.addChild(enemyShow_mc);
    }

    感謝

    1. 我會在迴圈中加入設定物件唯一名稱的敘述,例如:

      for (var i:int=0;i<10;i++) {
      var enemyShow_mc:Enemy=new Enemy();
      enemyShow_mc.name = 'enemyShow' + i;
      parent.addChild(enemyShow_mc);
      }

      在迴圈之外存取動態建立的物件時,可採用getChildByName()方法,例如:

      var index:int = 0;
      var _mc:Enemy = parent.getChildByName('enemyShow' + index);

      thanks,
      jeffrey

  31. 老師您好
    我之所以這樣寫,是因為我只會這種方法,
    我很想使用陣列的方法,但是不知道要怎麼將物件寫入陣列。

    我想要嘗試寫飛機的遊戲程式,我利用動態產生子彈和敵人,要不斷的產生然後消失,之前我是將固定的物件數(例如10顆子彈)抓進舞台,然後使用變數來記錄這顆子彈的生命週期,可是遊戲變複雜以後感覺很亂。所以我才想用動態的方式來產生,但是卻又不知如何控制。
    請問老師比較正統的方式為何?是利用陣列嗎?要如何寫呢?
    感謝老師指導

    1. 就像掛載在真實飛機上的飛彈一樣,大致有兩種處置方式。一個是每次發射之後,持續追蹤飛彈的狀態,直到它擊中目標或者超過射程為止。這樣的方式需要記錄尚在運作中的飛彈,所以要使用陣列變數,類似這樣:

      // 宣告陣列
      var missiles:Array = [];
      :
      function onFire() {
      var m:Missile = new Missile();
      // 儲存飛彈
      missiles.push(m);
      :
      }

      另外還需要加上一個迴圈查看陣列中的每個飛彈元素的狀態。

      第二種處置方式,宛如發射具備自動導引功能的飛彈,也就是在發射之前設定好飛彈的目標和初始位置等參數後,主程式就不用理它,等到飛彈擊中目標或者超過射程時,飛彈將發出一個自訂事件訊息通知主程式,這時再讓主程式介入處理加分以及移除飛彈物件等的程序。你可以把像這樣的程式寫成自訂類別,或者放在飛彈物件的時間軸。

      thanks,
      jeffrey

  32. 老師您好
    請問偵測飛彈與飛機碰撞的程式是要寫在飛彈的時間軸還是飛機的時間軸?
    我的想法是如果偵測程式寫在飛彈上,那麼飛機是不是就要對應到陣列上,後不斷地偵測有沒有擊中飛機。
    反之,偵測程式寫在飛機上,那飛彈就要對應到陣列,同樣也不斷地偵測是否碰撞。

    那到底在哪裡比較好呢?
    感謝

    1. 無論如何,每個飛彈一定要循環偵測是否碰撞到任一敵機。假設每當畫面新增一架敵機,程式就將它記錄在enimies陣列,那麼飛彈內部的程式碼就要有個類似這樣的迴圈:

      var total:int = parent.enimies.length();
      for (var i:int=0;i<total;i++) {
      // 碰撞偵測
      var hit:Boolean = this.hitTestObject(parent.enimies[i]);
      :
      }

      thanks,
      jeffrey

  33. 老師您好
    我嘗試利用陣列變數來指定產生的敵機,並且在飛彈的時間軸偵測是否有和敵機碰撞,有的話就結束敵機的生命週期,並且刪除所對應的陣列。
    在這邊我有一個疑問,萬一敵機結束飛行前都沒有和飛彈發生碰撞,這時候我想結束敵機的生命週期並且刪除對應的陣列,這個偵測程式我寫在敵機的時機軸,可是這樣一來,我就不知道它所對應的陣列索引是幾號,就不知道怎麼刪除陣列。
    我在想是不是要額外做一個mc,在上面做迴圈偵測。

    請老師賜教

    1. 對,你也可以把敵機和飛彈分別放在不同的mc,並在它們的生命週期結束時將它們移除即可。在執行removeChild()方法之前,記得先移除所有該物件上的附加的事件,例如,假設飛彈元件註冊了Event.ENTER_FRAME事件,要先執行removeEventListener()方法將它移除,否則該事件和物件將會持續運作。

      thanks,
      jeffrey

  34. 老師您好
    我將敵機記錄在陣列,並監控敵機的狀態,然後在敵機超出舞台時,移除它,如下:
    for (var i:int=0; i480) {
    parent.removeChild(parent[“enemyArray”][i]);
    parent[“enemyArray”].splice(i,1);
    }

    可是這樣發生一個問題,例如全部陣列有10個,當移除第4個時、地5個時,那個第9、10個陣列就不存在了,當迴圈跑到第9、10個陣列要偵測時就會發生錯誤。不知要如何修改。

    請老師指導

    1. 將迴圈的索引數字改成從大到小遞減即可,例如:


      var lastIndex:int = enemyArray.length - 1;
      for (var i:int=lastIndex; i>0; i--) {
      removeChild(enemyArray[i]);
      enemyArray.splice(i,1);
      }

      你貼入的程式碼包含大於或小於符號,系統誤認為是HTML標籤,所以某些字會漏掉。

      thanks,
      jeffrey

  35. 老師您好:
    有個問題想請教您,我有一個主swf,他要去載入外部的子swf
    那個swf是一個小遊戲,而裡面遊戲的元件也都是使用程式去呼叫的,
    現在是有成功連結子swf,遊戲內的元件卻缺了兩三種,但有一些元件又能正常顯示出來,不知道這會是什麼問題?而如果單獨執行子swf,又都很正常 🙁

    1. hi summer:

      請先確認動態載入的影片檔採用的ActionScript版本是否和主影片檔一致,另外,也請確認動態載入元件的目標路徑和階層,這樣比較容易除錯。

      good luck!
      jeffrey

  36. 老師您好,
    我做個簡單的線段,寫在AS2.0可以顯示出線段,但寫在AS3.0卻不能了,我試著把嚴謹模式關掉依然一樣,請問老師要怎樣才能在AS3.0顯示出現斷呢? 😕

    _root.createEmptyMovieClip(“mc”, 1);
    with (_root.mc) {
    lineStyle(2, 0xFF00FF, 100);
    moveTo(50,415);
    _root.mc.lineTo(130, 30);
    _root.mc.lineTo(210, 150);
    }

    1. hi sadd:

      AS3.0和AS2.0的語法差異很大,像_root和createEmptyMovieClip()在AS3.0都不存在了。底下的AS3.0程式片段提供你參考:

      var sp:Sprite = new Sprite();
      sp.graphics.lineStyle(2, 0xFF00FF, 100);
      sp.graphics.moveTo(50,415);
      sp.graphics.lineTo(130, 30);
      sp.graphics.lineTo(210, 150);
      addChild(sp);

      thanks,
      jeffrey

  37. 老師您好,
    我要做個combobox下拉式選單,選單內有1、2、3、4、5,當我選到1時旁邊有顯示圖片,選到2時又有另外一張不同的圖片,以此類推下去,請問這個要怎麼做以及程式碼要怎麼寫呢?

    1. hi vincent:

      市面上許多ActionScript參考書籍都有類似的內容可供參考。

      good luck!
      jeffrey

  38. 老師您好,
    近來在寫一個能夠設計餐點的flash,
    在影格1佈置一個按鈕,
    點選後前往影格6,
    影格6會撥放一小段知道來到影格11,
    影格11會產生一個按鈕讓使用者新增想要選用的物件到舞台上,
    可是我在影格11碰到了以下錯誤訊息,
    TypeError: Error #1009: 無法存取 Null 物件參考的屬性或方法。
    at demo02_fla::MainTimeline/frame11()
    請問我該如何解決此問題並成功新增物件至舞台上,
    謝謝老師
    以下是我的程式碼:
    影格1:
    stop();
    orange_btn.addEventListener(MouseEvent.CLICK,go_6);
    function go_6(e:Event):void {
    gotoAndPlay(6);
    }
    影格11:
    stop();
    var orange:MovieClip = new orange_mc();
    var disk_money=60;
    var orange_price=30;
    orange_make_btn.addEventListener(MouseEvent.CLICK,make_orange);
    function make_orange(event:MouseEvent) {
    var orange:MovieClip = new orange_mc();
    orange.addEventListener(MouseEvent.MOUSE_DOWN,drag);
    orange.addEventListener(MouseEvent.MOUSE_UP,drop);
    orange.x=150;
    orange.y=150;
    disk_money+=orange_price;
    money.text=disk_money.toString();
    stage.addChild(orange);
    }

    function drag(event:MouseEvent):void {
    var move_target=event.target;
    move_target.startDrag();
    setChildIndex(move_target,numChildren-1);
    }
    function drop(event:MouseEvent):void {
    var move_target=event.target;
    move_target.stopDrag();
    if (move_target.hitTestObject(rm)) {//當物件移到垃圾桶上時移除物件
    event.target.parent.removeChild(event.target);
    event.target.removeEventListener(Event.ENTER_FRAME,drag);
    event.target.removeEventListener(Event.ENTER_FRAME,drop);
    if (move_target is orange_mc) {
    disk_money-=orange_price;
    money.text=disk_money.toString();
    }
    }
    }

    1. hi little boy:

      你的影片的影格11有以下物件嗎?
      orange_make_btn
      money
      rm

      另外,你的程式碼有兩個小地方有問題:

      function go_6(e:Event):void

      應該寫成:

      function go_6(e:MouseEvent):void

      第11影格裡的:

      stage.addChild(orange);

      要寫成:

      this.addChild(orange);

      addChild(orange);

      thanks,
      jeffrey

  39. 老師您好,
    謝謝老師回答我的問題,
    您提到的三個東西是有的,
    只是在不同圖層,
    已改掉問題,
    老師我的程式是不是因為要新增orange物件才被說是錯誤呢,
    如果是的話,
    我爬文有看到說,
    要先給舞台偵聽動作,
    是否是因為少了此步驟呢?
    謝謝老師

    1. 看樣子,應該是你沒有替元件庫中的”orange_mc”物件設定AS連結,所以程式才找不到它。

      thanks,
      jeffrey

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top