这是我的问题。在我的文档类TowerDefenseGame.as中,我定义了一个变量Turrent1Flag:
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldType;
public class TowerDefenseGame extends MovieClip
{
public var Turrent1Flag==0;
}
public function TowerDefenseGame()
{
......
}
现在,在另一个类Turrent1Button.as中,我需要创建一个鼠标单击事件,Turrent1Flag被设置为1:
package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.display.Sprite;
import TowerDefenseGame;
public class TurretButton1 extends MovieClip
{
public var ButtonBase:Sprite=new Sprite();
public var TurretBase:Sprite=new Sprite();
public var Gun:Sprite=new Sprite();
public function TurretButton1()
{
......
this.addEventListener(MouseEvent.CLICK, MouseClick);
}
public function MouseClick(event:MouseEvent):void
{
MovieClip(root).Turret1Flag = 1;
}
嗯,这不起作用。我使用的是Adobe Flash cs6,它说无法访问该值。有人知道怎么做吗?
答案 0 :(得分:1)
试试这个:
private static var _instance:TowerDefenseGame;
public static function get instance():TowerDefenseGame { return _instance; }
public function TowerDefenseGame()
{
_instance = this;
}
public function MouseClick(event:MouseEvent):void
{
TowerDefenseGame.instance.Turret1Flag = 1;
}
答案 1 :(得分:1)
因此,首先,AS3很难让你习惯于在AS2中习惯这样做,以便更好地实现面向对象的实践。当您在班级之间保持高而紧的墙壁时,更换A级变得更容易,而对B级没有任何影响.B级只知道进入A级房屋的“官方”方式的门窗,所以如果你移动沙发也没关系。您还可以非常轻松地将A类替换为具有类似门窗的C类。
当您通过引入全局状态到达墙壁时,您不能在不更改A类的情况下将C类替换为C类,因为A类直接引用B类并且确切知道沙发的位置。
处理此问题的一种方法是通过Inversion of Control(IoC)。因此,对于我们的房子,沙发可能是从外面供应的,并且提供的任何组件都可以保留它的参考,因此无论在房子的哪个地方它都可以进入沙发。因此,您可以选择创建TurretButton
并将其传递给拥有该TowerDefenseGame
的人,而TurretButton
保留对它的引用并直接侦听它,更改其自己的标志响应点击。
查看您的代码,您可能不需要那么远,因为我没有看到任何迹象表明您的TurretButton
实际上是嵌套的。在这种情况下,你可以直接听它,无论你是在舞台上创建它还是通过代码创建它(我不是它的粉丝)。如果您在IDE中使用舞台并且它存在于舞台上,那么只需创建SimpleButton
类型的公共变量(或者您可以使用TowerDefenseGame
,因为您不再需要特殊这里的类根据您显示的代码而定。该实例将在{{1}}的构造函数中提供。只需向其添加事件侦听器,然后要更改的侦听器和变量位于同一范围内。问题,你试图解决的问题从未存在过 - 你只是从一个过于复杂的事物的角度来看问题。
事实上,如果您的代码 以未显示的方式嵌套,您可以使用ActionScript 3的事件系统,这是非常棒的,可以在不引入直接耦合的情况下处理问题而无需通过代码创建按钮并将其下推到使用它的位置。一种方法是只监听任何鼠标点击(因为这是一个冒泡事件)并查看点击的内容。另一种解决方案是从按钮生成自定义事件,然后您可以从顶层收听以更改标志。这看起来像是:
package view.button { public class TurretButton extends MovieClip { public function TurretButton() { super(); mouseChildren = false; addEventListener(MouseEvent.CLICK, broadcastTurretEvent); } protected function broadcastTurretEvent(e:Event):void { dispatchEvent(new Event('turretClicked', true));//the true parameter makes it bubble } } }
然后你的塔级看起来像
package { public class TowerDefenseGame extends MovieClip { //the fact that you're calling it Turret1Flag suggests you're going to have more than 1 protected var turretFlags:Array /*of Boolean*/ = [false, false]; //your turret button instances //doesn't show nesting, this is just to indicate that //these are named instances so you know how what they're called //they could be nested at any level public var turret1:TurretButton; public var turret2:TurretButton; //...etc. public function TowerDefenseGame() { super(); addEventListener('turretClicked', onTurretClicked); } protected function onTurretClicked(e:Event):void { //you can also just extract the number and do the math //to get the correct array index switch(e.target.name) { case 'turret1': turretFlags[0] = !turretFlags[0]; break; case 'turret2': turretFlags[1] = !turretFlags[1]; break; } } } }
请注意这种程度如何。您不必为每个按钮设置不同的类来更改每个单独的标志。在没有大量代码更改的情况下添加更多按钮也很容易。您可以进一步采用此解决方案并创建一个自定义事件,该事件具有一个属性,该属性显示单击了哪个按钮,您可以通过依赖注入等提供用于按钮的值。
我还在我的代码中假设标志应该是布尔值,并且它们在第一次单击时打开并在第二次单击时关闭,等等。您可以采用相同的想法并将其更改为,例如,每次点击都会增加。我怀疑你实际上并不想做你的代码所显示的内容,只需在第一次点击时将其打开,然后永远保持开启状态。
另一个注意事项是,如果您认为您可能希望在较长期内在AS3中进行编码,则应该了解AS3中使用的编码约定。其中之一是类名以大写字母开头,但属性和方法不是。
答案 2 :(得分:0)
进入一切可能不是一个很好的习惯,但静态变量看起来就像在这里一样。
public class TowerDefenseGame extends MovieClip
{
public static var Turrent1Flag = 0;
}
在Turrent1Button.as:
public function MouseClick(event:MouseEvent):void
{
TowerDefenseGame.Turret1Flag = 1;
}