MovieClip子对象的问题(Issues about MovieClip children)

有一些关于h5的bug反馈一下:

  1. MovieClip的子对象渲染混乱(openfl 6.0.1里表现正常,openfl 6.1.x -> html5);
    无标题
  2. MovieClip的子对象实例只能和第一帧的变量绑定,即使之后子对象发生了变化(导出flash正常);

例程如下(不能上传附件 :sob:):

package;

import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.ui.Keyboard;
import openfl.Assets;

/**
 * ...
 */
class Main extends Sprite
{

	var mc:MovieClip;

	public function new()
	{
		super();
		addEventListener(Event.ADDED_TO_STAGE, onAdded);
	}

	function onAdded(e:Event):Void
	{
		stage.color = 0xffffff;

		mc = Assets.getMovieClip("tigeress:TigeressPlayer");
		addChild(mc);
		mc.x = stage.stageWidth / 2;
		mc.y = stage.stageHeight / 2;
		mc.stop();
		stage.addEventListener(KeyboardEvent.KEY_UP, onKey);
		stage.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
		stage.addEventListener(MouseEvent.CLICK, onSwitchFilter);
	}

	/**
	 * GlowFilter on/off
	 * @param	e
	 */
	function onSwitchFilter(e:MouseEvent):Void
	{
		// perform well in openfl 6.1.0
		// set filters lead to disappearance of mc in openfl 6.0.1
		mc.filters = mc.filters.length > 0 ? [] : [new GlowFilter(0, 1, 30, 30)];
	}

	/**
	 * to next or prev label
	 * @param	next
	 */
	function labelStep(next:Bool):Void
	{
		var labels:Array<String> = getAllLabels();
		var i:Int = labels.indexOf(mc.currentLabel);
		if (next)
		{
			// to next label
			mc.gotoAndStop(i >= labels.length - 1 ? labels[0] : labels[i + 1]);
		}
		else
		{
			// to prev label
			mc.gotoAndStop(i <= 0 ? labels[labels.length - 1] : labels[i - 1]);
		}

		if (Reflect.getProperty(mc,"role") == mc.getChildByName("role"))
		{
			// perform well in flash
			trace("mc.role == mc.getChildByName('role')");
		}
		else
		{
			// issue in H5:
			// get child by property do not equal to get child by name except first label
			trace("mc.role != mc.getChildByName('role')");
		}
	}

	/**
	 * change scale
	 * @param	expand
	 * true scale++
	 * false scale--
	 */
	function zoom(expand:Bool):Void
	{
		if (expand)
		{
			mc.scaleX *= 1.2;
			mc.scaleY = mc.scaleX;
		}
		else
		{
			mc.scaleX /= 1.2;
			mc.scaleY = mc.scaleX;
		}
	}

	/**
	 * get all labels of mc
	 * @return
	 */
	function getAllLabels():Array<String>
	{
		var a:Array<String> = [];
		for (fl in mc.currentLabels)
		{
			a.push(fl.name);
		}
		return a;
	}

	/**
	 * on scroll
	 * @param	e
	 */
	function onWheel(e:MouseEvent):Void
	{
		// ctrl + mousewheel change mc's scale
		if (e.ctrlKey)
		{
			zoom(e.delta > 0);
		}
		// mousewheel change current label
		else
		{
			labelStep(e.delta > 0);
		}
	}

	/**
	 * on key up
	 * @param	e
	 */
	function onKey(e:KeyboardEvent):Void
	{
		// ↑ enlarge view
		// ↓ reduce view
		// ← to prev label
		// → to next label
		switch (e.keyCode)
		{
			case Keyboard.LEFT:
				labelStep(false);
			case Keyboard.RIGHT:
				labelStep(true);
			case Keyboard.UP:
				zoom(true);
			case Keyboard.DOWN:
				zoom(false);
		}
	}

}

其他配置如下:

<!-- project.xml -->
<library path="tigeress.swf" id="tigeress" preload="true" generate="true" />

mc有3个标签,每个标签有一个名为role的动画
截屏图片

所有文件在这里:https://www.dropbox.com/s/o23lv32727o72e9/test_5.zip

Thanks, I think @sbimikesmullin has a rework of MovieClip animation he’s doing which may resolve some of these issues. We’ll try and take a look once that’s ready :slight_smile:

I can’t wait for openfl to update.:smile:

I created an issue:

I have some other pressing things that I need to take care of first, but I would like to look into this soon and find the root cause :slight_smile:

Filters’ issue did may be related to cacheAsBitmap in openfl 6.0.1.
But it fixed in openfl 6.1.0.
I think other reasons cause children render confusion that perform well in openf 6.0.1. :slightly_smiling_face:

I compared source of 6.0.1 and 6.1.0, I found a difference cause issue between them.
MovieClip.hx : __enterFrame()
6.0.1

// TODO: Do not remove manually added children
while (__children.length > currentInstances.length)
{
	removeChild (__children[__children.length - 1]);
}

6.1.0 and 6.1.1

var child, length = __children.length;
for (i in currentInstances.length...length)
{
	child = __children[i];
	// TODO: Faster method of determining if this was automatically added?
	for (instance in __activeInstances)
	{
		if (instance.displayObject == child)
		{
			removeChild (child);
		}
	}
}

There were so many todo lists, so I just modified them temporarily, even if it‘s not best-case solution. :joy:

var child: DisplayObject, i: Int = currentInstances.length,
	length: Int = __children.length;
while (i < length)
{
	child = __children[i];
	// TODO: Faster method of determining if this was automatically added?
	for (instance in __activeInstances)
	{
		if (instance.displayObject == child)
		{
			removeChild(child);
			// index and length need to update
			i--;
			length--;
		}
	}
	i++;
}

Looks like openfl need more people to maintain the code. :smile:

Ah, good catch :slight_smile:

We received a contribution with a complete overhaul of the MovieClip class. This resolved some errors, but caused new regressions. I hope that this will even out soon.

I appreciate your help :grinning: