Actionscript:
-
var circs:Array = []
-
var circNum:int = 600;
-
addEventListener(Event.ENTER_FRAME, onAdd);
-
function onAdd(evt:Event):void {
-
if (circs.length <circNum){
-
makeGrowable();
-
}
-
}
-
-
function makeGrowable(){
-
-
var s:MovieClip = MovieClip(addChild(new MovieClip()));
-
s.x = Math.random() * stage.stageWidth;
-
s.y = Math.random() * stage.stageHeight;
-
with(s.graphics){
-
lineStyle(0,0);
-
drawCircle(0,0,10);
-
}
-
s.scaleX = s.scaleY = 0;
-
circs.push(s);
-
s.addEventListener(Event.ENTER_FRAME, onScaleUp);
-
}
-
-
function onScaleUp(evt:Event):void {
-
var c:MovieClip = MovieClip(evt.currentTarget);
-
c.scaleX = c.scaleY += 0.05;
-
for (var i:int = 0; i<circs.length; i++){
-
var circ:MovieClip = circs[i];
-
if (circ != c){
-
var amt:Number = circ.width/2 + c.width/2;
-
var dx:Number = circ.x - c.x;
-
var dy:Number = circ.y - c.y;
-
var dist:Number = Math.sqrt(dx * dx + dy * dy);
-
if (amt> dist){
-
c.removeEventListener(Event.ENTER_FRAME, onScaleUp);
-
if (c.scaleX <0.1){
-
if (contains(c)){
-
removeChild(c);
-
}
-
}
-
}
-
}
-
-
}
-
}
Circle fitting is one of those things I've never bothered to do... today I figured I'd give it a try and this is what I came up with. I posted it on wonderfl:
Also posted in Graphics, misc | Tagged actionscript, as3, flash, s |
Actionscript:
-
[SWF(width = 500, height=500)]
-
var ring:MovieClip = createRing();
-
ring.x = stage.stageWidth / 2;
-
ring.y = stage.stageHeight / 2;
-
addChild(ring);
-
-
function createRing(sectionNum:int = 30):MovieClip{
-
var container:MovieClip = new MovieClip();
-
container.circles = [];
-
container.theta = 0;
-
container.thetaDest = 0;
-
var step:Number = (Math.PI * 2) / sectionNum;
-
for (var i:int = 0; i<sectionNum; i++){
-
var c:MovieClip = new MovieClip();
-
with (c.graphics){
-
lineStyle(0,0x000000);
-
beginFill(0xCCCCCC);
-
drawCircle(0,0,20);
-
}
-
c.thetaOffset = step * i;
-
container.addChild(c);
-
container.circles.push(c);
-
}
-
container.addEventListener(Event.ENTER_FRAME, onRun);
-
return container;
-
}
-
function onRun(evt:Event):void {
-
var container:MovieClip = MovieClip(evt.currentTarget);
-
var num:int = container.circles.length;
-
for (var i:int = 0; i<num; i++){
-
var c:MovieClip = container.circles[i];
-
var angle:Number = container.theta + c.thetaOffset;
-
c.x = 200 * Math.cos(angle);
-
c.y = 100 * Math.sin(angle);
-
c.scaleX = (100 + c.y) / 120 + 0.2;
-
c.scaleY = c.scaleX;
-
}
-
container.circles.sortOn("y", Array.NUMERIC);
-
for (i = 0; i<num; i++){
-
container.addChild(container.circles[i]);
-
}
-
if (container.mouseX <-100){
-
container.thetaDest -= 0.05;
-
}
-
if (container.mouseX> 100){
-
container.thetaDest += 0.05;
-
}
-
container.theta += (container.thetaDest - container.theta) / 12;
-
-
}
This snippet shows how to create a 3D ring navigation using sine and cosine. Have a look:
Actionscript:
-
makeFlyer();
-
-
function makeFlyer():void{
-
var thing:MovieClip = new MovieClip();
-
thing.x = 200;
-
thing.y = 200;
-
-
addChild(thing);
-
-
var prop:Shape = new Shape();
-
with (prop.graphics){
-
lineStyle(0,0x000000);
-
beginFill(0x000000);
-
moveTo(-100,0);
-
curveTo(-100, -30, 0, 0);
-
curveTo(100, 30, 100, 0);
-
curveTo(100, -30, 0, 0);
-
curveTo(-100, 30, -100, 0);
-
}
-
prop.scaleX = prop.scaleY = 0.5;
-
var container:MovieClip = new MovieClip();
-
//container.x = -50;
-
container.addChild(prop);
-
container.scaleY = 0.6;
-
thing.addChild(container);
-
-
var body:Shape = new Shape();
-
with (body.graphics){
-
lineStyle(0, 0x000000);
-
beginFill(0x000000);
-
lineTo(0,80);
-
drawCircle(0,80,10);
-
}
-
thing.addChild(body);
-
thing.velX = 0;
-
thing.velY = 0;
-
thing.posX = thing.x;
-
thing.posY = thing.y;
-
thing.theta = 0;
-
thing.prop = prop;
-
thing.addEventListener(Event.ENTER_FRAME, onRun);
-
}
-
function onRun(evt:Event):void{
-
var t:MovieClip = MovieClip(evt.currentTarget);
-
t.prop.rotation += 10
-
t.velY = 3 * Math.cos(t.theta);
-
t.velX = 3 * Math.sin(t.theta / 2);
-
t.theta += 0.05
-
t.posX += t.velX;
-
t.posY += t.velY;
-
-
t.x = t.posX;
-
t.y = t.posY;
-
}
This snippet creates a small flying object that moves with sine and cosine.
Have a look at the swf...

Posted in motion | Tagged actionscript, as3, flash |
By Zevan | April 24, 2010
Actionscript:
-
var circles:Array = [];
-
for (var i:int = 0; i<30; i++){
-
var c:Sprite = makeCircle();
-
c.x = stage.stageWidth / 2;
-
c.y = stage.stageHeight / 2;
-
c.scaleX = 1 + i/2;
-
c.scaleY = 0.5 + i/4;
-
addChild(c);
-
circles.push(c);
-
}
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
circles[0].y += (mouseY - circles[0].y) / 4;
-
for (var i:int = 1; i<circles.length; i++){
-
var pre:Sprite = circles[i - 1];
-
circles[i].y += (pre.y - circles[i].y) / 4;
-
}
-
}
-
function makeCircle():Sprite{
-
var s:Sprite = new Sprite();
-
with(s.graphics){
-
lineStyle(0,0x000000);
-
drawCircle(0,0,10);
-
}
-
return s;
-
}
This morning I woke up with a vision of this simple mouse toy in my head. I decided I might as well code it up... I may do more simple things like this in the next few days, it's relaxing.
Also posted in Graphics, misc | Tagged actionsnippet, as3, flash |
By Zevan | March 15, 2010
Actionscript:
-
[SWF(width = 500, height=500, backgroundColor=0x000000)]
-
-
var clockNum:int = 100;
-
var clocks:Vector.<Function> = new Vector.<Function>(clockNum, true);
-
-
var clockContainer:Sprite = Sprite(addChild(new Sprite()));
-
clockContainer.x = stage.stageWidth / 2;
-
clockContainer.y = stage.stageHeight / 2;
-
buildClocks();
-
runClocks();
-
-
function buildClocks():void{
-
for (var i:int = 0; i<clockNum; i++){
-
var theta:Number = Math.random() * Math.PI * 2;
-
var radius:Number = Math.random() * 200;
-
var xp:Number = radius * Math.cos(theta);
-
var yp:Number = radius * Math.sin(theta);
-
clocks[i] = makeClock(xp,yp,Math.random() * Math.PI * 2);
-
}
-
}
-
function runClocks():void{
-
addEventListener(Event.ENTER_FRAME, onRunClocks);
-
}
-
function onRunClocks(evt:Event):void{
-
for (var i:int = 0; i<clockNum; i++){
-
clocks[i]();
-
}
-
clockContainer.rotationX = clockContainer.mouseY / 30;
-
clockContainer.rotationY = -clockContainer.mouseX / 30;
-
}
-
function makeClock(x:Number, y:Number, time:Number=0):Function{
-
var radius:Number = Math.random() * 20 + 5;
-
var border:Number = radius * 0.2;
-
var smallRadius:Number = radius - radius * 0.3;
-
-
var clock:Sprite = Sprite(clockContainer.addChild(new Sprite()));
-
clock.x = x;
-
clock.y = y;
-
clock.z = 100 - Math.random() * 200;
-
clock.rotationX = Math.random() * 40 - 20;
-
clock.rotationY = Math.random() * 40 - 20;
-
clock.rotationZ = Math.random() * 360;
-
return function():void{
-
with (clock.graphics){
-
clear();
-
lineStyle(1,0xFFFFFF);
-
drawCircle(0,0,radius + border);
-
var xp:Number = smallRadius * Math.cos(time/2);
-
var yp:Number = smallRadius * Math.sin(time/2);
-
moveTo(0,0);
-
lineTo(xp, yp);
-
xp = radius * Math.cos(time);
-
yp = radius * Math.sin(time);
-
moveTo(0,0);
-
lineTo(xp, yp);
-
}
-
time+=0.1;
-
}
-
}
You can go check the swf out at wonderfl.net...

Also posted in 3D, Graphics, misc | Tagged actionscript, as3, flash |
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
By Zevan | November 25, 2009
Actionscript:
-
var container:Sprite = new Sprite();
-
container.x = stage.stageWidth / 2;
-
container.y = stage.stageHeight / 2;
-
addChild(container);
-
-
var redBox:Sprite = new Sprite();
-
redBox.graphics.beginFill(0xFF0000);
-
redBox.graphics.drawRect(-50,-250,100,500);
-
redBox.rotationZ = 10;
-
container.addChild(redBox);
-
-
var logos:Array = []
-
var elements:Array = [];
-
elements.push({element:redBox, z:0});
-
-
// add the logos
-
for (var i:int = 0; i<6; i++){
-
var logoContainer:MovieClip = new MovieClip();
-
var logoText:TextField = new TextField();
-
logoText.defaultTextFormat = new TextFormat("_sans", 50);
-
logoText.text = "LOGO";
-
logoText.autoSize = "left";
-
logoText.selectable= false;
-
-
logoText.x = -logoText.width / 2;
-
logoText.y = -logoText.height / 2;
-
logoContainer.addChild(logoText);
-
logoText.backgroundColor = 0xFFFFFF;
-
-
container.addChild(logoContainer);
-
logos.push(logoContainer);
-
elements.push({element:logoContainer, z:0});
-
}
-
-
var ang:Number = -Math.PI / 2;
-
var rotationSpeed:Number = 0.05;
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
-
var dx:Number = (mouseY - stage.stageHeight / 2) / 10;
-
var dy:Number = (mouseX - stage.stageWidth / 2) / 10;
-
container.rotationX += (dx - container.rotationX) / 4;
-
container.rotationY += (dy - container.rotationY) / 4;
-
-
ang += rotationSpeed;
-
for (var i:int = 0; i<logos.length; i++){
-
var logo:Sprite = logos[i];
-
logo.x = 150 * Math.cos(ang + i);
-
logo.z = 150 * Math.sin(ang + i);
-
logo.alpha = 1 - logo.z / 200;
-
logo.rotationY = -Math.atan2(logo.z, logo.x) / Math.PI * 180 - 90;
-
}
-
-
// z-sort
-
for (i = 0; i<elements.length; i++){
-
elements[i].z = elements[i].element.transform.getRelativeMatrix3D(this).position.z;
-
}
-
-
elements.sortOn("z", Array.NUMERIC | Array.DESCENDING);
-
for (i = 0; i<elements.length; i++) {
-
container.addChild(elements[i].element);
-
}
-
}
A student of mine was having trouble creating a 3D logo for a client. I created this snippet to help explain how some of the fp10 3D stuff works.... z-sorting etc... The code could be optimized a bit... but it works nicely...
Have a look at the swf...

Also posted in 3D, misc | Tagged actionscript, as3, flash, fp10 |
Actionscript:
-
package {
-
import flash.display.Shape;
-
import flash.display.Sprite;
-
import flash.geom.Point;
-
-
/**
-
* Re: http://board.flashkit.com/board/showthread.php?t=797453
-
* @author makc
-
* @license WTFPLv2
-
*/
-
public class BouncingBall extends Sprite{
-
public function BouncingBall () {
-
r = 10;
-
ball = new Shape;
-
ball.graphics.beginFill (0);
-
ball.graphics.drawCircle (0, 0, r);
-
addChild (ball);
-
v = new Point;
-
v.x = Math.random ();
-
v.y = Math.random ();
-
V = 1 + 20 * Math.random ();
-
v.normalize (V);
-
R = 200; X = 465 / 2; Y = 465 / 2;
-
graphics.lineStyle (0);
-
graphics.drawCircle (X, Y, R);
-
ball.x = X + 100;
-
ball.y = Y - 100;
-
addEventListener ("enterFrame", loop);
-
}
-
private var r:Number;
-
private var ball:Shape;
-
private var v:Point;
-
private var V:Number;
-
private var R:Number;
-
private var X:Number;
-
private var Y:Number;
-
private function loop (e:*):void {
-
ball.x += v.x;
-
ball.y += v.y;
-
// R-r vector
-
var P:Point = new Point (X - ball.x, Y - ball.y);
-
if (P.length> Math.sqrt ((R - r) * (R - r))) {
-
// normalize R-r vector
-
P.normalize (1);
-
// project v onto it
-
var vp:Number = v.x * P.x + v.y * P.y;
-
// subtract projection
-
v.x -= 2 * vp * P.x;
-
v.y -= 2 * vp * P.y;
-
v.normalize (V);
-
// move away from bounding circle
-
P = new Point (X - ball.x, Y - ball.y);
-
while (P.length> Math.sqrt ((R - r) * (R - r))) {
-
ball.x += v.x;
-
ball.y += v.y;
-
P = new Point (X - ball.x, Y - ball.y);
-
}
-
}
-
}
-
}
-
}
Makc3d said I could choose one of his excellent wonderfl.net pieces and submit it to the contest. This snippet creates a ball that bounces off the inside of a circle. I thought this was a pretty unique way to go about doing this - and found it easy to add gravity and other cool features to it.
Have a look at the swf over at wonderfl....
Some Makc3d links:
>> http://makc3d.wordpress.com/
>>http://code.google.com/p/makc/
>> http://wonderfl.net/user/makc3d
Makc3d elaborated on his code a bit via e-mail. He said that his technique sacrifices accuracy for simplicity... and that if you simplify too much it would be easy to break the code. "e.g. comment out piece of code where it says "move away from bounding circle""...
Here is a picture that Makc3d drew explaining why you need to multiply by 2:

By Zevan | November 7, 2009
Since the release of QuickBox2D 1.0 two bugs were discovered by numerous developers. The first bug was the inability to properly destroy group objects. The second bug was a small memory leak that caused most QuickObjects to remain in memory. Both of these bugs are now resolved.
Download QuickBox2D 1.1
Testing the memory leak. In QuickBox2D 1.0 if you created and destroyed 100s of rigid bodies, the ram would very slowly rise... Sometimes it would get garbage collected, but the memory would never fully be released. I created a simple test to make sure this is fixed in 1.1:
Actionscript:
-
import com.actionsnippet.qbox.*;
-
-
var sim:QuickBox2D = new QuickBox2D(this, {debug:false});
-
-
sim.createStageWalls();
-
-
var levelParts:Array = [];
-
const TWO_PI:Number = Math.PI * 2;
-
-
// destroys and then creates a bunch of rigid bodies
-
// called every second
-
buildRandomLevel();
-
setInterval(buildRandomLevel, 1000);
-
-
var txt:TextField = TextField(addChild(new TextField()));
-
txt.x = txt.y = 30;
-
txt.backgroundColor = 0xFFFFFF;
-
sim.start();
-
-
// display amount of ram used, to make sure garbage collection is working
-
sim.addEventListener(QuickBox2D.STEP, onStep);
-
function onStep(evt:Event):void{
-
txt.text = (System.totalMemory / 100000).toFixed(2) + "mb";
-
}
-
-
function buildRandomLevel():void{
-
// destroy all rigid bodies
-
for (var i:int = 0; i<levelParts.length; i++){
-
levelParts[i].destroy();
-
}
-
levelParts = [];
-
// create a bunch of circles and boxes
-
for (i = 0; i<16; i++){
-
var rad:Number = 0.4 ;
-
levelParts.push(sim.addCircle({x:1 + i * rad * 4, y : 2, radius:rad - Math.random()*0.3}));
-
-
var rot:Number = Math.random() * TWO_PI;
-
levelParts.push(sim.addBox({x:4+Math.random() * i * 2, y:4+Math.random()*i,
-
width:3, height:0.25, angle:rot, density:0}));
-
}
-
}
This snippet creates and destroys a bunch of rigid bodies again and again.... On my macbook 2.6 Ghz intel core duo... the ram runs between 79mb and 112mb. I let it run for 40 minutes and this did not change - it always eventually returned down to 79mb.
Have a look at the swf...

Thanks to all the people who gave feedback that lead to the discover of these bugs.
By Zevan | October 29, 2009
Actionscript:
-
[SWF(width = 100, height = 100)]
-
var circle:Shape = new Shape();
-
with(circle.graphics) beginFill(0x000000), drawCircle(20,20,20);
-
-
var currFrame:Frame;
-
-
// populate the linked list
-
generateAnimation();
-
-
var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);
-
addChild(new Bitmap(canvas));
-
var loc:Point = new Point(20, 20);
-
-
addEventListener(Event.ENTER_FRAME, onLoop);
-
function onLoop(evt:Event):void {
-
// clear the canvas
-
canvas.fillRect(canvas.rect, 0x000000);
-
// draw the current frame
-
canvas.copyPixels(currFrame.bitmap, currFrame.bitmap.rect, loc, null, null, true);
-
// get the next frame of the animation
-
currFrame = currFrame.next;
-
}
-
-
// generate and capture 40 bitmaps by altering the colorTransform of the circle shape
-
function generateAnimation():void{
-
var channel:uint = 0;
-
var ct:ColorTransform = new ColorTransform();
-
var increase:Boolean = true;
-
var firstFrame:Frame;
-
var pFrame:Frame;
-
for (var i:int = 0; i<40; i++){
-
if (increase){
-
channel += 10;
-
if (channel == 200){
-
increase = false;
-
}
-
}else{
-
channel -= 10;
-
}
-
ct.color = channel <<16 | channel <<8 | channel;
-
circle.transform.colorTransform = ct;
-
// populate linked list
-
currFrame = capture(circle);
-
if (pFrame){
-
pFrame.next = currFrame;
-
}
-
if (i == 0){
-
firstFrame = currFrame;
-
}
-
pFrame = currFrame;
-
}
-
// close the list
-
currFrame.next = firstFrame;
-
currFrame = firstFrame;
-
}
-
-
// create the Frame instance and draw the circle to it
-
// preserving the colorTransform information
-
function capture(target:Shape):Frame{
-
var frame:Frame = new Frame();
-
frame.bitmap = new BitmapData(target.width, target.height, true, 0x00000000);
-
frame.bitmap.draw(target, null, target.transform.colorTransform);
-
return frame;
-
}
Requires this little Frame class
Actionscript:
-
package {
-
import flash.display.*;
-
final public class Frame{
-
public var bitmap:BitmapData;
-
public var next:Frame;
-
}
-
}
This is a small test I did today to see how easy it would be to use a circular linked list to loop an animation of bitmaps. I did this because I was thinking about using some animated sprites in conjunction with Utils3D.projectVectors() to do an orthographic 3D demo with lots of animating sprites. In the past I've had up to 7,000 animated sprites running nicely using arrays and copyPixels... figured it would be interesting to try and do the same with a circular linked list.
When compiled, this test simply draws a circle that fades from black to gray and back again... Pretty boring, but I threw it up over at wonderfl anyway... check it out.
I recently saw a few tweets (forget who from) about using the final keyword on linked list nodes... haven't tested it myself but it's supposed to be faster...