Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411651 Posts in 69395 Topics- by 58451 Members - Latest Member: Monkey Nuts

May 15, 2024, 10:35:05 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Changing variables among classes in AS3
Pages: [1] 2
Print
Author Topic: Changing variables among classes in AS3  (Read 5463 times)
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« on: June 14, 2010, 05:36:22 PM »

This is probably going to sound like a stupid question, but I'm not making much headway trying to figure it out on my own, so I figure I might as well ask. I'm tinkering around, building a card game engine in AS3.

In the document class, I've got a function which deals out the cards in the player's deck:

Code:
function showDeck () {

for (i = 0 ; i < playerDeck.length ; i++ ) {

//ADD CARD MOVIECLIP
var myCard:Card = new Card();
addChild(myCard);

myCard.x = 10;
myCard.y = 40 + (i * 25);
myCard.rotation = 0;
myCard.gotoAndStop(playerDeck[i][0]); //make card BG correct color
myCard.currCardName = playerDeck[i][2]; //give card correct name

}
}

You'll note, at the end of that function, some code which tries to pass the correct name of each card from an array to the new card instance. The class Card, in turn, has in its class method code which adds the title of the card to each card when it's created:

Code:
//ADD CARD NAME TEXT
var cardNameText:TextField = new TextField();

cardNameText.text = currCardName;
addChild(cardNameText);
cardNameText.x = 5;
cardNameText.y = 5;
cardNameText.width = 125;
cardNameText.height = 30;
cardNameText.border = false;
cardNameText.selectable = false;

Or at least, that should be what it does. Unfortunately, I don't seem to be passing currCardName from my document class to the Card class correctly. I'm 98% sure that I'm doing something stupid, but as a newcomer to OOP, I'm not quite sure what it is. Any pointers?
Logged

Matt Thorson
Level 7
**

c'est la vie


View Profile WWW
« Reply #1 on: June 14, 2010, 05:42:30 PM »

When is the second block of code executed? If it's in Card's constructor, that's your problem. Right now you're constructing the Card object, at which point the text is set to the title string (which is probably some default value right now because it hasn't been set yet), then you're setting the title string.

What you'd want to do is add a "name" parameter to Card's constructor so you can create the Card object like:
Code:
var myCard:Card = new Card(playerDeck[i][2]);
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #2 on: June 14, 2010, 05:57:40 PM »

If it's in Card's constructor, that's your problem. Right now you're constructing the Card object, at which point the text is set to the title string (which is probably some default value right now because it hasn't been set yet), then you're setting the title string.

Okay, that makes sense.

What you'd want to do is add a "name" parameter to Card's constructor so you can create the Card object like:
Code:
var myCard:Card = new Card(playerDeck[i][2]);

You lost me on this part. What would this do, exactly?
Never mind, figured it out. Brilliant! Thanks for the help! Smiley
« Last Edit: June 14, 2010, 07:00:31 PM by Craig Stern » Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #3 on: June 15, 2010, 02:08:26 AM »

I think you've missed a trick with OO. Is playerDeck purely for loading purposes? If not, wouldn't it make more sense that each player's deck is composed of instances of Card, too? That makes the actual game code a lot simpler, as we don't have to worry about constantly converting between Cards and array format.
Logged
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #4 on: June 15, 2010, 05:55:19 AM »

Is playerDeck purely for loading purposes?

Nope. Smiley
Logged

Matt Thorson
Level 7
**

c'est la vie


View Profile WWW
« Reply #5 on: June 15, 2010, 10:19:43 AM »

If it's in Card's constructor, that's your problem. Right now you're constructing the Card object, at which point the text is set to the title string (which is probably some default value right now because it hasn't been set yet), then you're setting the title string.

Okay, that makes sense.

What you'd want to do is add a "name" parameter to Card's constructor so you can create the Card object like:
Code:
var myCard:Card = new Card(playerDeck[i][2]);

You lost me on this part. What would this do, exactly?
Never mind, figured it out. Brilliant! Thanks for the help! Smiley

Glad I could help. When can we play the game?
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #6 on: June 15, 2010, 03:17:08 PM »

When can we play the game?

There's not much to show just yet, but I'll be sure to post about it when I've got something worth seeing. (Or, you know, when AS3 confounds me again and I need some help. Smiley )
Logged

agj
Level 10
*****



View Profile WWW
« Reply #7 on: June 15, 2010, 06:05:21 PM »

I have toyed with the idea of creating a system to play any card game, as if it were a real deck (allowing you to have a hand, piles, rows of cards, etc.), online. Is this sort of what you're making? If so, awesome, I don't have to make it myself!
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #8 on: June 15, 2010, 07:14:54 PM »

Sorta. I'm basically teaching myself AS3 by creating a turn-based strategy game / collectible card game. My goal is to make it something like a cross between Magic: the Gathering and Shining Force.

I'm working on the card engine first--as of now, I've got it so it randomly generates a player deck from an index of all possible cards, then shuffles the deck, then deals a hand of 7 cards to the player, then displays the hand. The cards are all draggable, and are generated from code based on values stored in an array. (I just finished coding it so it displays casting cost symbols on the cards a little while ago.) Smiley
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #9 on: June 24, 2010, 10:17:45 PM »

I'm working on code to play cards from your hand now, and I'm experiencing sort of the inverse of my original problem: namely, determining the number associated with the card being clicked, and using that pull the card's info from an array (so as to determine casting cost, what type of card it is, etc.)

Here is the code in the document class that attaches each card movieclip in the first place:

Code:
//ADD CARD MOVIECLIP
var myCard:Card = new Card(targetArray[i][1] , targetArray[i][2] , targetArray[i][3] , targetArray[i][4] , targetArray[i][5] , targetArray[i][6] , targetArray[i][7] , targetArray[i][8] , targetArray[i][10] , i ); //creates a new instance of Card, referred to by the variable myCard; passes along cardName, cardType
myCard.name = "card" + i;
addChild(myCard); //adds the myCard movieclip instance as a child of the stage

myCard.x = 10;
myCard.y = 40 + (i * vertSpacing);
if (i > columnMax) {
myCard.x += horSpacing;
myCard.y -= ((columnMax + 1) * vertSpacing);
}
myCard.rotation = 0;
myCard.gotoAndStop(targetArray[i][0]);

cardMCArray.push(myCard);

It's that very last argument in the first line of real code there, i, that I am storing in each card like so via the Card class, and which I need to be able to retrieve later:

Code:
	public class Card extends MovieClip {

public function Card (cardType , cardName, iceCost , airCost , fireCost , lightCost , darkCost , miscCost , range , cardID) {

var ID:int = cardID;

My current attempts at determining the ID for each card upon activation involve the following code in the document class:

Code:
//MAKE DRAGGABLE and DOUBLE-CLICKABLE
myCard.doubleClickEnabled = true;
addListeners(myCard);

function addListeners (card:Card) {

if (targetArray == playerHand) {
card.addEventListener(MouseEvent.DOUBLE_CLICK, playCard);
}

function playCard (event:MouseEvent) {
payCastingCost(etherArray); //check to see if player has enough ether to pay casting cost
trace(event.target);
cardPlayed = event.target.ID;
if (castingCostPaid == true) {
if (playerHand[cardPlayed][1] == "Minion") {
//move card from player's hand to the field
addCharacter(cardPlayed);
}
removeChild(cardMCArray[cardPlayed]);
playerHand.splice(cardPlayed , 1);
}
}

The event.target code, when traced, returns [object Card]. Any attempt at accessing the ID property that way gets me Error #1069: Property ID not found on Card and there is no default value. It seems to me that event.target is referring to the class Card, and not to the instance on the stage. How can I work around this problem?
Logged

bateleur
Level 10
*****



View Profile
« Reply #10 on: June 24, 2010, 10:30:32 PM »

It seems to me that event.target is referring to the class Card, and not to the instance on the stage. How can I work around this problem?

That doesn't sound right. You wouldn't get that error message if that was the problem.

I suspect the difficulty is most likely that you're trying to use objects as if they were duck typed. AS3 actually has a proper type system and won't allow this.

So, in particular:

Code:
cardPlayed = event.target.ID;

...is bad, because event.target has type Object even if the specific instance at runtime happens to be an instance of Card. You cannot access 'ID' like this, because it is a field of the class 'Card' and not the class 'Object'.

Instead, do either this:

Code:
cardPlayed = Card(event.target).ID;

...or this...

Code:
cardPlayed = (event.target as Card).ID;

...which in your case will make no difference. (Generally speaking you use 'as' when the cast could fail. If it does, you then get a null object rather than an Exception.)
Logged

Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #11 on: June 25, 2010, 08:45:12 AM »

Both methods leave me with a compiler error: 1119: Access of possibly undefined property ID through a reference with static type Card.
Logged

agj
Level 10
*****



View Profile WWW
« Reply #12 on: June 25, 2010, 09:28:44 AM »

I'll admit that I didn't look very closely at your code, but it seems to me that you're declaring the variable within the constructor function, whereas you need to declare it outside of any function, but within the class declaration, so that it actually belongs to the scope of the class. The 'var' keyword is context-sensitive, so to speak. From within the constructor you can access (and set) that variable by skipping the 'var' keyword.
Logged

Sam
Level 3
***



View Profile WWW
« Reply #13 on: June 25, 2010, 09:44:25 AM »

Whilst you were typing a new reply has been posted..
I am totally repeating what agj just said, sorry!

Code:
public class Card extends MovieClip
{
   public function Card (cardType , cardName, iceCost , airCost , fireCost , lightCost , darkCost , miscCost , range , cardID)
   {
                var ID:int = cardID;
   }
}
Your current code declares a variable called ID within the constructor function, which can then only be accessed from within that same function.

Code:
public class Card extends MovieClip
{
   public var ID:int;
   public function Card (cardType , cardName, iceCost , airCost , fireCost , lightCost , darkCost , miscCost , range , cardID)
   {
                ID = cardID;
   }
}
Move the declaration of ID to outside of any function (but within the Card class definition), set it as Public and now that variable can be accessed by stuff outside of the Card class.
Logged
Craig Stern
Level 10
*****


I'm not actually all that stern.


View Profile WWW
« Reply #14 on: June 25, 2010, 12:45:49 PM »

Wonderful, thank you! I knew there had to be a way to do that. Smiley
Logged

PleasingFungus
Level 7
**



View Profile WWW
« Reply #15 on: June 25, 2010, 01:45:32 PM »

For the record, you actually can emulate duck typing with AS3:

Code:
foo.bar() #in a duck-typed language
translates to
Code:
foo["bar"](); //in AS3

This is horrible and morally reprehensible and removes all compile-time type-checking; plus, I strongly suspect that there's a nasty speed penalty for this. But, well. If it comes up.
Logged

Finished games: Manufactoria! International King of Wine!
And others on my site.
bateleur
Level 10
*****



View Profile
« Reply #16 on: June 26, 2010, 01:51:17 PM »

This is horrible and morally reprehensible and removes all compile-time type-checking; plus, I strongly suspect that there's a nasty speed penalty for this. But, well. If it comes up.

It's also a little bit surprising to me that it works (as indeed it does) since I would have expected () to require an object of (known) type Function. Since foo["bar"] is in general not a function even when it is defined, it seems wrong to me that this construction doesn't at least spit out a warning.
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #17 on: June 27, 2010, 01:45:48 PM »

Using brackets is nothing special, it's just turning off static typing.
You can just as easily do
var foo2:* = foo;
foo2.bar.

Either way, it is casting foo to a dynamic object (in this case, Object), retrieving the property with name "bar", casting it to Function, and applying it.

I don't know why you call it duck typing, it is exactly like regular scripting languages do it, and with a big it compared with static stuff. If you make all your objects "dynamic", then they behave like regular scripting language objects.
Logged
bateleur
Level 10
*****



View Profile
« Reply #18 on: June 28, 2010, 02:49:09 AM »

A dynamic object is just one to which you can add properties at runtime, so there's no necessity for such an object to allow itself to be cast to a Function.

The reason I referred to "duck typing" originally is because Craig Stern appeared to have written code that accessed a property on the basis that it new for sure that it was defined, which in a duck typed language is fine. (And it's not in general fine in AS3, as you know.)
Logged

BorisTheBrave
Level 10
*****


View Profile WWW
« Reply #19 on: June 28, 2010, 12:34:47 PM »

A dynamic object is just one to which you can add properties at runtime, so there's no necessity for such an object to allow itself to be cast to a Function.
Right, but then you get the "bar" property. This will be a type "*" as obviously the compiler doesn't know the type. And anything of type "*" can be implicitly cast to anything, including Function.
Logged
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic