Forked from: kkeisuke's forked from: beginBitmapFill で背景を無限スクロール(dispose) diff:35 forked from: beginBitmapFill で背景を無限スクロール(Statsの罠) narutohyper forked:3favorite:3lines:131license : MIT License modified : 2010-02-08 02:23:19 share Tweet // 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; } } Code Fullscreen Preview Fullscreen HaraMakoto fenixkim : stars norichika2 : BitmapDataloop BitmapData loop stars width System.gc toFixed System.totalMemory Event.ADDED_TO_STAGE graphics mouseEnabled Event.RESIZE Shape selectable removeEventListener TextFormat Math.PI Math.cos align defaultTextFormat TextFieldAutoSize.LEFT font autoSize addEventListener sort new page view favorite forked pv41 étoiles jcayzac forked:0 favorite:0lines:116 (diff:34) pv109 forked from: forked from: begi.. takahashitakashi forked:0 favorite:0lines:131 (diff:1) pv65 forked from: forked from: begi.. yoziee forked:0 favorite:0lines:131 (diff:1)