-
repeated lineTo slows down
I am making a demo where an object is moved around the screen with a line tracing its movement. The speed of this noticeably slows down over time. I tried it both with an enterFrame and by setting an interval. I imagine it has something to do with the graphics class vector drawing and garbage collection. Here is a simplified version for demo/testing. If you run it you will see the line drawing slow down over time. What is causing this? Is there a way to achieve it without the slow down?
I read somewhere of a technique where you use the bitmap data class to draw on a stage-sized bitmap. Is this a good way to achieve this? If so, can someone give me help to get me started on this? (I've never programmed the bitmap data class before). Thanks.
Here is the code:
code: var lineX:Number = 100; var lineY:Number = 100;
var deltaX:Number = 10; var deltaY:Number = 10;
var lineDrawing:MovieClip = new MovieClip();
this.addChild(lineDrawing);
lineDrawing.graphics.lineStyle(1, 0xCCCCCC, 1);
lineDrawing.graphics.moveTo(lineX,lineY);
var lineInterval:uint = setInterval (moveline, 1);
// NOTE: Slow down also happens without interval and with enterFrame,
// but it takes longer to be noticeable:
// addEventListener(Event.ENTER_FRAME, moveline);
function moveline ():void {
lineX += deltaX; lineY += deltaY;
if (lineX > stage.stageWidth) {lineX = 0}
if (lineX < 0) {lineX = stage.stageWidth}
if (lineY > stage.stageHeight) {lineY = 0}
if (lineY < 0) {lineY = stage.stageHeight}
lineDrawing.graphics.lineTo(lineX, lineY)
}
-
Senior Member
It's because vector graphics are quite memory/cpu intensive, best bet is draw to a bitmapdata:
Code:
var bmd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFF);
var bm:Bitmap = new Bitmap(bmd);
addChild(bm);
var lineX:Number = 100; var lineY:Number = 100;
var deltaX:Number = 10; var deltaY:Number = 10;
var lineDrawing:MovieClip = new MovieClip();
this.addChild(lineDrawing);
lineDrawing.graphics.lineStyle(1, 0xCCCCCC, 1);
lineDrawing.graphics.moveTo(lineX,lineY);
var lineInterval:uint = setInterval (moveline, 1);
// NOTE: Slow down also happens without interval and with enterFrame,
// but it takes longer to be noticeable:
// addEventListener(Event.ENTER_FRAME, moveline);
function moveline ():void {
lineX += deltaX; lineY += deltaY;
if (lineX > stage.stageWidth) {lineX = 0}
if (lineX < 0) {lineX = stage.stageWidth}
if (lineY > stage.stageHeight) {lineY = 0}
if (lineY < 0) {lineY = stage.stageHeight}
lineDrawing.graphics.lineTo(lineX, lineY)
bmd.draw(lineDrawing);
lineDrawing.graphics.clear();
lineDrawing.graphics.lineStyle(1, 0xCCCCCC, 1);
lineDrawing.graphics.moveTo(lineX, lineY)
}
-
Senior Member
Also, you can forget the movieclip all together if you want, here is an example with a bitmap move/lineTo function:
Code:
var bmd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xFFFFFF);
var bm:Bitmap = new Bitmap(bmd);
addChild(bm);
var lineX:Number = 100;
var lineY:Number = 100;
var deltaX:Number = 10;
var deltaY:Number = 10;
bitmapMoveTo(new Point(lineX,lineY));
var lineInterval:uint = setInterval (moveline, 1);
function moveline():void {
lineX += deltaX;
lineY += deltaY;
if (lineX > stage.stageWidth) {
lineX = 0;
}
if (lineX < 0) {
lineX = stage.stageWidth;
}
if (lineY > stage.stageHeight) {
lineY = 0;
}
if (lineY < 0) {
lineY = stage.stageHeight;
}
bitmapLineTo(bmd, new Point(lineX, lineY), 0xCCCCCC);
}
var lastPosFlag:Point = new Point(0, 0);
function bitmapMoveTo(p:Point):void {
lastPosFlag = p.clone();
}
function bitmapLineTo(bmd:BitmapData, e:Point, c:uint):void {
var s:Point = lastPosFlag.clone();
lastPosFlag = e.clone();
var steep:Boolean = Math.abs(e.y - s.y) > Math.abs(e.x - s.x);
if(steep){
s.x ^= s.y
s.y ^= s.x
s.x ^= s.y
e.x ^= e.y
e.y ^= e.x
e.x ^= e.y
}
if(s.x > e.x){
s.x ^= e.x
e.x ^= s.x
s.x ^= e.x
s.y ^= e.y
e.y ^= s.y
s.y ^= e.y
}
var deltaX:int = e.x - s.x;
var deltaY:int = Math.abs(e.y - s.y);
var error:int = 0;
var ystep:int = s.y < e.y ? 1 : -1;
var y:int = s.y;
for(var x:int = s.x; x < e.x; x++){
if(steep){
bmd.setPixel32(y, x, c);
} else {
bmd.setPixel32(x, y, c);
}
error += deltaY;
if( (error << 1) >= deltaX){
y += ystep;
error -= deltaX;
}
}
}
-
Thanks. I ended up using method one as it drew anti aliased lines, unlike method 2. Thank you for your help.
-
For complex drawings, the bitmap technique is certainly the way to go. It works here too, of course. But this seems to be quite simple, and I think all you really had to do was add a linedrawing.graphics.clear() call in there to prevent the accumulation of redundant line segment vector data.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|