2

当用户在浏览器中切换标签时,为什么 flash 应用程序会暂停?如何防止?,我需要让它连续播放

更新:

<?xml version="1.0"?>
<s:Module 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init();"
    xmlns:MyComp="components.*">


    <fx:Script>
        <![CDATA[
            import library.TicketCard;
            import library.UtilFunctions;

            [Embed(source="../images/ball1.png")] 
            private var red:Class;
            [Embed(source="../images/ball2.png")] 
            private var orange:Class;
            [Embed(source="../images/ball3.png")] 
            private var blue:Class;
            [Embed(source="../images/ball4.png")] 
            private var green:Class;
            [Embed(source="../images/ball5.png")] 
            private var purple:Class;

            private var numTimer:Timer;
            private var step:int;
            public var currentRand:Number;
            public var randNumbers:Array;
            public var vNum:Array;
            public var speedAnim:Number;
            [Bindable]
            public var countNum:int = 0;
            public var ticketsBought:*;

            private function init():void {

                vNum = new Array();
                step = 1;
                ticketsBought = parentApplication.m_ticket.child.ticketsBought;
                speedAnim = 1000;
                generateNumbers();
                randNumbers = new Array();
                for(var i:int = 0; i < 90; i++)
                {
                    randNumbers.push((i + 1));

                }
                numTimer = new Timer(1000, 180);
                numTimer.addEventListener(TimerEvent.TIMER, onTick);
                numTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTickComplete);
                initialPosition();
                numTimer.start();
            }

            private function initialPosition():void {

                bigBall.width = 4;
                bigBall.height = 4;
                bigBall.horizontalCenter = -92;
                bigBallLabel.horizontalCenter = bigBall.horizontalCenter;
                bigBallLabel.setStyle('fontSize', 1);

            }

            private function onTickComplete(e:TimerEvent):void {

                parentApplication.showMessage('end game!');

            }

            private function onTick(e:TimerEvent):void {

                if(step == 1)
                {
                    if(countNum < 90)
                    {
                        countNum++;
                    }
                    var rand:Number = UtilFunctions.randomRange(randNumbers.length - 1, 0);
                    currentRand = randNumbers[rand];
                    for(var i:int = 0; i < ticketsBought.length; i++)
                    {

                        var ticket:* = ticketsBought[i];
                        var numbers:Array = ticket.ticketNumbers;
                        for(var j:int = 0; j < numbers.length; j++)
                        {

                            if(numbers[j].text == currentRand)
                            {
                                var num:* = numbers[j];
                                num.setStyle('backgroundColor', '#552c68');
                                num.setStyle('color', '#FFFFFF');
                                ticket.checkedNumbers++;
                                break;
                            }

                        }

                    }
                    randNumbers.splice(rand, 1);
                    var n:* = vNum[rand];
                    n.alpha = 1;
                    vNum.splice(rand, 1);
                    bigBallLabel.text = currentRand.toString();
                    startIncreaseAnim();
                }
                else
                if(step == 2)
                {
                    startReduceAnim();
                }
                numTimer.stop();

            }

            private function generateNumbers():void {

                for(var i:int = 0; i < 90; i++)
                {
                    var m:MyImg = new MyImg();
                    var c:Canvas = new Canvas();
                    var l:Label = new Label();
                    l.text = (i + 1).toString();
                    l.horizontalCenter = 0;
                    l.verticalCenter = 0;
                    c.width = 25;
                    c.height = 25;
                    c.alpha = 0.3;
                    vNum.push(c);
                    m.horizontalCenter = 0;
                    m.verticalCenter = 0;

                    if(i >= 0 && i < 18)
                    {
                        m.source = red;
                    }
                    else if(i >= 18 && i < 36)
                    {
                        m.source = orange;

                    }
                    else if(i >= 36 && i < 54)
                    {

                        m.source = blue;
                    }
                    else if(i >= 54 && i < 72)
                    {
                        m.source = green;
                    }
                    else if(i >= 72 && i < 90)
                    {
                        m.source = purple;
                    }
                    c.addChild(m);
                    c.addChild(l);
                    numbersBlock.addChild(c);
                }
            }

            public function startIncreaseAnim():void {

                stage.addEventListener(Event.ENTER_FRAME, increaseAnim);

            }

            public function startReduceAnim():void {

                stage.addEventListener(Event.ENTER_FRAME, reduceAnim);

            }

            public function endIncreaseAnim():void {

                stage.removeEventListener(Event.ENTER_FRAME, increaseAnim);

            }

            public function endReduceAnim():void {

                stage.removeEventListener(Event.ENTER_FRAME, reduceAnim);

            }

            public function increaseAnim(e:Event):void {

                bigBall.width += 4;
                bigBall.height += 4;
                bigBall.horizontalCenter += 4;
                bigBallLabel.horizontalCenter = bigBall.horizontalCenter;
                bigBallLabel.setStyle('fontSize', bigBallLabel.getStyle('fontSize') + 1);
                if(bigBall.horizontalCenter >= 0)
                {
                    step = 2;
                    endIncreaseAnim();
                    numTimer.start();
                }

            }

            public function reduceAnim(e:Event):void {

                bigBall.width -= 4;
                bigBall.height -= 4;
                bigBall.horizontalCenter += 4;
                bigBallLabel.horizontalCenter = bigBall.horizontalCenter;
                bigBallLabel.setStyle('fontSize', bigBallLabel.getStyle('fontSize') - 1);
                if(bigBall.horizontalCenter >= 90)
                {
                    step = 1;
                    initialPosition();
                    endReduceAnim();
                    numTimer.start();
                }

            }
            ]]>
    </fx:Script>

    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";


    </fx:Style>

    <mx:VBox height="727" width="176" styleName="leftBar" verticalGap="4">
        <mx:Box verticalGap="12">
            <mx:Box width="176" horizontalScrollPolicy="off">
                <mx:Canvas width="100%" height="100" id="bigBallWrapper" horizontalScrollPolicy="off">
                    <MyComp:MyImg id="bigBall" verticalCenter="0" horizontalCenter="0" source="@Embed(source='../images/ball1-1.png')"/>
                    <s:Label color="#000000" id="bigBallLabel" fontSize="24" text="45" verticalCenter="0" horizontalCenter="0" />
                </mx:Canvas>
                <mx:Canvas width="100%">
                    <s:Label text="ball # {countNum}" fontSize="18" verticalCenter="0" horizontalCenter="0" />
                </mx:Canvas>
            </mx:Box>
            <MyComp:MyImg id="bingoLeft" source="@Embed(source='../images/bingoLeft.png')"/>
        </mx:Box>
        <mx:Tile fontSize="12" fontFamily="bor" color="black" direction="vertical" horizontalGap="9" height="100%" width="100%" paddingLeft="8" paddingRight="8" id="numbersBlock" verticalScrollPolicy="off" horizontalScrollPolicy="off">

        </mx:Tile>
    </mx:VBox>
</s:Module>

有点复杂的代码:),但是计时器第一次执行,然后停止,在每个动画开始后,我将它用作 setTimeout(在 js 中)

4

1 回答 1

1

以下是我基于我创建的一个简单应用程序所做的一些观察:

  • 有一个按钮来开始/停止Timerw/a 指定的时间间隔
  • 有一个按钮来添加/删除一个Event.ENTER_FRAME处理程序
  • 有一个按钮来添加/删除一个FlexEvent.UPDATE_COMPLETE处理程序
  • graphics可选择让您在每一帧上绘制(使用属性)
  • 有选择地尝试<s:Rect />在每一帧上移动 Flex 对象 (a )

有趣的观察以粗体显示,代码在底部。

测试#1

当 Flash 应用程序的浏览器选项卡位于“前台”时,这些Timer和“enterFrame”事件按预期工作。以指定的Timer时间间隔触发,并Event.ENTER_FRAME尽快发送(在我的机器上每 30-50 毫秒)。

当 Flash 应用程序的浏览器选项卡位于“后台”时,Event.ENTER_FRAME大约每 500 毫秒调度一次。如果您将 的间隔设置Timer为低于 500 毫秒,Timer则它也只会每 500 毫秒触发一次。

因此,正如我们所猜测的,当 Flash Player 知道它不可见时,它会通过减少触发频率来尝试使用更少的 CPU Event.ENTER_FRAME,并且您不能使用Timer小于 500 毫秒的间隔。

测试#2

但是当您尝试更新屏幕时会发生什么?

我让应用程序在处理程序中绘制了几行圆圈Event.ENTER_FRAME。屏幕更新按预期进行,但当 Flash 应用程序的浏览器选项卡在后台时会更慢。

测试#3

但是Flex呢?Flex 组件有自己的生命周期,上面的绘制代码不参与该生命周期。让我们为FlexEvent.UPDATE_COMPLETE. 这是一个在每个 Flex 组件生命周期结束时调度的事件(提交任何更改的属性、测量和渲染的一次迭代)。在此测试中,除非您执行调整浏览器窗口大小(这会导致 Flex 重绘屏幕)之类的操作,否则不会调度该事件。

如果 Flash 应用程序的浏览器选项卡位于“背景”中,FlexEvent.UPDATE_COMPLETE则不会调度(在调整浏览器窗口大小时)。Flash Player 知道应用程序不可见,因此当我调整浏览器大小时它不会浪费 CPU 尝试重绘屏幕。

测试#4

好的,现在我想我们已经准备好尝试做一些与您在应用程序中所做的事情相近的事情了……为某物的位置设置动画。在这种情况下,我将<s:Rect />通过在“enterFrame”处理程序中更改它的 x/y 坐标来移动 a。

屏幕似乎仍在更新,尽管当 Flash 应用程序的浏览器选项卡位于“背景”时要慢得多。另请注意,当矩形移动时,它FlexEvent.UPDATE_COMPLETE也会被调度。

结论

根据上述证据,Flash Player 并没有暂停应用程序,而是在 Flash 知道应用程序不可见时限制应用程序。

现在这对您的代码意味着什么?我还不确定:) 也许你的更新正在发生,但它太慢了,似乎什么都没有改变?

代码:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:local="*"
               width="100%" height="100%"
               creationComplete="application1_creationCompleteHandler(event)">

    <s:layout>
        <s:VerticalLayout />
    </s:layout>

    <fx:Script>
        <![CDATA[
            import flash.utils.getTimer;

            import mx.events.FlexEvent;

            private var timer:Timer;
            private var previousTimerTime: int = 0;
            private var timerEventDelta:int = 0;
            private var previousFrameTime:int = 0;
            private var enterFrameDelta:int = 0;
            private var surface:Graphics;
            private var drawingPoint:Point = new Point(0,0);

            protected function application1_creationCompleteHandler(event:FlexEvent):void
            {
                timer = new Timer(1000);
                timer.addEventListener(TimerEvent.TIMER, onTimerEvent);
                surface = drawingSurface.graphics;
            }

            private function toggleTimer():void
            {
                if (timer && timer.running)
                {
                    timer.reset();
                }
                else
                {
                    var interval:int = parseInt(timerInterval.text) as int;
                    timer.delay = interval;
                    timer.start();
                }
            }

            protected function onTimerEvent(event:TimerEvent):void
            {
                var currentTime:int = getTimer(); // milliseconds since the app started
                if (previousTimerTime == 0)
                {
                    trace("timer event (first event)");
                }
                else
                {
                    timerEventDelta = currentTime - previousTimerTime;
                    trace("timer event: time between last event: " + timerEventDelta);
                }
                previousTimerTime = currentTime;
            }

            protected function onEnterFrame(event:Event):void
            {
                var currentTime:int = getTimer(); // milliseconds since the app started
                if (previousFrameTime == 0)
                {
                    trace("enter frame (first event)");
                }
                else
                {
                    enterFrameDelta = currentTime - previousFrameTime;
                    trace("enter frame: time between last event: " + enterFrameDelta);
                }
                previousFrameTime = currentTime;
                if (drawOnEachFrame.selected)
                    draw();
                if (moveOnEachFrame.selected)
                    moveRect();

            }

            protected function onUpdateComplete(event:FlexEvent):void
            {
                trace("update complete");
            }

            private function toggleEnterFrameHandler():void
            {
                if (hasEventListener(Event.ENTER_FRAME))
                {
                    removeEventListener(Event.ENTER_FRAME, onEnterFrame);
                    previousFrameTime = 0;
                }
                else
                    addEventListener(Event.ENTER_FRAME, onEnterFrame);

            }

            private function toggleUpdateCompleteHandler():void
            {
                if (drawingSurface.hasEventListener(FlexEvent.UPDATE_COMPLETE))
                {
                    drawingSurface.removeEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateComplete);

                }
                else
                    drawingSurface.addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateComplete);
            }

            private function draw():void
            {
                surface.beginFill(0xFF0000);
                surface.drawCircle(drawingPoint.x, drawingPoint.y, 5);
                surface.endFill();
                drawingPoint.x += 10;
                if (drawingPoint.x > drawingSurface.width)
                {
                    drawingPoint.x = 0;
                    drawingPoint.y += 15;
                }
            }

            private function moveRect():void
            {
                rectbert.x += 10;
                if (rectbert.x > drawingSurface.width - 50)
                {
                    rectbert.x = 0;
                    rectbert.y += 25;
                }
            }



        ]]>
    </fx:Script>

    <s:HGroup>
        <s:Button label="start/stop timer" click="toggleTimer()" />
        <s:Label text="Timer Interval (milliseconds)" />
        <s:TextInput id="timerInterval" text="1000" />
    </s:HGroup>
    <s:HGroup>
        <s:Button label="add/remove Event.ENTER_FRAME handler" click="toggleEnterFrameHandler()"/>
        <s:CheckBox id="drawOnEachFrame" label="Draw on each frame" />
        <s:CheckBox id="moveOnEachFrame" label="Move rectangle on each frame" />
        <s:Label text="(note this code doesn't move an draw at the same time)"/>
    </s:HGroup>

    <s:Button label="add/remove FlexEvent.UPDATE_COMPLETE hanlder " click="toggleUpdateCompleteHandler()"/>

    <s:Group id="drawingSurface" width="100%" height="100%">
        <s:Rect id="rectbert" width="50" height="50" x="0" y="0">
            <s:fill>
                <s:SolidColor color="#0000FF"/>
            </s:fill>
        </s:Rect>
    </s:Group>
</s:Application>
于 2013-06-06T19:30:14.400 回答