【问题标题】:Actionscript 3: Array Scope in a Document ClassActionscript 3:文档类中的数组范围
【发布时间】:2025-11-28 17:25:01
【问题描述】:

我有以下功能可以在游戏中设置卡片。我创建了一个数组来保存卡片的种类,并创建了另一个数组来保存卡片的位置。

private function setPlayerCard(cardNumber:int, cardPos:int):void{
            for (var i:int = 1; i < _CardGridInstance.numChildren+1; i++) {
                var _position:MovieClip = MovieClip(_CardGridInstance.getChildByName("Position_" + i));
                cardPositions[i] = _position;
                cardPositions[i].pos_name.text = "position" + i;
                cardPositions[i].id = ["pos"+i];
            }


            for (var j:int = 1; j < numCards+1; j++) {
                var _c:Class = getDefinitionByName("Card_" + j) as Class;
                var _cardInstance:MovieClip = new _c();
                cards[j] = _cardInstance;
            }
            cards[cardNumber].x = _CardGridInstance.x + cardPositions[cardPos].x - 1;
            cards[cardNumber].y = _CardGridInstance.y + cardPositions[cardPos].y;
            addChild(cards[cardNumber]);
        }

所以如果我想将卡号“3”设置在位置“5”,我只需写:

setPlayerCard(3,5);

我可以看到的问题是,每次我想放置一张卡片时,我都会创建两个数组。我想让数组“全局”(即在我的文档类的构造函数中创建它)并在函数“setPlayerCard”中重用它,但是当我尝试这样做时出现错误。

有什么建议吗?

【问题讨论】:

    标签: actionscript-3 arrays scope


    【解决方案1】:

    这是单例静态类数据模型的完美案例。您可以从整个应用程序中获取 Singleton 的实例,因为它是一个静态类,它可以包含两个数组而不会重复。

    pixelbreaker 有一个不错的基本 Singleton AS3 示例,您可以从中构建。

    【讨论】:

    • 好主意!我现在正在实现 Singleton 类。我的问题是......在查看了一些关于如何实现 Singleton 类的文档后,我有点不确定如何在两个类之间引用显示列表对象。例如,我要创建的数组基于我添加到另一个类的显示列表中的 MovieClip。第 1 类:将一个 MovieClip 添加到显示列表中,比如将其命名为“foo” Singleton 在“foo”中创建一个项目数组 结果:在单例类中出现错误,以引用另一个类中的“foo” .
    【解决方案2】:

    在不知道如何创建变量以及遇到什么错误的情况下准确回答有点困难。你能发布整个课程和错误吗?

    不过,我可以建议您不要使用单例模式。对于单例来说,这不是一个完美的案例。 Singleton 模式在 OOP 中没有位置,它是像 OO 一样封装的过程编程,但这是其他地方的论据。

    不过,这是类级别变量的完美案例。下面是一个简单的例子。不过有一些变量声明缺失(numCards),因为我不知道您在哪里创建和设置它们。

    package{
        import flash.display.Sprite;
        public class CardGame extends Sprite{
    
           private var cardPositions:Array = new Array();
           private var cards:Array = new Array();
    
           public function CardGame(){
               for var i:uint = 1; i <= _CardGridInstance.numChildren; i++) {
                    var position:MovieClip = MovieClip(_CardGridInstance.getChildByName("Position_" + i));
                    cardPositions[i] = position;
                    cardPositions[i].pos_name.text = "position" + i;
                    cardPositions[i].id = ["pos"+i];
                }
                for(i = 1; i <= numCards; i++) {
                    var c:Class = getDefinitionByName("Card_" + i) as Class;
                    var cardInstance:MovieClip = new c();
                    cards[i] = cardInstance;
                }
            }
    
            private function setPlayerCard(cardNumber:uint, cardPos:uint):void{
                cards[cardNumber].x = _CardGridInstance.x + cardPositions[cardPos].x - 1;
                cards[cardNumber].y = _CardGridInstance.y + cardPositions[cardPos].y;
                addChild(cards[cardNumber]);
            }
        }
    }
    

    这样,您只需创建和填充一次数组,就可以从 CardGame 类中的任何位置访问它们。它们不是全局的,但它们在 setPlayerCard 方法的范围内。

    您可能会遇到错误,因为在调用文档类的构造函数时对象可能不会被实例化,但这可以解决。

    什么是变量需要是公共的和静态的?

    静态意味着变量在类上,而不是类的实例上。所以每个“CardGame”实例都将共享相同的静态变量。我假设,因为这是文档类,所以您不会拥有多个它的实例。所以没有理由这样做。

    唯一的其他原因,因为您将其声明为 public,是为了使该变量可以从类外部通过 CardGame.cardPositions 访问。这是不好的做法,因为您不应允许其他对象直接操作 Classes 内部数据。这打破了封装。由于这是文档类和层次结构的顶部,您应该将数据的副本传递给需要它的任何对象并等待事件来检索更新的数据。这样,您就可以在使用数据之前对其进行清理,而且您不会盲目地相信其他对象会尊重您的数据。

    http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

    【讨论】:

      【解决方案3】:

      我尝试使用 Singleton 类,但由于必须引用已在显示列表中的 MovieClip,我选择了与“Actionscript 3 Tip of the Day”不同的解决方案:

      http://www.kirupa.com/forum/showthread.php?p=2110830#post2110830

      package {
      
      public class ClassName {
             public static var myArray_1:Object = new Object;
             public static var myArray_2:Object = new Object;
      public function ClassName() {
             //constructor
             Whatever();
             DoStuffWithWhatever();
      }
      
      private function Whatever() {
           // put stuff into the array here
      
      }
      private function DoStuffWithWhatever():void {
          // do stuff with the array values here.
      }
      
         }
      }
      

      【讨论】:

      • 我想我还应该补充一点,我选择了这种方法,因为 myArray_1 和 myArray_2 根本不会改变(即保持静态)。
      • 您可以使用单例模式完成上述相同的功能,但是也可以正常工作。
      • 我找不到如何将 Singleton 与数组一起使用的示例(我看到很多字符串和整数示例?)。另外,我似乎需要向 Singleton 传递一个参数(因为数组是基于显示列表中的另一个项目创建的?)
      • 它们需要什么是公开的和静态的,它们不能只是私有的吗?