By Zevan | December 30, 2009
Actionscript:
-
var boxA:Shape = Shape(addChild(new Shape()));
-
with (boxA.graphics) beginFill(0), drawRect(-10,-10,20,20);
-
-
var boxB:Shape = Shape(addChild(new Shape()));
-
with (boxB.graphics) beginFill(0), drawRect(-10,-10,20,20);
-
-
boxA.x = 100;
-
boxA.y = 100;
-
-
boxB.x = 200;
-
boxB.y = 100;
-
-
var rot:Number = 32750;
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
rot += 1
-
// will stop rotating
-
boxA.rotation = rot
-
// will keep rotating
-
boxB.rotation = rot % 360;
-
}
I recently became aware of a strange aspect of the rotation property on DisplayObjects. For some reason, once it's value goes a little beyond ~32750 the DisplayObject will simply stop rotating. If you read the rotation property it is still changing, but there is no visual update - a quick check on the DisplayObject.transform.matrix property will show that the value has stopped.
The easy fix is to use mod before applying the value to the rotation property. Surprised I've never come across this one before. Maybe someone can shed some light on this.
// for people searching google for solutions to this problem I'll add the following key words:
MovieClip stops rotating, DisplayObject stops rotating, rotation property broken, not rotating
Also posted in misc, motion | Tagged actionscript, as3, flash |
By Zevan | August 30, 2009
Actionscript:
-
[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
-
stage.quality = "medium";
-
var frame:Sprite = Sprite(addChild(new Sprite()));
-
with (frame.graphics) beginFill(0xCCCCCC), drawRect(-200, -200, 400, 400), endFill();
-
frame.x = stage.stageWidth / 2;
-
frame.y = stage.stageHeight / 2;
-
frame.z = 100;
-
-
var canvas:Shape = Shape(frame.addChild(new Shape()));
-
var msk:Shape = Shape(frame.addChild(new Shape()));
-
with (msk.graphics) beginFill(0x00FF00), drawRect(-200, -200, 400, 400), endFill();
-
canvas.mask = msk
-
-
var txt:TextField = TextField(addChild(new TextField()));
-
txt.defaultTextFormat = new TextFormat("_sans", 12);
-
txt.x = txt.y = 10;
-
txt.textColor = 0xFFFFFF, txt.autoSize="left", txt.text = "Draw on the 3D plane...";
-
-
stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
-
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
-
function onDown(evt:MouseEvent):void{
-
canvas.graphics.lineStyle(4, 0x000000);
-
var pnt:Point = frame.globalToLocal(new Point(mouseX, mouseY));
-
canvas.graphics.moveTo(pnt.x, pnt.y);
-
addEventListener(Event.ENTER_FRAME, onDraw);
-
}
-
function onUp(evt:MouseEvent):void{
-
removeEventListener(Event.ENTER_FRAME, onDraw);
-
}
-
-
var t:Number = 0;
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
frame.rotationY = 35 * Math.sin(t);
-
frame.rotationX = 35 * Math.cos(t);
-
t+=0.02;
-
}
-
-
function onDraw(evt:Event):void {
-
var pnt:Point = frame.globalToLocal(new Point(mouseX, mouseY));
-
canvas.graphics.lineTo(pnt.x, pnt.y);
-
}
This demo shows that globalToLocal() works with 3D - saving us the trouble of doing some extra math if we want to draw on 3D display objects...
Have a look at the swf....
Was made aware of this trick by watching a video that kevinSuttle sent me via twitter. The video is an interview with Chris Nuuja (one of the flash player engineers).
Actionscript:
-
var grid:Sprite = Sprite(addChild(new Sprite()));
-
var matrix:Matrix = new Matrix();
-
// make the grid sprite look isometric using the transform.matrix property
-
matrix.rotate(Math.PI / 4);
-
matrix.scale(1, 0.5);
-
matrix.translate(stage.stageWidth / 2, stage.stageHeight / 2);
-
grid.transform.matrix = matrix;
-
-
// draw a grid of circles to show that it does in fact look isometric
-
var rowCol:Number = 8;
-
var num:Number = rowCol * rowCol;
-
-
var diameter:Number = 40;
-
var radius:Number = diameter / 2;
-
var space:Number = diameter + 10;
-
var halfGridSize:Number = rowCol * space / 2;
-
-
grid.graphics.beginFill(0xFF0000);
-
for (var i:int = 0; i<num; i++){
-
grid.graphics.drawCircle(i % 8 * space - halfGridSize, int(i / 8) * space - halfGridSize, radius);
-
}
This snippet shows how to use transform.matrix to make a DisplayObject look isometric. This can also be achieved with nesting.
In the case of this grid of red circles, we rotate it 45 degrees, scale it 50% on the y and move it to the center of the stage (lines 4-6).
Actionscript:
-
// make a complex poly and position it randomly
-
var poly:Sprite = Sprite(addChild(new Sprite()));
-
poly.graphics.lineStyle(3, 0xFF0000);
-
poly.graphics.beginFill(0x00FF00);
-
for (var i:int = 0; i<10; i++) {
-
poly.graphics.lineTo(Math.random()*100 - 50, Math.random()*100 - 50);
-
}
-
poly.x=Math.random()*stage.stageWidth;
-
poly.y=Math.random()*stage.stageHeight;
-
-
// get bound information:
-
-
// is in pixels (whole numbers)
-
trace("pixelBounds: ", poly.transform.pixelBounds);
-
// doesn't include stroke width
-
trace("getBounds: ", poly.getBounds(this));
-
// includes stroke width
-
trace("getRect: ", poly.getRect(this));
Three different ways to get the boundaries of a DisplayObject.