Access Child's Values from Other Class

Hi,

I’m always struggling to use the best way to access values from different elements from different places.

For example, I created an instance of Hero inside an instance of Level which is inside Game. Then, when I add an instance of PowerUp, I would like it to be attracted to the Hero when it’s close enough. To do that, I need to know the X and Y of this Hero when I’m inside the PowerUp class.

Without changing private var hero:Hero to public static var hero:Hero, what would you suggest to be the best approach?

Thank you!

When I first wrote an AS3 object-oriented project, I took the paradigm too literally :sweat:

For example, I built homing missiles, which (although very cool!) individually hunted for all available enemies, and plotted out a course.

There is more than one way to build a project, but one approach that has worked well for me was to write a small set of managers. I would keep the Hero and PowerUp as fairly simple objects, which know how to look the way they are supposed to, and how to respond to simple commands you give them, such as hero.showAnimation (WALK + LEFT) or powerUp.showAnimation (PULSE)

Then I might have either GameObjectManager or separate PlayerManager and PowerUpManager classes. Now you have a class that is above both your objects. In other words, you make Hero and PowerUp simple (like pawns on a chessboard) and you create higher-level classes that understand the game logic, and can check the state of many objects before determining an action.

This might look like:

private function onEnterFrame (event:Event):Void {
    
    var currentTime = Lib.getTimer ();
    var deltaTime = currentTime - previousTime;
    
    gameObjectManager.update (deltaTime);
    
}
public function update (deltaTime:Int):Void {
    
    for (powerUp in powerUps) {
        
        if (distanceSquared (powerUp, hero) < 20) {
            
            addIncrement (powerUp.x, hero.x, 0.20);
            addIncrement (powerUp.y, hero.y, 0.20);
            
        }
    
    }
    
}

If I did it again, I’d have one place that updates the homing logic for any homing missile on screen, perhaps in a ProjectileManager. I wouldn’t give each missile it’s own brain :wink:

Keeping controls centralized also is a godsend when you need to do things such as pausing, saving, restoring or moving to a new level. It’s helpful to have one authority you can go to when you need to change behavior

1 Like

Depending on how you choose to do animation, this addIncrement function may be helpful :slight_smile:

public function addIncrement (currentValue:Float, targetValue:Float, percentage:Float, minimum:Float = 0):Float {
	
	if (currentValue == targetValue) {
		
		return currentValue;
		
	}
	
	var increment = (targetValue - currentValue) * percentage;
	
	if (Math.abs (increment) < minimum) {
		
		if (increment < 0) {
			
			increment = - minimum;
			
		} else {
			
			increment = minimum;
			
		}
		
	}
	
	var nextValue = currentValue + increment;
	
	if (currentValue > targetValue && nextValue < targetValue) {
		
		return targetValue;
		
	} else if (currentValue < targetValue && nextValue > targetValue) {
		
		return targetValue;
		
	} else {
		
		return nextValue;
		
	}
	
}

Ah, I see! I already have a HitTestManager with an Array<Powers> (projectiles) and an Array<Ennemies> to check if you were able to hurt those ennemies.

public function update():Void {
	for (i in 0...powers.length) {
		for (j in 0...ennemies.length) {
			if (powers[i].hitZone.hitTestObject(ennemies[j].hitZone)) {
				powers[i].ouch();
				ennemies[j].ouch(powers[i].damage);
			}
		}
	}
}

I could do something similar or maybe add it directly in this HitTestManager! Each PowerUp would check if they are close enough of the Hero to move toward him until they touch him.

For the animations, I already have my system in place using the JSON provided by the TexturePacker software.

By the way, you replied to my posts more than once! Thank you for helping me! :slight_smile:

1 Like

Have you heard of Nape? Its a physics engine that also does thing like collision detection, and callbacks when things collide. I think it uses inline C++ so it should be very fast.

No, I never heard of it. I may look into it, but the little challenge I gave myself is to create everything myself, because that’s a great way for me (a non programmer) to learn.

But thanks, it could be helpful in the future! :slight_smile:

If you want to know how to do it in the future I’ve had to figure it out myself. This is what I have so far, it works but it may not be optimal.

You create a body for each entity:
body = new Body();
You add a “shape” to each entities body, like a square that represents the hitbox:
body.shapes.add(new Polygon(Polygon.box(40, 40)));
Create the “space” in a higher object that manages these entities:
_space = new Space();
Add all these bodies to the space:
_space.bodies.add(_position.get(entity).body);
Then you can query to see what bodies are touching:
var intersects = _space.bodiesInBody(entityBody,null);

Generally collision detection uses an axis-aligned bounding-box (AABB), which is like a grid that objects move along. When an object is queried it searches only those objects that are in the same grid as they are, eliminating searches that are N^2.

https://camo.githubusercontent.com/edf1a8bb6151a56e2a78a663d0079db1eb8fa25f/68747470733a2f2f6b696b69746f2e6769746875622e696f2f62756d702e6c75612f696d672f62756d702d73696d706c6564656d6f2e676966

If your game is complex enough, I would also recommend to try Nape, it might seems hard to comprehend the separation between graphics and physics first, Nape only takes care of the physics, but once you get it, you will be able to focus on other aspects of your project without worrying about performance, collisions and it can helps with movements, speed, impulse as well.

Joshua’s answer works, but different situations call for different solutions, so it’s best to know your options.

Here’s my suggestion: constructor arguments.

class PowerUp {
    private var hero:Hero;
    
    public function new(hero:Hero) {
        this.hero = hero;
    }
}

If you set up your class like this, you must then pass an instance of Hero when you create a PowerUp.

powerUp = new PowerUp(); //Fails, because nothing was passed.
powerUp = new PowerUp(hero); //Succeeds.

When you call new PowerUp(hero), it will save a reference to that Hero. That’s what’s happening when it runs this.hero = hero - it’s copying the argument (hero) to its own variable (this.hero). Then each frame, the PowerUp class can check the values of hero.x and hero.y and respond accordingly.

(Note: the constructor uses this.hero because there are two variables named hero, and you have to distinguish between them. Outside the constructor, there’s only one hero variable, so typing “this” is completely optional.)

I actually dont think Nape is good for only doing collision detection, its great if you using it for automatically rotating shapes around other shapes and doing actual physics but it lags a lot with too many objects if you arent utilizing it for moving objects around.

Another library I found is “Differ” though:

I can vouch for differ, currently using it. Just make sure you don’t test two polygons every frame, first do first stage circle based collision test, then second pass.

Actually my mistake, I dont think differ has any culling, so it just tests in N^2.

Theres another one I found called AABB:

It seems to work okay, but you cant simply pass it an ID without it breaking, it requires you create an entity.

Nape doesn’t lag at all imo… I’m using nape release version a lot.
It is light as a feather, I used it on mobile before and never seen a single frame drop.
It is usefull if you need some structure for your collisions, like making group of object, sensor, oneway platform etc. Maybe not so much for a simple game.

I’ve found using Nape for collision detection is 1/3 as fast in Neko and just as fast in C++ compared to hxAABBTree. I’m sure its much faster if you are using it for actual physics calculations though instead of just collision detection.