First of all, I think your issue may be the type casting that you're doing:
[source]
//Square draw function
public function draw(ratio:Number):void
{
renderPosition.x = int(position.x * ratio + prevPosition.x * (1 - ratio));
renderPosition.y = int(position.y * ratio + prevPosition.y * (1 - ratio));
Main.canvas.copyPixels(image, image.rect, renderPosition);
}
[/source]
In Flash, because you can do sub-pixel rendering, decimal values are used for x/y positioning. I have a feeling that the jumping you're seeing is because of the blind rounding that happens when casting to an int from a real. Maybe this will help?
[source]
//Square draw function
public function draw(ratio:Number):void
{
renderPosition.x = Number(position.x * ratio + prevPosition.x * (1 - ratio));
renderPosition.y = Number(position.y * ratio + prevPosition.y * (1 - ratio));
Main.canvas.copyPixels(image, image.rect, renderPosition);
}
[/source]
I also note that you're copying the square graphic to what I'm guessing is a mx.containers.Canvas instance. I don't want to presume anything but from the code I don't see any reason to be doing this. If it's a vector or bitmap graphic, you can use a Sprite or maybe even a Bitmap instance. It'll make your code cleaner and it should work faster than any custom blitting or pixel copy system.
For example:
[source]
var myGraphic:Sprite=new Sprite();
myGraphic.addchild(squareGraphic); //or draw or load it - this is very generic
[/source]
Subsequently you won't need the render function since the above has already rendered the graphic. So your new update function would be:
[source]
//Square draw function
public function draw(ratio:Number):void
{
myGraphic.x = Number(position.x * ratio + prevPosition.x * (1 - ratio));
myGraphic.y = Number(position.y * ratio + prevPosition.y * (1 - ratio));
}
[/source]
That all being said, you would probably save yourself some time and frustration by using a tweening system (Flash's or something like Greensock, for example). You tell it which object to move, the start position, end position, and interval -- it takes care of moving the graphic. All of the graphics properties should always be available so you can always calculate collisions (or whetever) on every motion increment, and of course you can stop, reset, and rewind any animation. You can also just get the tweener to dispatch events instead of affecting the graphic (you then update the graphic position based on where the tweener tells you to).
Have a look here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/transitions/Tween.html
Unless there's a compelling reason to move graphics around like you're doing, the solution that you've implemented is WAY too complicated and error-prone, not to mention limiting (tweens also do accelerations/decelerations and other nice effects).
Without seeing your ultimate application, here's how I would tackle graphic motion:
[source]
import flash.display.*;
import fl.transitions.Tween;
import fl.transitions.tweening.Regular; //Regular tweening equations; others include Strong, Elastic, Bounce, etc.
import fl.transitions.TweenEvent;
private var motionXTween:Tween;
private var motionYTween:Tween;
public function createSquare():Sprite {
//only need to create the square once!
var returnSquare:Sprite=new Sprite();
returnSquare.graphics.lineStyle(1,0x000000); //Black line, 1 pixel thick
returnSquare.graphics.moveTo(0,0);
returnSquare.graphics.beginFill(0xFF0000,1); //Red fill, 100% (1) opacity
returnSquare.graphics.lineTo(0,100); //Draw the 100x100 square...
returnSquare.graphics.lineTo(100,100);
returnSquare.graphics.lineTo(100,0);
returnSquare.graphics.lineTo(0,0);
returnSquare.graphics.endFill();
return (returnSquare);
}
public function onSquareMove(eventObj:TweenEvent):void {
if (eventObj.target== this.motionXTween) {
trace ("Square is now at X position: "+eventObj.position);
}
if (eventObj.target== this.motionYTween) {
trace ("Square is now at Y position: "+eventObj.position);
}
}
public function moveSquareTo(targetXPos:Number, targetYPos:Number):void {
var moveSquare:Sprite=this.createSquare();
this.stage.addChild(moveSquare);
this.motionXTween=new Tween(moveSquare, "x", Regular, moveSquare.x, targetXPos, 1, true); //Move "moveSquare", on "x" axis, using Regular tweening, from "moveSquare.x", to tagetXPos, using a duration of 1, in seconds
this.motionXTween.addEventListener(TweenEvent.MOTION_CHANGE, this.onSquareMove); //Call the onSquareMove function on every motion update -- completely optional!
this.motionXTween.start();
//Do the same thing for the Y axis...
this.motionYTween=new Tween(moveSquare, "y", Regular, moveSquare.y, targetYPos, 1, true);
this.motionYTween.addEventListener(TweenEvent.MOTION_CHANGE, this.onSquareMove);
this.motionYTween.start();
}
[/source]
You could probably shrink this code down a bit more but this is the essence of both creating the graphic and then moving it using a tween. You can also get rid of the onSquareMove event listener since it doesn't do anything except tell you where the square is while moving.
As I said, I'm making assumptions here; if you're loading the square then there are an extra couple of steps, and if you really do need to move the square around at the pixel level then it's best to combine your copyPixels call with the Tween event (use the event listener to assign the X/Y values instead of calculating them).
Hope this helps, and Merry Christmas!