-
Notifications
You must be signed in to change notification settings - Fork 153
Description
I was reading this code the other day and noticed a that in update, preUpdate and postUpdate are call once per level of nesting in the hierarchy of objects in a FlxNestedSprite. So the top level object calls them once, the second twice, the third three times and so on. I traced it in the attached program and it's so. This should have resulted in erroneous motion calculations when relativeVelocity is non-0. I tested that and it is also true. If you set _fns2.relativeVelocity to 10. and run the program the _fns2 sprite travels approximately twice as far relative to _fns1 as it should. If instead you make _fns3.relativeVelocity = 10 and leave _fns2 relativeVelocity = 0, the _fns3 will travel 3 times as far as it should relative to _fns1 as it should. This is consistent with multiple calls to updateMotion() at each level.
This is a simple PlayState demonstrating the issue. The lib versions involved are:
Haxe 4.3.3
flixel-addons: [3.2.1]
flixel: [5.6.2]
package;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.addons.display.FlxNestedSprite;
import flixel.tweens.FlxTween;
import flixel.tweens.misc.NumTween;
import flixel.util.FlxColor;
import haxe.Timer;
class FlxDebugNestedSprite extends FlxNestedSprite
{
var _name:String;
public function new(name:String)
{
super();
_name = name;
}
override public function preUpdate(elapsed:Float):Void
{
// trace('Starting preUpdate ${_name}');
super.preUpdate(elapsed);
// trace('Ending preUpdate ${_name}');
}
override public function update(elapsed:Float):Void
{
// trace('Starting update ${_name} at ${Timer.stamp()}');
super.update(elapsed);
// trace('Ending update ${_name} at ${Timer.stamp()}');
}
override public function postUpdate(elapsed:Float):Void
{
// trace('Starting postUpdate ${_name}');
super.postUpdate(elapsed);
// trace('Ending postUpdate ${_name}');
}
override function updateMotion(elapsed:Float):Void
{
// trace('Starting updateMotion ${_name}');
super.updateMotion(elapsed);
// trace('Ending updateMotion ${_name}');
}
}
class PlayState extends FlxState
{
var _fns1:FlxDebugNestedSprite;
var _fns2:FlxDebugNestedSprite;
var _fns3:FlxDebugNestedSprite;
var _fns4:FlxDebugNestedSprite;
override public function create()
{
super.create();
_fns1 = new FlxDebugNestedSprite('fns1');
_fns1.makeGraphic(100, 100, FlxColor.WHITE);
_fns1.setPosition(0, 100);
_fns2 = new FlxDebugNestedSprite('fns2');
_fns2.makeGraphic(40, 40, FlxColor.BLUE);
_fns2.relativeX = _fns2.relativeY = 50;
_fns3 = new FlxDebugNestedSprite('fns3');
_fns3.makeGraphic(10, 10, FlxColor.RED);
_fns3.relativeX = 30;
_fns4 = new FlxDebugNestedSprite('fns4');
_fns4.makeGraphic(10, 10, FlxColor.RED);
_fns4.relativeY = 30;
_fns2.add(_fns3);
_fns2.add(_fns4);
_fns1.add(_fns2);
add(_fns1);
// Various motion tests
// There is something odd with tweening which results in _fns3 and _fns4 being out of position.
// FlxTween.tween(_fns1, {x: 600}, 1.0, {type: PINGPONG});
// Basic white block speed
_fns1.velocity.x = 200;
// Relative speed tests. Uncomment _fns2 for see the example with doubled up relative distance.
// With 10 px/sec relative to _fns1 the final displacement change in x should be about 30 pixels
// but it is about 60.
_fns2.relativeVelocity.x = 10;
// Relative speed tests. Uncomment _fns3 for see the example with tripled up relative distance.
// With 10 px/sec relative to _fns1 the final displacement change in x should be about 30 pixels
// but it is about 90.
// _fns3.relativeVelocity.x = 10;
}
override public function update(elapsed:Float)
{
super.update(elapsed);
// Travelling about 200 pixels per second this gives about 3 seconds elapsed between sides
// of the game window.
if (_fns1.x <= 0 || _fns1.x > 600)
{
_fns1.velocity.x *= -1.0;
_fns2.relativeVelocity.x *= -1.0;
_fns3.relativeVelocity.x *= -1.0;
// Diff the values in consecutive prints of this debug.
trace('${Timer.stamp()}:_fns1.x=${_fns1.x} and _fns2.x=${_fns2.x} and _fns3.x=${_fns3.x}');
}
}
}