Apache flex &引用;“有趣”;Flash/Flex行为:增加绘制10000个三角形的时间
这是一个测试程序,用于测量Flash绘制10000次三角形所需的时间 应用程序(下面的代码)每N秒调用一次runTimeTest(),这将绘制10000次三角形 现在来看“有趣”部分:每次调用占用的处理器越来越多,直到第6次或第7次调用后,它进入“无限”(参见TaskManager的屏幕截图) 奇怪的虫子还是可以解释的Apache flex &引用;“有趣”;Flash/Flex行为:增加绘制10000个三角形的时间,apache-flex,flash,adobe,Apache Flex,Flash,Adobe,这是一个测试程序,用于测量Flash绘制10000次三角形所需的时间 应用程序(下面的代码)每N秒调用一次runTimeTest(),这将绘制10000次三角形 现在来看“有趣”部分:每次调用占用的处理器越来越多,直到第6次或第7次调用后,它进入“无限”(参见TaskManager的屏幕截图) 奇怪的虫子还是可以解释的 // create a Canvas to draw on var c:Canvas = new Canvas(); function onApplicationComple
// create a Canvas to draw on
var c:Canvas = new Canvas();
function onApplicationComplete(e:Event)
{
c.width = width;
c.height = height;
c.x = 0;
c.y = 0;
addChild(c);
// set up a timer to run every 10 seconds
var timer:Timer = new Timer(10000);
timer.addEventListener(TimerEvent.TIMER, runTimeTest);
timer.start();
}
function runTimeTest(e:Event)
{
// this is called every 10 seconds
var x0:int, x1:int, x2:int;
var y0:int, y1:int, y2:int;
// set triangle vertices
x0 = 100; y0 = 500;
x1 = 120; y1 = 515;
x2 = 155; y2 = 500;
// draw a filled triangle 10,000 times
for (var i:int = 0; i < 10000; ++i)
{
c.graphics.beginFill( 0xff0000, 1 );
c.graphics.moveTo( x0, y0 );
c.graphics.lineTo( x1, y1 );
c.graphics.lineTo( x2, y2 );
c.graphics.lineTo( x0, y0 );
c.graphics.endFill();
}
}
//创建要绘制的画布
var c:Canvas=newcanvas();
Application Complete上的函数(e:事件)
{
c、 宽度=宽度;
c、 高度=高度;
c、 x=0;
c、 y=0;
addChild(c);
//设置计时器,使其每10秒运行一次
var定时器:定时器=新定时器(10000);
timer.addEventListener(TimerEvent.timer,runTimeTest);
timer.start();
}
函数运行时测试(e:事件)
{
//每10秒调用一次
变量x0:int,x1:int,x2:int;
变量y0:int,y1:int,y2:int;
//设置三角形顶点
x0=100;y0=500;
x1=120;y1=515;
x2=155;y2=500;
//画一个填充的三角形10000次
对于(变量i:int=0;i<10000;++i)
{
c、 图形填充(0xff0000,1);
c、 图。移动到(x0,y0);
c、 图形。lineTo(x1,y1);
c、 图形。lineTo(x2,y2);
c、 图形。lineTo(x0,y0);
c、 graphics.endFill();
}
}
i34.tinypic.com/jutpwo.png
“如果在运行时测试开始时调用c.graphics.clear()如何?”詹姆斯·沃德 是的,添加c.graphics.clear()修复了它。
马特 Flash会一直保存所有绘图命令(即图形),直到调用graphics.clear()。这样,您就可以在多个帧上绘制,而无需同时绘制所有内容 绘制三角形的时间越来越长的原因是每次调用runTimeTest()Flash时都需要额外绘制10000个三角形 因此,第一次调用Flash时,它会绘制10000个三角形,第二次调用runTimeTest()时,它必须绘制前10000个三角形(因为尚未清除画布),然后再绘制第二个10000个三角形 正如格伦指出的,解决方案是在绘制每组三角形之前清除画布。这样,Flash只需绘制当前的三角形集。 无论出于何种原因,如果您确实需要在屏幕上绘制大量的项目,您可以利用位图缓存:如果您每次都在不同的画布/精灵上绘制图形,那么Flash只需绘制一次每个图形(其他图形都缓存在幕后的内存中) e、 g
私有函数drawTriangles():void
{
变量x0:int,x1:int,x2:int;
变量y0:int,y1:int,y2:int;
//设置三角形顶点
x0=100;y0=500;
x1=120;y1=515;
x2=155;y2=500;
//这是重要的部分。
//仅在此新精灵上绘制10000个三角形。
变量c:Sprite=新Sprite();
c、 cacheAsBitmap=true;
addChild(c);
对于(变量i:int=0;i<10000;++i)
{
c、 图形填充(0xff0000,1);
c、 图。移动到(x0,y0);
c、 图形。lineTo(x1,y1);
c、 图形。lineTo(x2,y2);
c、 图形。lineTo(x0,y0);
c、 graphics.endFill();
}
}
使用此方法,您会注意到每次绘制三角形所需的时间大致相同(因为Flash每次实际上只绘制相同数量的对象)
只需注意,在处理大部分静态图形时,位图缓存可以获得最大的好处
通常,如果不需要保留画布上以前的内容,则只绘制所需内容并执行graphics.clear()操作
针对马特的评论: 您的意思是,如果在每个三角形后都没有调用endFill()(就像现在一样) 这对性能没有任何好处,只会改变绘制的内容。如果在同一BegFill/endFill剖面期间在同一区域上绘制,则每次都会“反转”绘制的剖面 没有一个例子就有点难以解释 让我们修改您的三角形函数,以便它在同一beginFill/endFill剖面中绘制两个三角形:
c.graphics.beginFill( 0xff0000, 1 );
for (var i:int = 0; i < 2; ++i)
{
c.graphics.moveTo( x0, y0 );
c.graphics.lineTo( x1, y1 );
c.graphics.lineTo( x2, y2 );
c.graphics.lineTo( x0, y0 );
}
c.graphics.endFill();
c.graphics.beginll(0xff0000,1);
对于(变量i:int=0;i<2;++i)
{
c、 图。移动到(x0,y0);
c、 图形。lineTo(x1,y1);
c、 图形。lineTo(x2,y2);
c、 图形。lineTo(x0,y0);
}
c、 graphics.endFill();
如果你运行它,那么你就不会在屏幕上看到任何东西
这是因为你在同一个区域上画了两次,它被反转了(变成透明的)——从技术上讲,Flash仍然在画它,但你就是看不见它
如果将迭代次数更改为3,则将再次看到三角形(因为它每次都从可见->不可见->可见进行切换)
这一页很好地解释了这一点(见下面三分之一的“缠绕”部分)-虽然它专门讨论了Flash Player 10,但同样的想法也适用于以前的版本,我们只是当时无法控制它:)
如果你用精灵而不是画布来画画,会有什么不同吗?如果在runTimeTest开始时调用c.graphics.clear()如何?如果您使用新的图形API(即Graphics.drawGraphicsData),会怎么样?是的,添加c.Graphics.clear()修复了它。非常感谢!你能给我一个答复吗?这样我就可以接受了。MattCanvas和Sprite在这里没什么区别。绘制到本机flash图形层不会触发画布布局功能。.clear()工作的原因可能是内存问题。flash引擎可能正在跟踪每个填充的三角形。谢谢Sly提供的信息。我不知道Flash会一直保存所有绘图命令,直到清除()。我想知道如果endFill()被称为
c.graphics.beginFill( 0xff0000, 1 );
for (var i:int = 0; i < 2; ++i)
{
c.graphics.moveTo( x0, y0 );
c.graphics.lineTo( x1, y1 );
c.graphics.lineTo( x2, y2 );
c.graphics.lineTo( x0, y0 );
}
c.graphics.endFill();