Personal computing discussed

Moderators: renee, SecretSquirrel, just brew it!

 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

AS3: Setter question

Fri Feb 03, 2012 12:53 pm

I thought the whole point of using a getter/setter is to keep the class's variables private.

If I set the class variables as private and attempt to "set" them in the setter, function acts like they don't exist. Only way I could get it to work was to set the variables to as "public static". Defeats the purpose doesn't it? I'm assuming I'm misunderstanding something here:

package 
{
   import flash.display.MovieClip;
   import flash.events.Event;
   import flash.utils.Timer;
   import flash.events.TimerEvent;

   public class Enemy extends MovieClip
   {
      private var _vx:int;
      private var _vy:int;
      private var _enemyHalfWidth:uint;
      private var _enemyHalfHeight:uint;
      private var _wanderTimer:Timer;

      public static var _playerposx:int;  //These are the variables in question.
      public static var _playerposy:int;



      public function Enemy()
      {
         addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
      }

      private function onAddedToStage(event:Event):void
      {
         _enemyHalfHeight = height / 2;
         _enemyHalfWidth = width / 2;
         stop();
         _wanderTimer = new Timer(Math.round((Math.random()*5000)));
         

         addEventListener(Event.ENTER_FRAME, eachFrame);
         addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
         _wanderTimer.addEventListener(TimerEvent.TIMER,changePath);
      }
      private function onRemovedFromStage(event:Event):void
      {
         removeEventListener(Event.ENTER_FRAME, eachFrame);
         removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
         removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
         removeEventListener(TimerEvent.TIMER,changePath);
      }

      private function changePath(Event:TimerEvent):void
      {
         _vx = Math.random() * 3 * (int(Math.random()*2) - 1 | 1);
         _vy = Math.random() * 3 * (int(Math.random()*2) - 1 | 1);
      }

      public static function set playerPosX(playerposx:int):void  //THESE TWO SETTERS ARE WHERE THE ERROR IS THROWN UNLESS THE CLASS VARIABLES ARE SET TO PUBLIC STATIC
      {
         _playerposx = playerposx;
      }

      public static function set playerPosY(playerposy:int):void
      {
         _playerposy = playerposy;
      }
      
      private function eachFrame(event:Event):void
      {   
         if (Math.abs(x - _playerposx) < 15 || Math.abs(y - _playerposy) < 15)
         {
            enemyHunt();
         }
         else
         {
            enemyWander();
         }
      }

      private function enemyHunt():void
      {
         //this function is also dependent on the variables _playerposx & _playerposy
      }

      private function enemyWander():void
      {
         //does stuff.
      }
   }
}
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 1:10 pm

I'm by no means an AS3 expert, but it looks sufficiently similar to C++ that I can make an educated guess as to what your problem is.

You've declared the two "set" functions to be static, which means they are not associated with any specific instance of the object. Because of this, they can *only* access static variables. Making the variables (and get/set methods) static means that if you create more than one instance of this class, those variables are effectively shared among all instances instead of (potentially) having different values in each instance -- i.e. setting the variable in instance A will also affect instance B.

I'm not sure if this was your intent or not (but I'm guessing not).
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 1:28 pm

I declared the setter as static because when I call the function from another class, it fails with "Access of possibly undefined playerPosX through a reference with static type Class." if it is only declared as public, and not public static.

My call in the other class looks like this:

Enemy.playerPosX = x;


To help you figure out what I'm doing, I'm reporting the position of the player object to the Enemy class so the enemy can use the information to "hunt" the player.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 1:33 pm

That doesn't look like a method call on an object instance. It looks like you're just trying to directly access a static member variable (hence the complaint from AS3). Where are you creating the instance of the object of type "Enemy"?

Edit: Do you understand the difference between declaring a class, and creating an instance of that class? If not, then perhaps you need to take a step back from AS3 and do a little reading about general object oriented design concepts first.
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 1:38 pm

It is a symbol on the stage. It is exported for AS3 with the class "Enemy". The original code I posted is of Enemy.as in the same folder as Player.as
All of it functions perfectly when set as public static, I just don't get why it has to be. I am finding so many examples of public setters setting private variables, yet I'm unable to reproduce.

If I understand you correctly, you think I'm slapping a bandaid on a problem that actually lies in my call in the Player class that just happens to work?
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 1:39 pm

No, I think what you're doing is setting the variables directly without even using the "set" methods. You're not calling anything.

Please also refer back to the edit of my previous post (if you didn't notice it already).
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 1:47 pm

Sorry, I didn't catch the edit.

I'm actually very much new to OOP and this is my first foray into it. I think I'm getting lost where I don't know how much Flash is doing for me in the "background". If an object instantiated as "enemy" on the stage, which is anchored to the AS3 class "Enemy", do I need to do any more? If I create a new instance of "Enemy" in class "Player", am I not duplicating?

My goal is for class "Player" to communicate with class "Enemy" in the safest way possible. The problem with tutorials I'm following is that they are either riddled with errors which makes learning from them impossible, or they say "do this" without any explanation as to why. I'm really big on the "whys".
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 1:51 pm

OK, so "Enemy" (with a capital "E") is your class, and "enemy" (lowercase "e") is your instance? If so, then you should be referring to "enemy" (not "Enemy") when you're trying to manipulate a specific instance of the Enemy class.

Also, you can probably disregard my previous post (the bit about not calling anything), I think I was a little confused about AS3 syntax.
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 2:02 pm

You know, I thought of the whole instance vs class reference problem as well, but it still throws an error back when the Player class tries to send the variable to the enemy instance of the Enemy class.

But perhaps its more telling:

"Access of undefined property enemy."

If I understand the error correctly, Player (class) can't "see" enemy (instance).


EDIT: I think I was right, because now everything is honky-dory if I add
private var _enemy:Enemy = new Enemy();


to the Player class. Except now they obviously don't communicate. The enemy instance on the stage wanders around as it should, but never attempts to "hunt" player, and a trace confirms this by show the "_playerpos(#)" variables contain "0". and no longer update with the player position.
Last edited by StefanVonS on Fri Feb 03, 2012 2:11 pm, edited 1 time in total.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 2:10 pm

StefanVonS wrote:
If I understand the error correctly, Player (class) can't "see" enemy (instance).

Agreed.

Where are you creating the instance of Enemy, and how are you passing/communicating that instance to the Player instance?

(As an aside: Static members will work as long as you never try to create more than one instance of a class. But as soon as you create more than one instance, any statics will be shared among all instances... which generally isn't what you want in an OO design.)
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 2:16 pm

As to your aside: thank you for that explanation, makes perfect sense.

If you take a look at my edit above, I explain what happens if I try to instantiate a new Enemy class in "Player".

This is probably where things are flying over my head. I have a symbol on the stage, gave it an instance name of "enemy" and tied it to the Enemy class as stated before. But I'm with you on the fact that I know that Player (or player) needs to be aware of the enemy instance. Maybe where I'm going completely wrong is trying to communicate between these two classes. Perhaps I need yet a third class to instantiate the entire stage, which would then be fully aware of all instances available.

Will that "awareness" be inherited by the Player and Enemy classes?
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Re: AS3: Setter question

Fri Feb 03, 2012 2:16 pm

StefanVonS wrote:
EDIT: I think I was right, because now everything is honky-dory if I add
private var _enemy:Enemy = new Enemy();


to the Player class. Except now they obviously don't communicate. The enemy instance on the stage wanders around as it should, but never attempts to "hunt" player, and a trace confirms this by show the "_playerpos(#)" variables contain "0". and no longer update with the player position.

Sounds like you now have *two* instances of the Enemy class? Rather than creating a new one inside the Player instance, you need to pass in a reference to the one you've (presumably) already created elsewhere?

(Sort of guessing here, since I haven't seen the code that creates the (original) Enemy instance or the Player instance...)

Edit: I think we've got the "why" sorted. Someone else with actual AS3 experience probably needs to help you with the "how"... this feels kind of like a half-blind man trying to lead a 3/4-blind man! :lol:
Nostalgia isn't what it used to be.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 2:28 pm

Lol, thank you for your guidance none-the-less. Very much appreciated.
 
Zoomastigophora
Gerbil Elite
Posts: 667
Joined: Tue Nov 11, 2008 7:10 pm

Re: AS3: Setter question

Fri Feb 03, 2012 4:38 pm

Without being able to see how you've actually architected your game, I can only echo what jbi said to pass a reference of your player instance to all the enemies. My experience is also only on the programming side i.e. AS3 with Flex and MXML; I've never done any connecting of AS3 code to Flash IDE objects and stages. Having a third class to instantiate everything is unnecessary unless you have gameplay logic that must exist at the world level rather than between individual actors.

As an aside, get and set are real function calls and since AS3 doesn't have language support for inlining function calls, the cost of using the get/set multiples times a frame because very high very quickly. I ended up making most of the variables that needed a getter public member variables because enforcing encapsulation just wasn't worth the huge performance penalty (the game was unplayable until we stopped using getters).
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Fri Feb 03, 2012 9:29 pm

How do you handle compartmentalizing it all, or do you not? For example, if I wanted to switch the level after completion, do I just copy and paste all the player/enemy logic instead of using classes?
 
Zoomastigophora
Gerbil Elite
Posts: 667
Joined: Tue Nov 11, 2008 7:10 pm

Re: AS3: Setter question

Sat Feb 04, 2012 3:20 am

StefanVonS wrote:
How do you handle compartmentalizing it all, or do you not? For example, if I wanted to switch the level after completion, do I just copy and paste all the player/enemy logic instead of using classes?

Depends on the scope and complexity of your game. What defines a level? Are there gameplay rules specific to one level? Is there state data that needs to persist between levels?

Off the top of my head, an easy route to start with is to define a base Actor class and make Player and Enemy subclasses of Actor. The Actor class can contain logic and data to handle operations that all actors can perform such as drawing and movement, and then your subclasses can specialize additional data such as health, attack, defense, or what have you. You can have a Level class that contains a list of enemies, a reference to player and an update function, which you can then subclass for specific levels that spawn specific types of enemies in certain quantities and contain specific rules that execute in update. In your main game application, you can create a single instance of a player and then instantiate levels with a reference to the player. For the active level, just call update every frame after doing whatever else you need to do (like input handling). It's a very rough basis for a gameplay system, but since you're new to OO, this is one way to start. This is roughly how XNA architects their system so you can take a look at that for reference. I also found this tutorial helpful when I was first learning to use AS3 to build games.

One thing to note though is that if you plan on doing a large complex game, deep inheritance hierarchies are not the way to go (or else you end up with the Unreal Engine 3). Components and aggregation is generally the way to go. Gameplay systems tend to be more ad-hoc in their design though, regardless of the type of engine architecture being used, and is usually designed to make sense for the genre of game the engine is built for.
 
StefanVonS
Gerbil Elite
Topic Author
Posts: 553
Joined: Mon Aug 14, 2006 2:51 pm
Location: Strong Badia

Re: AS3: Setter question

Sun Feb 05, 2012 8:48 pm

Thanks for all the replies. I ended up going the route of continuing to separate the classes. If for any reason at this point, it's to help me learn AS3. The part I was missing in communicating between the classes was the parent/child relationship. By adding MovieClip(parent.parent).playerposx(this), I was able to get it working properly. It also makes no direct reference to the class, so I am able to change out levels without having to rewrite the Player class.

Who is online

Users browsing this forum: No registered users and 1 guest
GZIP: On