要了解這個問題就要先對flash中的顯示對象結構有一個大概的了解:
?
第一級:舞臺;
?
第二級:當前SWF;
?
第三級:各種容器及可視對象(如:文本框,位圖……);
?
以此類推…………
?
stage:
?
其中舞臺(Stage)是最根本的容器,包含當前SWF的所有顯示對象,每個flash程序只能有一個舞臺容器。
?
所有顯示對象的stage屬性指向舞臺。
?
root:
?
在舞臺下面的也是一個容器,被稱作當前SWF主類的實例(注:AS3.0中所有容器直接或間接繼承自DisplayObjectContainer類),在AS3.0中,每一個SWF都和一個類相關聯,這個類就稱為SWF的主類,如果沒有設定文檔類,則MainTimeline類(注:MainTimeLine是MovieClip的子類)就是主類。而root就指向當前SWF主類的實例(注:在AS2.0中,_root.指代絕對路徑)。
?
this:
?
this關鍵字持有對當前對象的引用,編譯器將this關鍵字加在類中每一個調用實例屬性和實例方法的地方。
?
this關鍵字常見使用情況:
?
(1)向第三方提供對象自身的引用。
?
(2)與return結合,在類方法中返回自身的引用。
?
(3)和局部變量,方法參數,靜態屬性同名時,加上this關鍵字明確指定使用實例屬性。
?
1.STAGE是根,是最頂層的容器!可以通過STAGE的任何子容器或顯示
?
對象以DisplayObjectContainer.stage(需注意的是stage是小寫,如果在時間軸上trace(stage.width)是正確的,如果寫成trace(Stage.width則會報錯))或DisplayObject.stage訪問到Stage類的
?
唯一實例stage.就連主時間軸也是stage容器的子容器。
例如。你在主時間軸上寫上代碼:trace(this);輸出的是什么呢?因為你是在主
?
時間軸上寫的。所以返回的是一個對象:MainTimeLine,也就是主時間軸了。同
?
志們可以試試在主時間軸上寫:trace(this.stage);當然輸出的是Stage對象了
?
。也可以省略不寫this,直接寫:trace(stage);輸出的還是Stage對象。為了更清
?
楚,在主時間軸上寫上代碼:trace(stage.getChildAt(0));看看輸出的是什么
?
呢?如果是MainTimeLine的話,就更能說明問題了,主時間軸是stage容器的第
?
一個子容器,在索引位置0上。
?
2.stage.width 與stage.stageWidth
?
我記得width相當于sprite的width,是stage上所有child構成的范圍的寬(
?
沒東西width就是0),stageWidth就是舞臺的寬
其實這個問題很簡單,但是你為什么不自己用個兩個文本框在各種不同的情況下
?
顯示一下這兩個的值呢。
?
Java代碼
1.stage.addEventListener(MouseEvent.CLICK,update);??
2.?
3.function update(e)??
4.{??
5.?? txt.text = String(stage.stageWidth);??
6.?
7.?? txt1.text = String(stage.width);??
8.}?
stage.addEventListener(MouseEvent.CLICK,update);
?
function update(e)
{
?? txt.text = String(stage.stageWidth);
?
?? txt1.text = String(stage.width);
}
?
?
?
自己看看吧,改變一下舞臺的大小,場景上的東西,還有環境,縮放,
?
自己試出來的結果永遠比別人講的來的清晰
?
?
?
3.這兩天看AS3 cookbook和AS3的幫助文檔,里面很多代碼執行后都會出現“TypeError: Error #1009: 無法訪問空對象引用的屬性或方法。”這個錯誤。幾經周折,才知道解決辦法:使用addEventListener( Event.ADDED_TO_STAGE, enterDLHandle ),把要用的stage代碼放到enterDLHandle里面,就沒問題了。不知道有沒有其他解決方法,知道的說聲啊~
?
在經典論壇上提問這個問題,終于有人做出全面回答了,在此感謝zjs35
?
首先要明白stage是什么意思,stage是顯示對象的一個引用舞臺的屬性,如果顯示對象不在顯示列表中,即沒有用addChild()添加,stage等于null,你的問題就在這里。
使用stage有下面幾種方法:
1、文檔類的構造函數中可以直接使用stage屬性
2、非文檔類可以通過參數傳遞到類里面。
class Test extends Shape
{
function Test(stage:Stage)
{
}
}
3、不想傳遞參數時,要注意代碼的順序。
class Test extends Shape
{
function Test()
{
}
functon useStage()
{
trace(stage)
}
}
這樣使用
var test=new Test()
test.useStage()//null,你的問題出在這里
addChild(test)//添加到顯示列表后,就可以使用stage屬性。
test.useStage()//[object Stage]
總之,理解stage是顯示對象的屬性,位于顯示列表中的顯示對象的stage才引用舞臺
?
AS3.0 中root和parent的用法
一、首先看一下在單個swf中的用法:
在主舞臺上的幀上寫下如下代碼:
var xxx="this is root";
新建一個MC,給它一個實例名稱test_mc1,在test_mc1中的幀上寫下如下代碼:
trace(parent["xxx"]);
trace(root["xxx"]);
trace(root["test_mc1"].alpha)
最終的輸出為:
this is root this is root
1
如果在test_mc1中在建立一個實例名稱為test_mc2的movieclip,如何trace它的alpha呢:
trace(root["test_mc1"].test_mc2.alpha);
最終輸出“1”。
?
二、如果是兩個swf,他們之間是怎樣操作的呢:
新建兩個flash文件,命名為a1和a2,
在a1.fla中的幀上寫下如下代碼:
var xxx="this is root";
var myloader=new Loader();
myloader.load(new URLRequest("a2.swf"));
addChild(myloader);
在a2.fla中建立一個動態文本框,實例名稱為txt;
在幀中寫下如下代碼:
txt.text=parent.root["xxx"];
分別發布兩個flash文件,然后運行a1.swf,看到其顯示結果為"this is root";
在發布a2.swf是你會看到:
ReferenceError: Error #1069: 在 flash.display.Stage 上找不到屬性 xxx,且沒有默認值。
at a2_fla::MainTimeline/a2_fla::frame1()
不用去理它,因為他不是通過a1.swf load到場景,所以找不到xxx這個參數。
這里的第一個parent是a1.swf中的myloader,myloader的再上一級才能找到xxx這個參數,這里也可以寫成parent.parent["xxx"]。
我想通過這兩個例子應該比較清楚如何在AS3中使用root和parent了。
?
但as3的root在類型轉換上出現的問題具有普遍性
as3的文檔類通常使用Sprite或MovieClip,但實際上繼承DisplayObject的類,在理論上均可做文檔類
故adobe在設計root時,
設計為root:DisplayObject
?
很多時候需要使用root as MovieClip來使用gotoAndStop一類腳本 這在前一篇文章中(AS2中的_root,在AS3的用法)已經說過了
?
我通過這段時間對 AS 3.0 的研究, 發現下面這個很有價值的問題, 所以今天寫下來, 給大家分享.
?
?
Action Script 2.0 中 this 的用法:
在 Flash 里拖一個 Button 組件到舞臺, 給這個 Button 實例取個名字叫 b1, 在 b1 身上添加代碼:
?
[復制到剪貼板]CODE:on (click) {
this.label = "你點了這個按鈕一下";
}
?
這里的 this 指的就是 Button 對象 b1, 點擊 b1 之后, b1的標簽馬上變為"你點了這個按鈕一下". 也就是說, 在 AS 2.0 中 this 指的是使用該方法的當前對象.
?
?
Action Script 3.0 中 this 的用法:
在 Flex Builder 的 Design 模式下拖一個 Button 到舞臺, 給這個實例取名, 也就是設置 id 的值, 還是取名 b1, 然后回到 Source 模式下, 添加代碼:
?
[復制到剪貼板]CODE:<mx:Button id="b1" click="this.label="你點了這個按鈕一下";"/>
?
當你運行之后就會發現, 點了 b1 之后, b1 的標簽并沒有任何改變, 這是因為, this 關鍵字并不是指的 b1 這個按鈕, 而是指的 Application 的實例, 所以, 點了按鈕之后, 實際上企圖修改的是 Application 的標簽, 而不是 b1 這個按鈕的標簽.
?
因此正確的代碼應該是:
?
[復制到剪貼板]CODE:<mx:Button id="b1" click="b1.label="你點了這個按鈕一下";"/>
?
原因是這樣的: 每個 MXML Application 在保存以后, 實際上都被編譯成了一個 AS 3.0 的類(類名跟 MXML 文件名相同), this 指的是這個類本身的實例, 所以 this 的用法跟 AS 2.0 大相徑庭, 完全兩碼事.
?
?
總之, 在 AS 3.0 中, this 永遠是指當前頂級類的一個實例(對象), 細分下面幾種情況:
?
1. 在 MXML Applcation 文件中, this 永遠指的是 Application 的實例;
?
2. 在 MXML Component 文件中, this 永遠指的是 Componet 的實例, 也就是這個文件中根元素的實例;
?
3. 在 Action Script Class 文件中, this 永遠指的是這個 Class 的實例;
?
4. 如果 MXML Component 和 Action Script Class 都被導入到 MXML Applcation 中, 在這個 MXML Applcation 里 this 關鍵字依然還是指 Application 的實例, 而不是其中任何子元素的實例.
?
好了, 這就是我最近研究 AS 3.0 發現的一個典型問題, 希望對大家有幫助 :-)
?