AS3:只允许一定数量的某种类型的对象放入一个Array中
我想找到一种方法,只允许某些对象进入其类名中具有特定单词的数组。或者至少找到做这样的事情的最佳方法。这是详细信息。我有一个数组,用于存储放入购物车的所有对象。
function addProductToArray (e:MouseEvent):void{ currMC = (e.target as MovieClip); myCart.itemsInCart.push(currMC); trace(myCart.itemsInCart);}
例如,如果我放下一个 [object BreadGrain] 和一个 [object PastaGrain]。
trace(myCart.itemsInCart);// 将跟踪 [object BreadGrain],[object PastaGrain]
。
很简单,没有任何问题。但是,如果我只想允许 2 个类名中带有“Grain”的对象进入数组,我该怎么办?我想这样做,以便用户只能将每种类型的 2 个食物放入“购物车”。食物的类型有谷物、水果、蔬菜、肉类等,我已将食物的类型附加到类名的末尾,希望这样我可以用它来检测它是什么类型的食物并阻止它被添加超过限制并显示错误。即“您已经有 2 种谷物产品”。
我希望这是有道理的。不管怎样,我发现这在一定程度上效果很好:
if (currMC is BreadGrain) {
myCart.itemsInCart.push(currMC);
} else {
// error message code here
}
但是我有几种产品,我不想为它们全部编写 if/else 或 switch 语句。我希望通过类似以下内容动态地执行此操作:
//this is an example of the logic
if (currMC classNameContainsTheWord "Grain" AND myCart.itemsInCart DoesNotContainMoreThan 2 Grain Objects) {
myCart.itemsInCart.push(currMC); } 别的 { //这里是错误信息代码 。
我很困惑 即使只是一句“伙计,你做错了”也会有帮助。谢谢。
I want to find a way to only allow certain objects into an array that have a certain word in thier class name. Or at least find the optimal way of doing something like this. Heres the details. I have an Array that stores all the objects dropped into a cart.
function addProductToArray (e:MouseEvent):void{
currMC = (e.target as MovieClip);
myCart.itemsInCart.push(currMC);
trace(myCart.itemsInCart);}
If, for example, I drop an [object BreadGrain] and a [object PastaGrain].
trace(myCart.itemsInCart);// would trace [object BreadGrain],[object PastaGrain]
.
Easy, no problems there. But what do I do if I only want to allow 2 objects with "Grain" in their Classname into the array? I want to do this so that the user can only drop 2 of each type of food into the 'cart'. The types of food are Grain, Fruit, Vegetable, Meats etc and I've appended the type of food to the end of the Classname, hopefully so that I can use it to detect what type of food it is and stop it from being added over the limit as well as displaying an error. i.e "You already have 2 Grain products".
I hope that makes sense. Anyway, i've found that works well to a degree:
if (currMC is BreadGrain) {
myCart.itemsInCart.push(currMC);
} else {
// error message code here
}
BUT I have several products and I don't want to have to write a if/else or switch statement for them all. I was hoping to do this dynamically with something similar to:
//this is an example of the logic
if (currMC classNameContainsTheWord "Grain" AND myCart.itemsInCart DoesNotContainMoreThan 2 Grain Objects) {
myCart.itemsInCart.push(currMC);
} else {
// error message code here
}
I'm stumped. Even just a "Dude, you are doing this all wrong" would help. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用 getQualifiedClassName 函数。然后,您可以尝试使用 RegExp 将字符串与特定模式进行匹配,或者您也可以仅检查类名是否包含某些子字符串。
也就是说,我认为更好的方法可能是使用公共基类或接口。
或者
然后,如果您使用基类:
或者,使用接口
如果这些对象是MovieClips,也许使用基类会不那么繁琐,因为否则您必须将对象转换回来任何时候您想要将它们添加到显示列表(或删除它们)时,都可以将其添加到
MovieClip
(或DisplayObject
)。顺便说一句,这是因为 Adobe 的某个人忘记包含一个IDisplayObject
接口,并让显示列表 API 接受实现此接口的对象,而不是接受无论如何都无法直接派生的半途而废的抽象类(又名 DisplayObject);这将使将显示对象视为接口变得更容易,但我离题了)。无论如何,无论是使用接口还是公共基类,您都可以使用 is 运算符进行验证,但您只需检查一种类型:Grain。
您还可以更进一步,使用 Vector 而不是大批。 Vector 的工作方式几乎与 Array 相同,但它是严格类型化的,因此您可以这样做:
如果您尝试添加不扩展/实现 Grain 的对象,您将收到编译时错误。
矢量可用于 Flash Player 10,但您需要 Flash CS4(如果您使用的是 Flash IDE;否则,我认为您至少需要 3.2 SDK 才能编译)。
You can get the class name of any object with the getQualifiedClassName function. Then you could try to match strings agains a certain pattern, with a RegExp or you could also just check if the class name contains some substring.
That said, I think a better approach could be using either a common base class or an interface.
or
Then, if you went with the base class:
Or, with the interface
If these objects are
MovieClips
, perhaps it's less tedious to use a base class, because otherwise you'd have to cast your objects back toMovieClip
(orDisplayObject
) any time you want to add them to the display list (or remove them). By the way, that's because someone at Adobe forgot to include anIDisplayObject
interface and have the display list API accept objects that implemented this interface instead of a half-assed abstract class that you can't derive directly anyway (a.k.a.DisplayObject
); this would have make it easier to treat display objects as interfaces, but I digress).Anyway, either with an interface or a common base class you could do your validation with the
is
operator, but you'd just have to check for one type: Grain.You could also take this further and use a Vector instead of an Array. A Vector works almost the same as an Array, but it's strictly typed, so you could do:
You'll get a compile time error if you try to add an object that does not extend/implement Grain.
Vectors are available for Flash Player 10 and you'd need Flash CS4, though (if you're using the Flash IDE; otherwise, I think you'd need at least the 3.2 SDK to compile).
嗯。我认为你需要一些更复杂的东西才能使其正常工作。您实际上是在问一个由两部分组成的问题:如何跟踪内容以及如何识别内容。我将从简单的部分开始,进行跟踪。
免责声明:我的 AS3 相当生疏,但至少理论应该是合理的,即使实现可能有点偏差。
首先,您想要定义每种食物类型的限制,因此:
然后,您想要记录添加到购物车的对象的数量
然后,当您添加新对象时,首先根据相关对象检查其类型数数。如果计数器小于限制,则将其放入并递增计数器:
您会注意到我创建了一个虚构的函数 getFoodTypeForObject()。这是更棘手的一点:识别。
您可以像这样实现示例逻辑:
其中
classNameContainsTheWord
是通过getQualifiedClassName
和indexOf
的组合来实现的,但更好的是使用通用的基类,如 Juan Pablo Califano 建议的那样。不过,我建议采用稍微不同的样式:使用它作为购物车项目 MC 的基类,然后在舞台上的 MC 实例上设置这些布尔属性。然后,您可以检测类似以下内容的类型:
比所有类名业务更清晰,并且具有额外的好处,您可以独立于其类名设置某些内容的属性。
它并不完美;例如,如果您需要很多属性,则需要更高级的东西,但这应该足以让您继续前进。
Hm. I think you're going to need something a bit more complex to make this work properly. You're actually asking a two-part question: how to keep track of stuff, and how to identify stuff. I'll start with the easy bit, keeping track.
DISCLAIMER: My AS3 is pretty rusty, but at least the theory should be sound, even if the implementation might be a bit off.
First, you'd want to define the limits for each type of food, thus:
Then, you want to keep count of objects you're adding to your cart
Then, when you add a new object, first check its type against the relevant count. If the counter is less than the limit, let it in and increment the counter:
You'll notice that I've created an imaginary function, getFoodTypeForObject(). This is the trickier bit: identification.
You could implement your example logic like so:
Where
classNameContainsTheWord
is achieved with a combination ofgetQualifiedClassName
andindexOf
, but better would be to use a common base class, as suggested by Juan Pablo Califano. I'd suggest a slightly different style though:use that as the base Class for your cart item MCs, then set those boolean properties on the instances of MCs on your stage. Then, you can detect the type of something like this:
Cleaner than all that classname business, and has the added benefit that you can set something's properties independent of its class name.
It's not perfect; for instance, you'd need something more advanced if you needed a lot of properties, but it should be enough for you to keep going.
大学让我做了一段时间的其他事情,但最终我可以回到我的游戏项目中。
我已经成功了。我使用了胡安·巴勃罗·卡利法诺的方法。我最初确实使用了 Henry Cooke's,因为我想摆脱为每种食物制作一个 .AS 文件(即 apple.as、grays.as、bread.as、oranges.as)。使用 Henry Cooke 的方法,我创建了一个
`var foodTypeLimit:Object = new Object();
foodTypeLimit["谷物"]=2;
foodTypeLimit["水果"]=2;
var foodTypeCount:Object = new Object();
等等等等
`
对于每种食物类型。然后使用:
var type:String = getFoodTypeForObject( currMc );
if( foodTypeCount[ 类型 ] < foodTypeLimit[ 类型 ] ){
items.push( currMc );
foodTypeCount[类型]++;
} 别的 {
// 抛出错误
}
按照建议。该函数返回了字符串和中提琴,它工作得很好。但是,由于我的 foodTypeCount 变量(例如 foodTypeCount["grain"]=0;)位于函数内部,因此每次调用这些变量的函数都会设置为 0,因此每次调用时增量都不会超过。所以我想,好吧,我将把这些 foodTypeCount 变量与 var foodTypeCount:Object = new Object(); 的实例化一起放在函数之外,但是不,我一直得到
:它就在那个奇怪的声明之下。我知道我太菜鸟了,无法理解为什么会这样。不管怎样,出于这个原因(缺乏增量,这对于这个函数来说是至关重要的)我硬着头皮使用了 Juan Pablo Califano 的方法。
首先,我写出了这样的类:
}
然后添加了接口
现在我的函数看起来像这样:
我试图将所有这些放入一个开关中。例如:
上面的实现不起作用。也许 switch 语句可能不应该这样使用。我不知道。 :S
不管怎样,感谢你们提供了非常好的答案,这是我最喜欢的网站,可以找到生命、宇宙和一切的答案。
Uni had me doing other stuff for a while but finally I can get back into my game project.
I've got it working. I used Juan Pablo Califano's method. I did initially use Henry Cooke's because I wanted to get away with making a .AS file for each food (i.e. apple.as, cereal.as, bread.as, oranges.as). With Henry Cooke's method I created a
`var foodTypeLimit:Object = new Object();
foodTypeLimit["grain"]=2;
foodTypeLimit["fruit"]=2;
And var foodTypeCount:Object = new Object();
etc etc
`
For each food type. Then used the:
var type:String = getFoodTypeForObject( currMc );
if( foodTypeCount[ type ] < foodTypeLimit[ type ] ){
items.push( currMc );
foodTypeCount[ type ]++;
} else {
// throw error
}
As suggested. The function returned the string and viola it worked fine. However because my foodTypeCount variables (for example foodTypeCount["grain"]=0;) was inside the function, every time the function called these were set to 0 so the increment never got above with each call. So I thought, ok, i'll put these foodTypeCount variables outside of the function along with the instantiation of the var foodTypeCount:Object = new Object(); BUT NO, I kept getting the:
Even though it was right under the freakin declaration. I get i'm just too noob to understand why this is so. Anyway, for this reason (the lack of incrementation, which was essential to this function) I bit the bullet and used Juan Pablo Califano's way.
First I wrote out the classes like so:
}
And then added the interface
And now my function looks something like this:
I tried to put all this into a switch. For example:
The above implementation didn't work. Perhaps switch statements probably aren't meant to be used that way. idk. :S
Anyway, thanks for the really great answers guys, this is my favorite site to come to for answers to life the universe and everything.