mieki256's diary



2012/09/08() [n年前の日記]

#3 [as3][flash][starling] Starling使用中のウインドウをリサイズする際の処理でハマる

Windows7 x64 上で Starling を勉強中なのだけど。ウインドウサイズを変更した際に、表示内容もウインドウサイズに合わせて拡大縮小させようとしたものの、何度もサイズを変更してるうちにエラーが出て Flash Player が固まってしまう不具合が出てハマってしまったり。

ウインドウサイズ変更時は、Event.RESIZE でイベント発生させられるのだけど。もしかすると前のリサイズ処理がまだ終わってないうちに、次のイベントが発生して、マズイことになってるのかなと。しかしそれなら、まだ処理中だよ的フラグを用意すれば、そこそこ改善するはずで。しかし、相変わらずエラーが出る。改善できてるように見えない…。

変更したら必ず固まるわけではないのが困る。時々何かの拍子に発生するようで。Starling.current.viewPort = viewport; のあたりがおかしいのかなあ…。よくわからん…。

色々試したけど、どうにかエラーが出ない感じになったかもしれず。とりあえず、Main.as は下のようになった。
package com.blawat2015
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import starling.core.Starling;
    
    [SWF(width="480",height="320",frameRate="60",backgroundColor="#000000")]
    
    /**
     * Starling + ウインドウサイズ変更のテスト
     */
    public class Main extends Sprite
    {
        private var myStarling:Starling;
        private var resize_exec:Boolean = false;
        
        /**
         * コンストラクタ
         */
        public function Main():void
        {
            // stage が既に存在しているなら即座に、
            // stage が存在していないならステージ生成時に、初期化メソッドを呼ぶ。
            if (stage)
                init()
            else
                addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        /**
         * 初期化処理
         * @param   e
         */
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.BEST;
            
            // Starlingのインスタンスを生成
            var viewport:Rectangle = new Rectangle(0, 0, _g.STGW, _g.STGH);
            myStarling = new Starling(MySprite, stage, viewport, null, "auto", "baseline");
            
            myStarling.antiAliasing = 1; // アンチエイリアス設定
            myStarling.showStats = true; // 状態表示有効化
            myStarling.enableErrorChecking = true; // エラーチェック
            myStarling.start(); // 描画処理開始
            
            // ウインドウリサイズ時の処理を設定
            stage.addEventListener(Event.RESIZE, onResize);
        }
        
        /**
         * ウインドウリサイズ時に呼ばれる処理
         * @param   e
         */
        private function onResize(e:Event):void
        {
            // 処理中にイベントが再発生するとマズいので、フラグでチェック
            if (resize_exec)
                return;
            
            resize_exec = true;
            var v:Rectangle, sw:int, sh:int;
            myStarling.stop(); // 念のために描画を停止しておく
            do
            {
                sw = stage.stageWidth;
                sh = stage.stageHeight;
                v = new Rectangle(0, 0, sw, sh);
                
                // 縦横拡大率を求める
                _g.wdw_scaleX = sw / _g.STGW;
                _g.wdw_scaleY = sh / _g.STGH;
                
                if (_g.wdw_scaleX > _g.wdw_scaleY)
                {
                    // 横に引き延ばし過ぎ
                    var w:int = int(_g.STGW * _g.wdw_scaleY);
                    if (v.width > w)
                        v.width = w;
                    v.x = int((sw - v.width) / 2) & 0xfff8;
                    _g.wdw_scaleX = _g.wdw_scaleY;
                }
                else if (_g.wdw_scaleX < _g.wdw_scaleY)
                {
                    // 縦に引き延ばし過ぎ
                    var h:int = int(_g.STGH * _g.wdw_scaleX);
                    if (v.height > h)
                        v.height = h;
                    v.y = int((sh - v.height) / 2) & 0xfff8;
                    _g.wdw_scaleY = _g.wdw_scaleX;
                }
                
                    // 処理中にウインドウサイズが変更されてたら算出し直し
            } while (sw != stage.stageWidth || sh != stage.stageHeight);
            
            myStarling.viewPort = v;
            myStarling.stage.stageWidth = _g.STGW;
            myStarling.stage.stageHeight = _g.STGH;
            myStarling.start(); // 描画再開
            _g.wdw_w = sw;
            _g.wdw_h = sh;
            resize_exec = false;
        }
    }
}
ちなみに、main.as とは別に、MySprite.as、_g.as が用意してある。

ハマってた時のソースから変えた部分をメモ。 最初は、全てを格納するSpriteの拡大縮小率を変更して対応させてたけど。PC上であればそういうことをしなくても済む感じ。Android等ではどうなるか分からないけど。ひとまず、Starling が持ってる、viewPort、stage.stageWidth、stage.stageHeight を弄ることでどうにかできるっぽい。

以下、よくわかってないけど。 例えば。 こんな感じなのかな…。たぶん。自信無いけど。間違ってるかもしれんけど。

以上です。

過去ログ表示

Prev - 2012/09 - Next
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project