我正在制作一个文本冒险游戏,该游戏将始终在舞台上至少包含一些组件(用于用户输入的叙述和文本输入的文本区域)。因此,我通过Flash的WYSIWYG设计环境静态创建了这些组件。我分别给了他们实例名称“myTA”和“myTI”。我能够让我的主类(舞台的文档类)与它们交互(在运行时像打字机那样一次动态添加一个字符),但是同一个包中的其他类似乎无法识别舞台组件。以下是相关代码:
案例A,其中所有内容都发生在Main类中:
package {
public class Main extends MovieClip {
public var myTA:TextArea;
var displayedChar:String = new String();
var textToWrite:String = new String();
var i:int = 0; var intervalId:uint;
var done:int = 0;
public function Main {
setUpTA();
}
public function setUpTA(){
myTA.text = "" + playAtInterval("Hello Player!");
}
public function writeCharsSlowly(){
textToWrite = arguments[0];
displayedChar=textToWrite.substring(i,i+1);
myTA.appendText(displayedChar);
i++;
if (i == textToWrite.length) {
done = 1;
clearInterval(intervalId);
}
}
public function playAtInterval(theText:String) {
i = 0;
intervalId = setInterval(writeCharsSlowly, 100, theText);
}
}
}
案例B,Main调用第二类'TypeWriter'来处理打字机打印:
主:
package {
public class Main extends MovieClip {
public var myTA:TextArea;
public var myTI:TextInput;
var str:String = new String();
public function Main{
testTypeWriter();
}
public function testTypeWriter(){
typeW.playAtInterval("Hello Player");
typeW.addEventListener(MouseEvent.CLICK,testTypeWriter2);
typeW.addEventListener(KeyboardEvent.KEY_DOWN,inputEngine2)
addChild(typeW);
}
public function testTypeWriter2(event:MouseEvent){
if (myTI.text == "a") {
typeW.playAtInterval("yo");
} else {
typeW.playAtInterval("Greetings, I am a test...");
}
addChild(typeW);
}
public function inputEngine2(event:KeyboardEvent){
str = String.fromCharCode(event.charCode);
myTI.appendText(str);
}
打字机:
package {
public class TypeWriter extends MovieClip {
public var myTI:TextInput;
public var myTA:TextArea;
var i:int = 0;
var done:int = 0;
var intervalId:uint;
var displayedChar:String = new String();
var textToWrite:String = new String();
public function TypeWriter(){
///nothing here
}
public function writeCharsSlowly(){
textToWrite = arguments[0];
displayedChar = textToWrite.substring(i,i+1);
myTA.appendText(displayedChar);
i++;
if (i == textToWrite.length) {
done = 1;
clearInterval(intervalId);
}
}
public function playAtInterval(theText:String) {
i = 0;
intervalId = setInterval(writeCharsSlowly, 100, theText);
}
}
}
案例A有效,但是如果B Flash给我错误“错误#1009:无法访问空对象引用的属性或方法”并注意到TypeWriter中的第一行,我尝试在myTA上操作问题
除了文档类“了解”现有舞台组件之外,我怎样才能创建其他类?
谢谢,
CCJ
答案 0 :(得分:1)
我会为此推荐Service Locator Pattern。最天真的方法是创建一个包含公共静态变量的资源类。然后在文档类中将舞台实例分配给资源类中的相应静态变量。然后您可以在任何地方访问这些舞台组件。
var someTextArea = Resource.TA; //probably should rename to something more meaningful
对于一些更巧妙的东西,你应该阅读我链接的文章。
我认为这比依赖注入要好,因为构造函数注入会导致巨大的参数列表,因为你可能会向舞台添加更多的项目,而且我不太喜欢setter注入,因为很容易忘记设置它们。
修改强>
为了让它更清晰,我想我会添加一些代码:)
资源类
package
{
//TODO imports
public class Resource
{
public static var TA:TextArea;
public static var TI:TextInput;
}
}
文档类
//....setup function
Resource.TA = myTA; //myTA is the name of the instance on stage
Resource.TI = myTI;
Foo class
Resource.TA.x = 100;
//or
_myClassMemberVariable = Resource.TA;
_myClassMemberVariable.x = 100;
答案 1 :(得分:0)
我认为一些依赖注入将解决这个问题。实例化Typewriter
课程时,请将引用传递给myTA
和myTI
。例如:
public function Main{
testTypeWriter(this.myTA, this.myTI);
}
然后你的Typewriter
构造函数应如下所示:
public function TypeWriter(ta:TextArea, ti:TextArea){
this.myTA = ta;
this.myTI = ti;
}
这也有助于使您的应用程序不那么紧密耦合,例如,您可以重复使用不同文本区域和文本输入的Typewriter
类。
修改
将来可能对您有所帮助的一些额外信息:您可以通过根对象访问舞台元素。但这仅适用于已添加到显示列表的对象。假设Typewriter
表示显示列表中的对象,您可以像这样访问myTA
:
MovieClip(root).myTA
(如果这是您的文档类扩展的话,请将MovieClip
更改为Sprite
。
但是,由于似乎Typewriter
没有添加到显示列表中,我建议使用我的第一个依赖注入建议。
同时查看this page,它会讨论使用CasaLib从任何对象访问舞台。我个人还没有尝试过,所以这就是为什么它最终在这里; - )
答案 2 :(得分:0)
myTA和myTI实际上是在作者时间在舞台上还是动态添加?
在第一种情况下,只需为每个实例添加一个实例名称。然后为每个类添加一个变量
var main_mc : Main = root as Main;
You can then access the instances via
(假设这些是您选择的实例名称),所有内容都应该是类型安全的。main_mc.myTA
and main_mc.myTI
在动态情况下,只需确保在添加主要类时将其保存到每个类中。
另一种选择是让myTA和myTI的类在其构造函数中发送一个事件来宣告它们的存在。然后,主类可以监听这些并注册引用。
老实说,你将显示器与逻辑混合在一起。特别是阅读MVC和PureMVC。通过良好的设计,可以通过消息处理所有内容,并且实例不需要直接引用彼此。 IIRC,Moock的AS3书中有一章关于MVC(但它可能是他的AS2书)。
答案 3 :(得分:0)
他们将一直在舞台上的事实不应该阻止你为他们创建特定的课程。
根据您的游戏结构,您可以使用TextField创建MovieClip并将它们链接到Typewriter类,或者只是为TextField创建一个类并使用Events来修改文本内容。
您正在使用外部类,因此没有理由在Flash CS中保留任何类型的逻辑。
答案 4 :(得分:0)
要清楚。在编写舞台时,您实际上是指flash文档的文档类。 Stage是一个类,每个已添加到displaylist的实例都可以访问。
我会将文本字段传递给需要更新它们的类。
var tw : Typewriter = new Typewriter();
tw.inputField = myTI;
tw.textArea = myTA;
或者
var tw : Typewriter = new Typewriter(myTI, myTA);