Actionscript 3 如何从另一个类访问一个类?
我有两个班;我的主课和一个叫BlockPlace的课。我想用我的主类来运行BlockPlace,但由于某些原因它不起作用。我尝试更改这两个代码,但只会导致错误。我知道代码是有效的,因为我在时间线中测试了它。我应该重组整个事情还是有不同的解决方案?以下是我的课程: 主类:Actionscript 3 如何从另一个类访问一个类?,actionscript-3,Actionscript 3,我有两个班;我的主课和一个叫BlockPlace的课。我想用我的主类来运行BlockPlace,但由于某些原因它不起作用。我尝试更改这两个代码,但只会导致错误。我知道代码是有效的,因为我在时间线中测试了它。我应该重组整个事情还是有不同的解决方案?以下是我的课程: 主类: package { import flash.display.*; import source.map.*; public class Main extends MovieClip{
package
{
import flash.display.*;
import source.map.*;
public class Main extends MovieClip{
public function Main()
{
BlockPlace();
}
}
}
package source.map{
import flash.display.MovieClip;
import flash.display.Stage;
public class BlockPlace extends MovieClip{
public function BlockPlace(){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
街区:
package
{
import flash.display.*;
import source.map.*;
public class Main extends MovieClip{
public function Main()
{
BlockPlace();
}
}
}
package source.map{
import flash.display.MovieClip;
import flash.display.Stage;
public class BlockPlace extends MovieClip{
public function BlockPlace(){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
更改:
BlockPlace()代码>
致:
var blockPlace:blockPlace=new blockPlace()代码>
您需要实际实例化它。更改:
BlockPlace()代码>
致:
var blockPlace:blockPlace=new blockPlace()代码>
您需要实际实例化它。我看到了一些问题,这可能解释了您看到的行为
首先,您调用它就像是一个函数,而不是构造函数
如果要静态引用此函数,则需要稍微更改:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public static function create(stage:Stage){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用以下命令调用它:
BlockPlace.create(stage);
请注意,该类不再扩展MovieClip,并且该方法被标记为静态,这意味着它可以直接从该类引用,而不需要该类的实例。还请注意,函数签名已更改。它现在接受一个参数——stage——从外部传入
使用这种方法,您可以将Main
实例中的stage引用提供给这个实用程序函数来执行一些工作。这可能是解决您的问题最直接的方法
相反,如果您想将其作为一个扩展MovieClip的类来保留--这意味着什么--那么您需要实例化该类的一个实例:
var blockPlace:BlockPlace = new BlockPlace();
然后,你需要把它放在圣人身上:
this.addChild(blockPlace);
但是你在舞台上还是有点鸡毛蒜皮的问题。实例化类时,在其构造函数中引用的是stage
属性。然而,在构建的这一点上,它还没有被添加到任何附加到stage的DisplayObjectContainers
。因此,stage
属性将为null
。因此,您不能向stage添加任何内容或获取stageHeight
或stageWidth
您需要等待,直到这种情况发生——直到addChild(blockPlace)
得到评估后才会发生这种情况
因此,您需要重新考虑一下您的架构,您可以将逻辑移动到另一个函数中,一旦您确定它已连接到后台,该函数将被您显式调用。比如:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
}
public function initialize():void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用类似于:
var blockPlace:BlockPlace = new BlockPlace();
addChild(blockPlace);
blockPlace.initialize(); // safe to call because its on the stage now given that `this` is on the stage
然而,一种更惯用的方法是使用事件来等待电影剪辑添加到舞台上,然后执行一些工作。例如:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
this.addEventListener(Event.ADDED_TO_STAGE, stageAvailable);
}
private function stageAvailable(e:Event):void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
注意,构造函数现在设置了一个事件监听器,它说,“当我被添加到stage时,去做另一个名为stageAvailable
的函数中的工作。”
您必须注意一些小的注意事项,显示对象可以直接在舞台上构建——flash IDE就是这样做的。因此,事件不会为这些项目触发,因为当事件附加时,它已经在舞台上,因此不会触发。最具防御性的写作方式是:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
if(stage) stageAvailable()
else this.addEventListener(Event.ADDED_TO_STAGE, stageAvailable);
}
private function stageAvailable(e:Event = null):void {
if(event) this.removeEventListener(Event.ADDED_TO_STAGE, stageAvailable);
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
在构造函数中,它检查是否有stage,如果有,则立即调用该函数。如果没有,那么它将设置一个侦听器,以等待这种情况发生。然后在处理程序中,如果它是因为某个事件而被调用的,则在它自身之后进行清理并删除侦听器。我看到了一些问题,这可能解释了您看到的行为
首先,您调用它就像是一个函数,而不是构造函数
如果要静态引用此函数,则需要稍微更改:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public static function create(stage:Stage){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用以下命令调用它:
BlockPlace.create(stage);
请注意,该类不再扩展MovieClip,并且该方法被标记为静态,这意味着它可以直接从该类引用,而不需要该类的实例。还请注意,函数签名已更改。它现在接受一个参数——stage——从外部传入
使用这种方法,您可以将Main
实例中的stage引用提供给这个实用程序函数来执行一些工作。这可能是解决您的问题最直接的方法
相反,如果您想将其作为一个扩展MovieClip的类来保留--这意味着什么--那么您需要实例化该类的一个实例:
var blockPlace:BlockPlace = new BlockPlace();
然后,你需要把它放在圣人身上:
this.addChild(blockPlace);
但是你在舞台上还是有点鸡毛蒜皮的问题。实例化类时,在其构造函数中引用的是stage
属性。然而,在构建的这一点上,它还没有被添加到任何附加到stage的DisplayObjectContainers
。因此,stage
属性将为null
。因此,您不能向stage添加任何内容或获取stageHeight
或stageWidth
您需要等待,直到这种情况发生——直到addChild(blockPlace)
得到评估后才会发生这种情况
因此,您需要重新考虑一下您的架构,您可以将逻辑移动到另一个函数中,一旦您确定它已连接到后台,该函数将被您显式调用。比如:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
}
public function initialize():void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
然后使用类似于:
var blockPlace:BlockPlace = new BlockPlace();
addChild(blockPlace);
blockPlace.initialize(); // safe to call because its on the stage now given that `this` is on the stage
然而,一种更惯用的方法是使用事件来等待电影剪辑添加到舞台上,然后执行一些工作。例如:
package source.map{
import flash.display.Stage;
public class BlockPlace {
public function BlockPlace() {
this.addEventListener(Event.ADDED_TO_STAGE, stageAvailable);
}
private function stageAvailable(e:Event):void {
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
请注意,构造函数现在设置了一个事件侦听器