views:

28

answers:

1

When drawing parallel vertical lines with a fixed distance between them (1.75 pixels) with a non-integer x-value-offset to both lines, the lines are drawn differently based on the offset. In the picture below are two pairs of very close together vertical lines. As you can see, they look very different. This is frustrating, especially when animating the sprite.

alt text

Any ideas how ensure that sprites-with-non-integer-positions' graphics will visually display the same?

package
{

import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;

public class tmpa extends Sprite
{

private var _sp1:Sprite;
private var _sp2:Sprite;
private var _num:Number;

public function tmpa( ):void
{
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    _sp1 = new Sprite( );
    drawButt( _sp1, 0 );
    _sp1.x = 100;
    _sp1.y = 100;

    _num = 0;
    _sp2 = new Sprite( );
    drawButt( _sp2, _num );
    _sp2.x = 100;
    _sp2.y = 200;

    addChild( _sp1 );
    addChild( _sp2 );

    addEventListener( Event.ENTER_FRAME, efCb, false, 0, true );
}

private function efCb( evt:Event ):void
{   _num += .1;
    if (_num > 400)
    {   _num = 0;
    }
    drawButt( _sp2, _num );
}

private function drawButt( sp:Sprite, offset:Number ):void
{
    var px1:Number = 1 + offset;
    var px2:Number = 2.75 + offset;

    sp.graphics.clear( );
    sp.graphics.lineStyle( 1, 0, 1, true );
    sp.graphics.moveTo( px1, 1 );
    sp.graphics.lineTo( px1, 100 );

    sp.graphics.lineStyle( 1, 0, 1, true );
    sp.graphics.moveTo( px2, 1 );
    sp.graphics.lineTo( px2, 100 );
}

}
}

edit from original post which thought the problem was tied to the x-position of the sprite.

+1  A: 

although flash internally uses twips, when rendering it can still only render to full pixels. There is no way (that I know of) to fix this, other than casting to an int before setting the .x position. You would then have to have a Number that keeps the actual floating point position, and cast it to an int before setting .x

Edit:

private function drawButt( sp:Sprite, offset:Number ):void
{
    var px1:int = 1 + offset;
    var px2:Number = px1 + 1.75;

    sp.graphics.clear( );
    sp.graphics.lineStyle( 1, 0, 1, true );
    sp.graphics.moveTo( px1, 1 );
    sp.graphics.lineTo( px1, 100 );

    sp.graphics.lineStyle( 1, 0, 1, true );
    sp.graphics.moveTo( px2, 1 );
    sp.graphics.lineTo( px2, 100 );
}
jonathanasdf
Thank you for your comment. It encouraged me to edit the post and remove the x-position of the sprite as a way to simplify the description of this problem. Since there are times when the sub-pixel space between the lines can be rendered, I guess my challenge is to find out what those conditions are.
jedierikb
ahh.. my mistake for misunderstanding.But as I said, flash cannot render on sub-pixels. I don't remember how it's rounded but the value definitely is rounded before being drawn. So the only way to ensure that they are the same is to cast it to an int yourself before drawing. I don't know why you MUST use sub-pixels, but if you just cast px1 to an int and then add 1.75 to it to get px2, you will still be able to have the lines be offset 1.75 from each other and they should visually be the same. I've edited that into my post.
jonathanasdf