Category Archives: DisplayObject

Rotation Property Weirdness

Actionscript:
  1. var boxA:Shape = Shape(addChild(new Shape()));
  2. with (boxA.graphics) beginFill(0), drawRect(-10,-10,20,20);
  3.  
  4. var boxB:Shape = Shape(addChild(new Shape()));
  5. with (boxB.graphics) beginFill(0), drawRect(-10,-10,20,20);
  6.  
  7. boxA.x = 100;
  8. boxA.y = 100;
  9.  
  10. boxB.x = 200;
  11. boxB.y = 100;
  12.  
  13. var rot:Number = 32750;
  14.  
  15. addEventListener(Event.ENTER_FRAME, onLoop);
  16. function onLoop(evt:Event):void {
  17.   rot += 1
  18.   // will stop rotating
  19.   boxA.rotation = rot
  20.   // will keep rotating
  21.   boxB.rotation = rot % 360;
  22. }

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 , , | 1 Comment

globalToLocal() in 3D

Actionscript:
  1. [SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
  2. stage.quality = "medium";
  3. var frame:Sprite = Sprite(addChild(new Sprite()));
  4. with (frame.graphics) beginFill(0xCCCCCC), drawRect(-200, -200, 400, 400), endFill();
  5. frame.x = stage.stageWidth / 2;
  6. frame.y = stage.stageHeight / 2;
  7. frame.z = 100;
  8.  
  9. var canvas:Shape = Shape(frame.addChild(new Shape()));
  10. var msk:Shape = Shape(frame.addChild(new Shape()));
  11. with (msk.graphics) beginFill(0x00FF00), drawRect(-200, -200, 400, 400), endFill();
  12. canvas.mask = msk
  13.  
  14. var txt:TextField = TextField(addChild(new TextField()));
  15. txt.defaultTextFormat = new TextFormat("_sans", 12);
  16. txt.x = txt.y = 10;
  17. txt.textColor = 0xFFFFFF, txt.autoSize="left", txt.text = "Draw on the 3D plane...";
  18.  
  19. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  20. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  21. function onDown(evt:MouseEvent):void{
  22.     canvas.graphics.lineStyle(4, 0x000000);
  23.     var pnt:Point = frame.globalToLocal(new Point(mouseX, mouseY));
  24.     canvas.graphics.moveTo(pnt.x, pnt.y);
  25.     addEventListener(Event.ENTER_FRAME, onDraw);
  26. }
  27. function onUp(evt:MouseEvent):void{
  28.     removeEventListener(Event.ENTER_FRAME, onDraw);
  29. }
  30.  
  31. var t:Number = 0;
  32. addEventListener(Event.ENTER_FRAME, onLoop);
  33. function onLoop(evt:Event):void {
  34.     frame.rotationY = 35 * Math.sin(t);
  35.     frame.rotationX = 35 * Math.cos(t);
  36.     t+=0.02;
  37. }
  38.  
  39. function onDraw(evt:Event):void {
  40.         var pnt:Point = frame.globalToLocal(new Point(mouseX, mouseY));
  41.     canvas.graphics.lineTo(pnt.x, pnt.y);
  42. }

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).

Also posted in 3D, Graphics, misc, motion | Tagged , , | 3 Comments

Isometric Transformation Matrix

Actionscript:
  1. var grid:Sprite = Sprite(addChild(new Sprite()));
  2. var matrix:Matrix = new Matrix();
  3. // make the grid sprite look isometric using the transform.matrix property
  4. matrix.rotate(Math.PI / 4);
  5. matrix.scale(1, 0.5);
  6. matrix.translate(stage.stageWidth / 2, stage.stageHeight / 2);
  7. grid.transform.matrix = matrix;
  8.  
  9. // draw a grid of circles to show that it does in fact look isometric
  10. var rowCol:Number = 8;
  11. var num:Number = rowCol * rowCol;
  12.  
  13. var diameter:Number = 40;
  14. var radius:Number = diameter / 2;
  15. var space:Number = diameter + 10;
  16. var halfGridSize:Number = rowCol * space / 2;
  17.  
  18. grid.graphics.beginFill(0xFF0000);
  19. for (var i:int = 0; i<num; i++){
  20.    grid.graphics.drawCircle(i % 8 * space - halfGridSize, int(i / 8) * space - halfGridSize, radius);
  21. }

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).

Also posted in misc | 3 Comments

Bounds 3 Ways

Actionscript:
  1. // make a complex poly and position it randomly
  2. var poly:Sprite = Sprite(addChild(new Sprite()));
  3. poly.graphics.lineStyle(3, 0xFF0000);
  4. poly.graphics.beginFill(0x00FF00);
  5. for (var i:int = 0; i<10; i++) {
  6.     poly.graphics.lineTo(Math.random()*100 - 50, Math.random()*100 - 50);
  7. }
  8. poly.x=Math.random()*stage.stageWidth;
  9. poly.y=Math.random()*stage.stageHeight;
  10.  
  11. // get bound information:
  12.  
  13. // is in pixels (whole numbers)
  14. trace("pixelBounds: ", poly.transform.pixelBounds);
  15. // doesn't include stroke width
  16. trace("getBounds: ", poly.getBounds(this));
  17. // includes stroke width
  18. trace("getRect: ", poly.getRect(this));

Three different ways to get the boundaries of a DisplayObject.

Posted in DisplayObject | Tagged , | 1 Comment