早上好,
我的问题听起来很愚蠢,过去两周我一直在读书。但可以使用一些指导。
我有一个flash项目,基本上是一个支持幻灯片放映。在舞台上我有以下内容:
main_mc(实例名称= images_mc)=包含“图片”的movieclip
ui1(实例名称= ui1_mc)=允许用户在图片上绘图的用户界面(启用绘图时)
ui2(实例名称= ui2_mc)=激活选择图片上的不可见命中区域(按钮),当点击命中区域时,我们跳转到main_mc中的另一张图片。
我在时间轴上完成了所有这些,但是我将代码更新为OOP。
我正在试图弄清楚如何存储对实例(images_mc等等)的引用,所以我可以从不同的类文件中控制它们。我发现很容易从文档类控制实例,而不是从不相关的类文件控制。
示例:images_mc.stop();在文档类中工作;但Movieclip(Parent).images_mc.stop()似乎不能在任何类文件中工作。(例如ui2类文件);
我应该创建一个名为References的类,并将变量传递给其他不相关的类文件(我能看到一个例子)吗?基本上这种情况下的最佳做法是什么?我不想通过代码将实例添加到舞台,因为一切都按原样定位。老实说,我没有预见到在这个项目中需要以编程方式添加任何东西,所以引用已经存在的实例非常重要。我想以“正确的方式”完成这项任务,任何帮助都将不胜感激。
答案 0 :(得分:0)
您的问题基本上显示了OOP和结构编程之间的区别。学习OOP是一个很好的决定,你会喜欢它,它会让你的生活更轻松。
我会尽量不去理你这个理论 - 我相信你以后会知道 - 但是帮助你完成你的项目:
首先,我想说对每个综合UI资产都有一个单独的类是一个好习惯。这不是针对每个图像或按钮,而是针对具有相同目的的对象组,例如:幻灯片放映,登录表单,控件,声音/音量按钮等。此类应仅包含与呈现图形和用户相关的逻辑相互作用。这是一项名为Model-View-Controller的原则的一部分。您可以稍后了解,但关键是您应该为images_mc和相关对象设置单独的类。在文档类中创建它,并为其提供文档阶段的引用。
slideShow = new SlideShow(this);
和
package {
import flash.display.MovieClip;
public class SlideShow {
private var images : MovieClip;
public function SlideShow(stageRef : MovieClip) {
images = stageRef['images_mc'] as MovieClip;
}
}
}
注意:我称之为文档阶段的不是Stage,它是第一个MovieClip。
你应该在OOP中遵循的第二个原则是encapsulation。长话短说,没有人应该知道你的幻灯片中有一个images_mc,你可以播放或停止它。相反,其他对象应该知道您可以在不知道细节的情况下播放或停止整个幻灯片放映。因此,你应该在SlideShow类中有这样的公共函数:
public function stopShow() : void {
images.stop();
}
如果你想从文档类中停止节目,只需调用
slideShow.stopShow();
注意:如果您的类继承自MovieClip,请注意不要命名play()或stop()等方法(如果您不想覆盖它们,但这是另一个故事)。 < / p>
现在,在访问/控制所有这些类时,有几种方法:
MVC就是其中之一:保留Controller中的大多数引用(可以是文档类)并让它决定做什么。让你的View类(如SlideShow)在舞台引用上调度事件(文档阶段实际上是一个MovieClip,这意味着它也是EventDispatcher)并让Controller监听它们,然后调用类似stopShow()的方法。
如果您不熟悉事件,并且整个Controller概念让您感到困惑,只需将对所有类的所有引用都放到一个特殊类中,并将其传递给您创建的每个类的构造函数。这是一团糟,但对于像你的幻灯片一样的小项目应该没问题。
修改强>
事件处理:
对于幻灯片放映来说可能太复杂了,但这是在大型项目中如何做到这一点。假设您在Ui2类中有表单字段和按钮,并且您希望在提交时发送包含表单字段中文本的自定义事件:
private var formField : TextField;
private var submitBut : SimpleButton;
并在构造函数中:
formField = stageRef['form_txt'] as TextField;
submitBut = stageRef['submit_but'] as SimpleButton;
submitBut.addEventListener(MouseEvent.CLICK, buttonHandler);
然后你需要handler属性来调度将从表单字段中携带文本的自定义事件:
private funstion buttonHandler(e : MouseEvent) : Void {
var customEvent : CustomEvent = new CustomEvent(CustomEvent.FORM_SUBMIT);
customEvent.text = formField.text;
this.dispatchEvent(customEvent); //check the note
}
注意:现在您要从此类调度它,因此请扩展EventDispatcher。最终你可以从stageRef发送它(将它存储在构造函数中以便在处理程序中使用)。
然后在控制器/文档类中听取:
ui2.addEventListener(CustomEvent.FORM_SUBMIT, doSomething);
自定义事件应如下所示(为简单起见,没有设置者/ getter):
package {
import flash.events.Event;
public class CustomEvent extends Event {
public static const FORM_SUBMIT: String = "form_submit";
public var text : String;
public function CustomEvent (type : String) {
super(type);
}
}
}
这只是一个开始,不断学习,祝你好运。
答案 1 :(得分:0)
有很多方法可以解决这个问题。一种方法是使用静态变量。看看这个例子:
这个例子有点复杂,因为它使用私有变量和getter。如果你不想这么安全,你可以在你的doc课程中这样做:
public static var display:MovieClip;
...然后在文档类的构造函数中:
MyDocClass.display = this;
这意味着您现在可以说:
MyDocClass.display.myClip
我通常称我的doc类为Main。所以你最终得到:
Main.display.myClip
如果您还不知道它们是什么,那么静态变量很感兴趣。正则变量存在于类实例中 - 假设我们有两个类,每个类都有一个属性时间:
var day1:Day = new Day();
day1.time = "morning";
var day2:Day = new Day();
day2.time = "night";
在第1天足够简单,时间var是“早晨”,在第2天,时间var是“夜晚”。这些变量对于它们的实例是唯一的。静态变量不是这种情况 - 类本身存在静态变量。像这样:
// inside the class
public static var YEAR:String = "1980";
// outside the class
Day.YEAR;
静态变量很强大,但它们也很危险。它们是全局变量并且使用全局变量可以减弱导致难以管理的代码。