In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: beginBitmapFill で背景を無限スクロール(Statsの罠)

beginBitmapFill のテストです。
背景を無限スクロールさせると、メモリはどのような状態になるのでしょう?

アドバイスを頂きました!ありがとうございます!!
dispose() を入れたら、自宅の環境だと 5M も減りました!!
開放される頻度も上がったように感じます!!
/**
 * Copyright narutohyper ( http://wonderfl.net/user/narutohyper )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cqe1
 */

// forked from kkeisuke's forked from: beginBitmapFill で背景を無限スクロール(dispose)
// forked from kkeisuke's beginBitmapFill で背景を無限スクロール
package  
{
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Matrix;
	import net.hires.debug.Stats;
	import flash.text.*;
	import flash.system.System
	
	/** 
	* beginBitmapFill のテストです。
	* 背景を無限スクロールさせると、メモリはどのような状態になるのでしょう?
	* 
	* アドバイスを頂きました!ありがとうございます!!
	* dispose() を入れたら、自宅の環境だと 5M も減りました!!
	* 開放される頻度も上がったように感じます!!
	*/
	[SWF(backgroundColor = 0xffffff, frameRate = 40, width = 465, height = 465)]
	public class TileLoopScroll extends Sprite
	{
		private var bd:BitmapData;
		private var bdw:int;
		private var bdh:int;
		private var sw:Number;
		private var sh:Number;
		private var mtx2:Matrix;
		private var dbg:TextField;
		private var Memory:Number=0;
		private var maxMemory:Number=0;
		
		
		public function TileLoopScroll() 
		{
			addEventListener(Event.ADDED_TO_STAGE , added);
		}
		
		
		private function added(e:Event):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, added);
			
			init();
		}
		
		
		private function getStar():BitmapData {
			// 素材の準備
			var star:Shape = new Shape();
			star.graphics.beginFill(0xFCE80D);
			star.graphics.drawRect(-50, -50, 100, 100);
			star.graphics.beginFill(0xFCC00D);
			GraphicsUtil.star(star.graphics, 20, 40);
			star.graphics.endFill();
			star.x = star.width * 0.5;
			star.y = star.height * 0.5;
			
			var mtx:Matrix = new Matrix();
			mtx.translate(star.width * 0.5, star.height * 0.5);
			
			var result:BitmapData;
			result = new BitmapData(star.width, star.height);
			result.draw(star, mtx);
			
			return result;
		}

		
		private function init():void
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			bd = getStar();
			
			bdw = bd.width;
			bdh = bd.height;
			
			// リサイズ用
			setStageSize(null);
			
			// beginBitmapFill 用の Matrix
			mtx2 = new Matrix();
			
			this.addEventListener(Event.ENTER_FRAME , loop);
			stage.addEventListener(Event.RESIZE , setStageSize);
			
			//addChild(new Stats());

			dbg=new TextField()
			dbg.autoSize=TextFieldAutoSize.LEFT
			dbg.selectable=false;
			dbg.mouseEnabled=false;
			var format:TextFormat=new TextFormat();
			format.color=0x666666
			format.size=12;
			format.font='_ゴシック';
			dbg.defaultTextFormat=format
			addChild(dbg);
			dbg.x=200
			
		}
		
		
		private function draw():void
		{
			// 素材の bitmapdata
			//bd.dispose();
			//bd = null;
			//bd = getStar();
			
			// 一応 clear() してるのですが・・・
			this.graphics.clear();
			this.graphics.beginBitmapFill(bd, mtx2);
			this.graphics.drawRect(0, 0, sw, sh);
			this.graphics.endFill();

			//メモリが増えていくのは、実はStatsのPixel描画によるものでは?
			//TextAreaにMemoryを表示するとほとんど変わらないので、上記の操作でメモリリークは無いと思われます。
			//なお、dispose()は、BitmapDataのメモリを開放するので、その際ガベージコレクションを更新しているに過ぎない気がします。
			//実際には、わずかですが、その処理分の負荷が増える事になりますよね
			//ちなみにこれでも、微妙にメモリは加算されますが、下記の表記によるゴミみたいなものなので、
			//デバックできる環境で、System.gc()(ガベージコレクションの強制開放)すると、メモリがまったく変化しないのが確認できるかと思います。
			Memory=Number((System.totalMemory * 0.000000954).toFixed(3));
			maxMemory=(maxMemory<Memory)?Memory:maxMemory;
			dbg.text='Mem '+String(Memory)+'\nMax '+String(maxMemory);
			//以下はデバッグでのみ有効()
			System.gc();
		}
		
		
		private function loop(e:Event):void 
		{
			if (mtx2.tx > bdw || mtx2.ty > bdh) 
			{
				mtx2.tx = mtx2.ty = 0;
			}
			
			// tx,ty でスクロールさせる。
			mtx2.tx += 2
			mtx2.ty += 2
			
			draw();
		}
		
		
		private function setStageSize(e:Event):void 
		{
			sw = stage.stageWidth;
			sh = stage.stageHeight;
		}
		
	}

}



import flash.display.Graphics;
import flash.display.Shape;
import flash.geom.Point;


/** 
* 既存にない Graphics を描画するクラスです。Graphics を返します。
*/
class GraphicsUtil
{
	static private var PI:Number = Math.PI;
	static private var DEGTORAD:Number = Math.PI / 180;
	
	
	/** 
	* 星形
	* @param g Graphics ターゲット 
	* @param inR 内側の半径
	* @param outR 外側の半径
	* @param vertex 頂点の数。5点以上
	* @return Graphics 生成した星形
	*/
	public static function star(g:Graphics, inR:Number, outR:Number, vertex:int = 5):Graphics
	{
		var points:/*Number*/Array = [];
		var rad:Number = PI * 2 / vertex;
		
		for (var i: int = 0; i < vertex; i++) 
		{
			var outTheta:Number = (i * rad) - PI * 0.5;
			var inTheta:Number = outTheta + (rad * 0.5);
			
			points[i << 2] = outR * Math.cos(outTheta);
			points[(i << 2) + 1] = outR * Math.sin(outTheta);
			points[(i << 2) + 2] = inR * Math.cos(inTheta);
			points[(i << 2) + 3] = inR * Math.sin(inTheta);
		}
		
		g.moveTo(points[0], points[1]);
		
		var n:int = points.length >> 1;
		for (var j: int = 1; j < n; j++) 
		{
			g.lineTo(points[j << 1], points[(j << 1) + 1]);
		}
		
		g.lineTo(points[0], points[1]);
		
		return g;
	}
}