views:

104

answers:

3

I have the following function to set up cards in a game. I created one array to hold the kind of cards, and another array to hold the position of the cards.

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]);
     }

So if I want to set the card number "3" in position "5" I just write:

setPlayerCard(3,5);

The problem I can see is that every time I'd like to place a card, I am creating two arrays every time. I would like to make the arrays "global" (i.e. create it in my constructor in my document class) and reuse it in the function "setPlayerCard" however I am getting errors when I try to do so.

Any suggestions?

+1  A: 

This is a perfect case for a Singleton static class data model. You can get the instance of the Singleton from throughout the application as it is a static class, and it can contain the two arrays without duplication.

pixelbreaker has a nice basic Singleton AS3 example that you can build from.

Tegeril
Good idea!I am working on implementing the Singleton class now. My question is...after looking at some documentation on how to implement the Singleton class I am a little unsure of how to reference display list objects between the two classes. For example, the arrays I'd like to create are based on a MovieClip that I added to the display list in the other class. Class 1: Add a MovieClip to the display list, say call it "foo" Singleton Create an array of the items inside "foo" Result: Get an error inside of the singleton class for referencing "foo" which is inside of the other class.
redconservatory
A: 

I tried using the Singleton class, but since I had to reference MovieClips that were already on the display list, I opted for a different solution from "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 funtion ClassName() {
       //constructor
       Whatever();
       DoStuffWithWhatever();
}

private function Whatever() {
     // put stuff into the array here

}
private function DoStuffWithWhatever():void {
    // do stuff with the array values here.
}

   }
}
redconservatory
I guess I should also add that I chose this method because myArray_1 and myArray_2 is not going to change at all (i.e. remain static).
redconservatory
You could have accomplished the same functionality above using the Singleton pattern, however that works fine too.
Tegeril
I couldn't find an example of how to use the Singleton with an array (I saw lots of examples with strings and integers?). Also, it seemed like I needed to pass an argument to the Singleton (since the array was created based on another item in the Display List?)
redconservatory
What is the need for them to be public and static, can't they just be private?
Joony
+1  A: 

It's a little difficult to answer accurately without knowing how you are creating the variables and what errors you're getting. Can you post the entire class and the errors?

I can, however, recommend that you do not use the Singleton pattern. This is not a perfect case for a Singleton. The Singleton pattern has no place in OOP, it's procedural programming wrapped up like OO, but that's an argument for elsewhere.

This is, though, a perfect case for a class level variables. The following is a simple example. There are a few missing variable declarations though (numCards), as I don't know where you're creating and setting them.

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]);
        }
    }
}

This way you only create and populate the arrays once and you can access them from anywhere within the CardGame Class. They are not global but they are within the scope of the setPlayerCard method.

You may get errors as objects might not be instantiated when the Document Class' constructor gets called, but that can be worked around.

What is the need for the variable to be public and static?

Static means that the variable is on the Class, not instances of the Class. So every "CardGame" instance will share the same static variable. I presume, because this is the Document Class, that you will not have more than one instance of it. So there is no reason for that.

The only other reason, because you declared it public, is to make the variable accessible from outside the Class through CardGame.cardPositions. This is bad practice as you shouldn't allow other objects to directly manipulate a Classes internal data. That breaks encapsulation. Since this is the Document Class and the top of the hierarchy, you should pass a copy of the data to whichever object needs it and wait for an event to retrieve the updated data. That way you can sanitise the data before using it and you're not just blindly trusting other objects to respect your data.

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

Joony