Access of undefined property


(Ryan C) #1

I am relatively new to ACC and flash punk, and i have started to make a 2D strategy shooter. I’m making a phase where you place your units, by using a public variable to track the mouse and the mouse clicks, but, the variable cannot be accessed over classes. i get the error of 8 Error: Access of undefined property this is the code I’m using

public class GameWorld extends World   
{
 public var DrawLine:int = 0;
 public var FriendlyFleaX:int = FP.world.mouseX
 public var FriendlyFleaY:int = FP.world.mouseY 
 public function GameWorld()

and to access

x = FriendlyFleaX
y = FriendlyFleaY

any help is appreciated.


(Bora Kasap) #2

can you tell something more about that

where is this x y function? world class have no any x y variables. you need entities


(Jacob Albano) #3

It would be helpful to see the entire error message.


(Ryan C) #4

The x y function is called in my main entity class, the whole code for it is

public class FreindlyFlea extends Entity
{
	[Embed(source = "Image_res/flea.png")] private const FLEA:Class;
	[Embed(source = "Image_res/fleaHoverd.png")] private const FLEAHOVERED:Class;
	
	public function FreindlyFlea()
	{
		graphic = new Image(FLEA); 
		x = FreindlyFleaX
		y = FreindlyFleaY
        setHitboxTo(graphic);	
		
	}
	override public function update():void
	{
		if (collidePoint(x, y, world.mouseX, world.mouseY))
		{
			graphic = new Image(FLEAHOVERED)
		}
	}
}

and the error i get is

C:\Users___\Documents\Flea wars\src\FreindlyFlea.as(15): col: 8 Error: Access of undefined property FreindlyFleaX.


(Bora Kasap) #5

FreindlyFlea variables stored in GameWorld class… and your entities’ “world” variable is null when your entity created but not added yet, it is getting the world variable when it added to world… so, you need to try to reach your FreindlyFlea variables in added function of your entitiy

override public function added():void
{
x = GameWorld(this.world).FreindlyFleaX;
y = GameWorld(this.world).FreindlyFleaY;
}

or you can import FP class into your entity class

import net.flashpunk.FP;

then you can reach to world by this function if you want to set x,y properties in constructor when your entity just created but not added to world yet

public function FreindlyFlea()
	{
		graphic = new Image(FLEA); 
		x = GameWorld(FP.world).FreindlyFleaX;
		y = GameWorld(FP.world).FreindlyFleaY;
        setHitboxTo(graphic);	

	}

(Bora Kasap) #6

But it’s better you use a static class for global variables instead of using world class… that makes everything much easier.


(Ryan C) #7

Much appreciated! It now works, and i can get on with programming again, thanks! Also- a static class? (I’m still new to programming)


(Jacob Albano) #8

Close, but that won’t exactly work since FP.world is typed as a regular World, which doesn’t have those variables.

What you can do, however, is tell the compiler to look at the world as a specific World type by typecasting it:


// this function runs when the entity is added to the world
// before this runs, you can't access the world,
// because the entity doesn't know about it
override public function added():void
{
    var gameWorld:GameWorld = world as GameWorld;
    if (gameWorld == null)
    {
        // error! the world we were just added to isn't a GameWorld!
        return; // or handle the error in another way
    }

    x = gameWorld.FriendlyFleaX;
    y = gameWorld.FriendlyFleaY;
}

(Bora Kasap) #9

it looks like i was editing my post while you’re fixing my fault :slight_smile:


(Bora Kasap) #10

as i know about, static class is a class cannot be converted to any object and cannot be added to the stage, it is just storing some functions and variables(for me actually) then setting & getting these variables or calling these functions when needed from “everywhere”…


(Jacob Albano) #11

I’m always hesitant to recommend the use of static variables, since you can get into trouble by modifying them from any point in the code. My early projects are full of ugly hacks that could have been avoided if I had put a little more care into structure. These days, my team has a strict rule against global mutable data and it’s lead to much more stable code.

Static constants, on the other hand, are something I use all over the place.


(Bora Kasap) #12

As you know, i’m a beginner too, What’s the difference? Could you summarize? Or simply, what is the constant actually?


(Bora Kasap) #13

Oh, constant, i got you late because of not trying to translate the word constant. But that’s not the same right? So, what are you using for something like “player lives”? I think you’re too using global static variables for this case. Then, in which cases you’re trying to avoid using static variables?

Or are you just talking about nayrdux’s variable? Actually i couldn’t realize why he is using public variables for getting things like x,y… I don’t know, i thought maybe he’s planning something about that…


(Jacob Albano) #14

What I usually do is actually keep the player’s lives as a variable on the Player class. If I need to display them on the screen, I send a message to the HUD object when he loses a life so it can display the correct information.

That way, the HUD doesn’t have control over the player’s lives, and I don’t have to worry about manually resetting the life count when I start a new game. Basically, I make sure each class owns its own data, and send that data to other classes whenever necessary.


(Bora Kasap) #15

Yeah, that’s looking simple, it looks that’s according to game genre, if you’re working on a game like zelda? still you’re using this way? if yes, i’m going to think more about your method


(Jacob Albano) #16

I’ve used the same approach in a point-and-click adventure, a top-down action game, and a local-multiplayer platformer/brawler. It doesn’t depend on the genre at all.

By making each class responsible for its own data, it makes it trivial to run multiple copies of a class at once. It our game The Heroes’ Tourney, adding support for multiple players (each with individual stats including kills, wins, and lives) was trivial because we don’t use any global data that might cause conflicts. We have it capped at 4 players at the moment, but we could theoretically have up to 16.


(Bora Kasap) #17

that’s great!!!

then you’re not creating worlds and entities again and again? you’re just creating them once when the game started first then you’re just replacing worlds without using “new” command to make things keep their latest properties?


(Alex Larioza) #18

@AlobarNon What you’re talking about is object pooling/recycling. @jacobalbano is referring to data encapsulation.

Encapsulation is not a rule, but rather good programming etiquette. Giving objects access to the members of other objects gets messy very fast. With larger code bases, it can often become impossible to maintain.

Think of it this way: you wouldn’t want all your friends simply walking into your house and borrowing what ever they wanted because then you wouldn’t know where your things were or who even had them. Instead your friends should come and ask you directly, so that you can retrieve the items they’d like to borrow.


(Bora Kasap) #19

Yeah, i know, also i’ve used this data encapsulation thing in my game lots of time for controlling runflow.

private var _health:int = 100;
   public function getHP():int
   {
      return _health;
   }
   public function setHP(hp:int):void
   {
      _health = hp;
   }
   public function takeDamage(dmg:int):void
   {
      _health -= dmg;
      if(_health < 0)
      {
         _health = 0;
         this.killplayer();
      }
   }

It’s really making things much more controllable, readable, multiplication works great, so less propabilty to make mistakes as @jacobalbano said, also it looks like it is the only good way to make something like that. And much more easy to debug things…


(Alex Larioza) #20

Cool, :smile:

I’d like to point out though that AS3 has special keywords for getters/setters. With your code:

private var _health:int = 100;
public function get health():int { return _health;}
public function set health(value:int):void { _health = hp; }
...
public function someFunction():void
{
	someObjWithHealth.health -= 10;
	if (someObjWithHealth.health < 0)
	{
		// dead
	}
}

They are quite useful because you don’t need to add the extra “get” and “set” in front of function names. Plus in FlashDevelop’s intellisense, it pops up with a property icon rather than a function icon.