Browse the notebook

Tag: as3

BitmapData Static

var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));

var pix:Vector.<uint> = new Vector.<uint>(canvas.width * canvas.height, true);

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	var i:int = pix.length;
	while(--i > -1){
		var c:uint = uint(Math.random() * 255);
	    pix[i] = c << 16 | c << 8 | c;
	}
	canvas.setVector(canvas.rect, pix);
	canvas.unlock();
}

This is an easy way to fill a BitmapData Object up with a bunch of TV-style static….

This post is meant to serve as filler while I work to get a good solid SIMPLE fp10, drawing api z-sorting example going… There seem to be 3 main ways of doing z-sorting all of which don’t seem right to me for some reason… they all work… but I have a gut feeling there is a faster way… The winner so far (unexpectedly) is using Array.sortOn

Read snippet: BitmapData Static

Gradient Bezier 3D

[SWF(backgroundColor=0x333333, width=800, height=600)];
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
var verts:Vector.<Number>  = new Vector.<Number>();
var tVerts:Vector.<Number> = new Vector.<Number>();
var pVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();

var igraph:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();

var tVect:Vector3D = new Vector3D();
var m:Matrix3D = new Matrix3D();
for (var i:int = 0; i<200; i++){
	for (var j:int = 0; j<3; j++){
		tVect.x = Math.random() * 0.15;
		m.identity();
		m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
		m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
		m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
		tVect = m.transformVector(tVect);
	    verts.push(tVect.x, tVect.y, tVect.z);
	}
	
	var stroke:GraphicsStroke = new GraphicsStroke();
	
	var col:int = [0xFFFFFF, 0x000000, 0xFFCC00, 0xFF0000][int(Math.random() * 4)];
	
    stroke.thickness = 2+(Math.random()*Math.random())*8;
	var mg:Matrix = new Matrix();
	mg.createGradientBox(350+Math.random()*20-10, 350+Math.random()*20-10, 0, -270+i/2,-240+i/2);
	stroke.fill = new GraphicsGradientFill(GradientType.RADIAL, [0xFFFFFF,0x444444], [1, 1], [30, 255], mg);

	var bez:GraphicsPath = new GraphicsPath();
	bez.commands = Vector.<int>([1, 3]);
	igraph.push(stroke);
    igraph.push(bez);
}

var perspective:PerspectiveProjection = new PerspectiveProjection();
perspective.fieldOfView = 45;
var trans:Matrix3D = new Matrix3D();
var proj:Matrix3D = perspective.toMatrix3D();
var dx:Number = 0, dy:Number = 0;

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	dx += (mouseX - dx) / 4;
	dy += (mouseY - dy) / 4;
	   
	trans.identity();
	trans.appendRotation(dy, Vector3D.X_AXIS);
	trans.appendRotation(dx, Vector3D.Y_AXIS);
	trans.appendTranslation(0,0,0.5);
	trans.transformVectors(verts, tVerts);
	Utils3D.projectVectors(proj, tVerts, pVerts, uvts);
	
	var inc:int = 0;
	for (var i:int = 1; i<igraph.length; i+=2){
		GraphicsPath(igraph[i]).data = pVerts.slice(inc, inc + 6);
		inc += 6;
	}
	 
	graphics.clear();
	graphics.drawGraphicsData(igraph);
}

A variation on yesterdays post – this makes use of GraphicsGradientFill to add some depth…

Check out the swf…

Read snippet: Gradient Bezier 3D

3D Bezier

[SWF(backgroundColor=0x000000, width=800, height=600)];
x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
var verts:Vector.<Number>  = new Vector.<Number>();
var tVerts:Vector.<Number> = new Vector.<Number>();
var pVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();

var igraph:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();

var tVect:Vector3D = new Vector3D();
var m:Matrix3D = new Matrix3D();
for (var i:int = 0; i<300; i++){
	for (var j:int = 0; j<3; j++){
		tVect.x = Math.random() * 0.15;
		m.identity();
		m.appendRotation(Math.random()*360, Vector3D.X_AXIS);
		m.appendRotation(Math.random()*360, Vector3D.Y_AXIS);
		m.appendRotation(Math.random()*360, Vector3D.Z_AXIS);
		tVect = m.transformVector(tVect);
	    verts.push(tVect.x, tVect.y, tVect.z);
	}
	
	 
	var stroke:IGraphicsData = new GraphicsStroke();
	
	var col:int = [0xFFFFFF, 0x000000, 0xFFCC00, 0xFF0000][int(Math.random() * 4)];
    with (stroke) thickness = (Math.random()*Math.random())*10, fill = new GraphicsSolidFill(col);

	var bez:GraphicsPath = new GraphicsPath();
	bez.commands = Vector.<int>([1, 3]);
	igraph.push(stroke);
    igraph.push(bez);
}

var perspective:PerspectiveProjection = new PerspectiveProjection();
perspective.fieldOfView = 45;
var trans:Matrix3D = new Matrix3D();
var proj:Matrix3D = perspective.toMatrix3D();
var dx:Number = 0, dy:Number = 0;

addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	dx += (mouseX - dx) / 4;
	dy += (mouseY - dy) / 4;
	   
	trans.identity();
	trans.appendRotation(dy, Vector3D.X_AXIS);
	trans.appendRotation(dx, Vector3D.Y_AXIS);
	trans.appendTranslation(0,0,0.5);
	trans.transformVectors(verts, tVerts);
	Utils3D.projectVectors(proj, tVerts, pVerts, uvts);
	
	var inc:int = 0;
	for (var i:int = 1; i<igraph.length; i+=2){
		GraphicsPath(igraph[i]).data = pVerts.slice(inc, inc + 6);
		inc += 6;
	}
	 
	graphics.clear();
	graphics.drawGraphicsData(igraph);
}

After a few hours of trying to get a super optimized fp10 z-sorting demo happening, I gave up (for now) and decided to just let loose with something easy. The result is this 3D Bezier example…


Check out the swf…

Read snippet: 3D Bezier

Sierpiński Glitch Texture #3

[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
 
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
var canvasRect:Rectangle = canvas.rect;
var w:int = canvas.width;
var w2:Number = 1/w;
var w10:Number = 1/(w * 80);
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
var pix:Vector.<uint> = new Vector.<uint>(size, true);
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var sin:Number = 0, cos:Number = 0;
var dx:Number = 0, dy:Number = 0;
var pnt:Point = new Point();
var blur:BlurFilter = new BlurFilter(10,10,1);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	dx +=  (mouseX * 10 - 3000 - dx) / 8;
	dy +=  (mouseY * 4 - dy) / 8;
	for (var i:int = 0; i<size; i++){
		var xp:int = i % w;
		var yp:int = int(i * w2);
		var xp2:int = xp <<1;
		var t:Number;
		t = ((yp|(xp + yp * 0.1)) * (xp + dx) *w10) % 6.14687;
		//compute sine
		// technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
		// by Michael Baczynski
		if (t<0) {
			sin=1.27323954*t+.405284735*t*t;
		} else {
			sin=1.27323954*t-0.405284735*t*t;
		}
		// compute cosine
		t = (xp2|(yp+xp*0.1) + dy) * convert % 6.28;
		t+=1.57079632;
		if (t>3.14159265) {
			t-=6.28318531;
		}
		if (t<0) {
			cos=1.27323954*t+0.405284735*t*t;
		} else {
			cos=1.27323954*t-0.405284735*t*t;
		}
		var c1:int = 31 * (sin - cos);
		if (c1 <0) c1 = 256 - c1;
		c1 = (c1 <<4 | c1) ;
		pix[i] = c1 <<16 | c1 <<8 | c1;
	}
	canvas.setVector(canvasRect, pix);
	clone.copyPixels(canvas, canvasRect, pnt);
	canvas.draw(clone, m, null, BlendMode.SUBTRACT);
	clone.copyPixels(canvas, canvasRect, pnt);
	clone.applyFilter(clone, canvasRect, pnt, blur);
	canvas.draw(clone, null, null, BlendMode.SCREEN);
	canvas.unlock();
}

Decided to do a grayscale version … also rendered it out large and posted it on flickr…

Check out the swf…


Check out the large flickr version…

Read snippet: Sierpiński Glitch Texture #3

Sierpiński Glitch Texture #2

[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
var canvasRect:Rectangle = canvas.rect;
var w:int = canvas.width;
var w2:Number = 1/w;
var w10:Number = 1/(w * 80);
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
var pix:Vector.<uint> = new Vector.<uint>(size, true);
var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var sin:Number = 0, cos:Number = 0;
var dx:Number = 0, dy:Number = 0;
var pnt:Point = new Point();
var blur:BlurFilter = new BlurFilter(10,10,1);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	dx += (mouseX * 10 - 3000 - dx) / 8;
	dy += (mouseY * 4 - dy) / 8;
	for (var i:int = 0; i<size; i++){
		var xp:int = i % w;
		var yp:int = int(i * w2);
		var xp2:int = xp <<1;
		var t:Number;
		t = ((yp|(xp + yp)) * (xp + dx) *w10) % 6.14687;
		//compute sine
		// technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
		// by Michael Baczynski
		if (t<0) {
			sin=1.27323954*t+.405284735*t*t;
		} else {
			sin=1.27323954*t-0.405284735*t*t;
		}
		// compute cosine
		t = (xp2|(yp+xp/dx) + dy) * convert % 6.28;
		t+=1.57079632;
		if (t>3.14159265) {
			t-=6.28318531;
		}
		if (t<0) {
			cos=1.27323954*t+0.405284735*t*t;
		} else {
			cos=1.27323954*t-0.405284735*t*t;
		}
		var c1:int = 31 * (sin - cos);
		if (c1 <0) c1 = 256 - c1;
		c1 = (c1 >>1  | c1) ;
		pix[i] = c1 <<17 | c1 <<8 | c1;
	}
	canvas.setVector(canvasRect, pix);
	clone.copyPixels(canvas, canvasRect, pnt);
	canvas.draw(clone, m, null, BlendMode.SUBTRACT);
	clone.copyPixels(canvas, canvasRect, pnt);
	clone.applyFilter(clone, canvasRect, pnt, blur);
	
	canvas.draw(clone, null, null, BlendMode.LIGHTEN);
	canvas.applyFilter(canvas, canvasRect, pnt, gray);
	canvas.unlock();
}

More texture experimentation…

Have a look at the swf over at wonderfl.net…

Read snippet: Sierpiński Glitch Texture #2

Sierpiński Glitch Texture #1

[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
var canvasRect:Rectangle = canvas.rect;
var w:int = canvas.width;
var w2:Number = 1/w;
var w10:Number = 1/(w * 80);
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
var pix:Vector.<uint> = new Vector.<uint>(size, true);
var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var sin:Number = 0, cos:Number = 0;
var dx:Number = 0, dy:Number = 0;
var pnt:Point = new Point();
var blur:BlurFilter = new BlurFilter(10,10,1);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	dx += (mouseX * 10 - 3000 - dx) / 8;
	dy += (mouseY * 4 - dy) / 8;
	for (var i:int = 0; i<size; i++){
		var xp:int = i % w;
		var yp:int = int(i * w2);
		var xp2:int = xp <<1;
		var t:Number;
		t = ((yp|xp) * (xp + dx) *w10) % 6.14687;
		
		//compute sine
		// technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
		// by Michael Baczynski
		if (t<0) {
			sin=1.27323954*t+.405284735*t*t;
		} else {
			sin=1.27323954*t-0.405284735*t*t;
		}
		// compute cosine
		t = (xp2 + dy) * convert % 6.28;
		t+=1.57079632;
		if (t>3.14159265) {
			t-=6.28318531;
		}
		if (t<0) {
			cos=1.27323954*t+0.405284735*t*t;
		} else {
			cos=1.27323954*t-0.405284735*t*t;
		}
		var c1:int = 31 * (sin - cos);
		if (c1 <0) c1 = 256 - c1;
		c1 = (c1 <<3 | c1) ;
		pix[i] = c1 <<15 | c1 <<8 | c1;
	}
	canvas.setVector(canvasRect, pix);
	clone.copyPixels(canvas, canvasRect, pnt);
	canvas.draw(clone, m, null, BlendMode.SUBTRACT);
	clone.copyPixels(canvas, canvasRect, pnt);
	clone.applyFilter(clone, canvasRect, pnt, blur);
	canvas.draw(clone, null, null, BlendMode.ADD);
	canvas.unlock();
}

More strange real-time texture generation. This one is particularly glitchy looking with hints of Sierpiński.


Check out the swf at wonderfl.net…

Read snippet: Sierpiński Glitch Texture #1

Interesting Texture #3 (animated)

[SWF(frameRate=60, backgroundColor=0x000000, width=500, height=500)]
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var clone:BitmapData = new BitmapData(500,500,false, 0x000000);
var canvasRect:Rectangle = canvas.rect;
var w:int = canvas.width;
var w2:Number = 1/w;
var w10:Number = 1/(w * 80);
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
var pix:Vector.<uint> = new Vector.<uint>(size, true);
var gray:ColorMatrixFilter = new ColorMatrixFilter([1, 0.55, 0.55, 0,0,0.55, 0.9, 0.55, 0,0,0.55, 0.55, 0.550,0, 0,0,0,1,0]);
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var sin:Number = 0, cos:Number = 0;
var dx:Number = 0, dy:Number = 0;
var pnt:Point = new Point();
var blur:BlurFilter = new BlurFilter(10,10,1);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	canvas.lock();
	dx += (mouseX * 10 - 3000 - dx) / 8;
	dy += (mouseY * 4 - dy) / 8;
	for (var i:int = 0; i<size; i++){
		var xp:int = i % w;
		var yp:int = int(i * w2);
		var xp2:int = xp << 1;
		var t:Number = (yp * (xp2 + dx) * w10) % 3.14687;
		//compute sine
		// technique from http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
		// by Michael Baczynski
		if (t<0) {
			sin=1.27323954*t+.405284735*t*t;
		} else {
			sin=1.27323954*t-0.405284735*t*t;
		}
		// compute cosine
		t = (xp2 + dy) * convert % 6.28;
		t+=1.57079632;
		if (t>3.14159265) {
			t-=6.28318531;
		}
		if (t<0) {
			cos=1.27323954*t+0.405284735*t*t;
		} else {
			cos=1.27323954*t-0.405284735*t*t;
		}
		var c1:int = 31 * (cos - sin);
		if (c1 <0) c1 = 256 - c1;
		c1 = (c1 <<2 | c1) ;
		pix[i] = c1 <<15 | c1 <<9 | c1;
	}
	canvas.setVector(canvasRect, pix);
	clone.copyPixels(canvas, canvasRect, pnt);
	canvas.draw(clone, m, null, BlendMode.SUBTRACT);
	clone.copyPixels(canvas, canvasRect, pnt);
	clone.applyFilter(clone, canvasRect, pnt, blur);
	canvas.draw(clone, null, null, BlendMode.ADD);
	canvas.applyFilter(canvas, canvas.rect, new Point(0,0), gray);
	canvas.unlock();
}

This snippet creates an interactive animated texture. Originally this texture wasn an unoptimized messy code snippet (see the original post here) – I went through and did a few optimizations to get it running in real-time and this is the result:

Check out the swf over at wonderfl.net…

Read snippet: Interesting Texture #3 (animated)

QuickBox2D Unicycler

import com.actionsnippet.qbox.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.Joints.*;
[SWF (backgroundColor=0x000000, width=700, height=600, frameRate=60)]
var sim:QuickBox2D = new QuickBox2D(this, {debug:false,gravityY:10, renderJoints:false});
sim.setDefault({fillColor:0xCC0000,lineAlpha:0});
sim.createStageWalls();

for (var i:int = 0; i<20; i++){
	sim.addCircle({x:1+i * 0.8, y:1, radius:0.1+Math.random()*0.1, restitution:0.3});
}

sim.setDefault({fillColor:0xEFEFEF, fillAlpha:0.5, lineColor:0xFFFFFF, groupIndex:-2});
var ancA:QuickObject = sim.addCircle({x:20, y:12, radius:0.5, density:0, skin:"none"});
var ancB:QuickObject = sim.addCircle({x:20, y:2, radius:0.5, density:0, skin:"none"});
var head:QuickObject = sim.addCircle({x:0, y:-0.6, radius:0.5});
var neck:QuickObject = sim.addBox({x:0, y:1, width:0.5, height:2});
var spindle:QuickObject = sim.addBox({x:0, y:3, width:0.1, height:2})
spindle.userData.visible = false;
var top:QuickObject = sim.addGroup({objects:[head, neck, spindle], x:10, y:5, fixedRotation:true});
var upperLegA:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5});
var lowerLegA:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5});
var wheel:QuickObject = sim.addCircle({x:10, y:9, radius:1});
var upperLegB:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5});
var lowerLegB:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5});
var upperArmA:QuickObject = sim.addBox({x:10.7, y:5.25, width:1.5, height:0.25});
var lowerArmA:QuickObject = sim.addBox({x:11.8, y:5.25, width:1.2, height:0.25});
var upperArmB:QuickObject = sim.addBox({x:9.5, y:5.25, width:1.5, height:0.25});
var lowerArmB:QuickObject = sim.addBox({x:8.4, y:5.25, width:1.2, height:0.25});
var anchor:b2Vec2 = new b2Vec2();
function connect(a:QuickObject, b:QuickObject, lower:Number, upper:Number, offX:Number=0, offY:Number = 0):QuickObject{
	 var min:Number = Math.min(a.y, b.y);
     var max:Number = Math.max(a.y, b.y);
     anchor.y = min + (max - min) * 0.5 + offY;
     min = Math.min(a.x, b.x);
     max = Math.max(a.x, b.x);
     anchor.x = min + (max - min) * 0.5 + offX;
	 return sim.addJoint({type:"revolute", a:a.body, b:b.body, x1:anchor.x, y1:anchor.y, lowerAngle:lower, upperAngle:upper});
}
sim.addJoint({type:"revolute", a:wheel.body, b:top.body, x1:wheel.x, y1:wheel.y});
sim.addJoint({type:"revolute", a:lowerLegA.body, b:wheel.body, x1:lowerLegA.x, y1:lowerLegA.y + 0.7});
sim.setDefault({enableLimit:true});
connect(top, upperArmA, 0, 3, -.3, .1);
connect(upperArmA, lowerArmA, -2.5, -1, 0, 0);
connect(top, upperArmB, -3, 0, .3, .1);
connect(upperArmB, lowerArmB, -2.5, -1, 0, 0);
sim.addJoint({type:"distance", a:lowerArmA.body, b:ancA.body, frequencyHz:0.3});
sim.addJoint({type:"distance", a:lowerArmB.body, b:ancB.body, frequencyHz:0.3});
sim.setDefault({enableLimit:true});
connect(top, upperLegA, -6.28, 6, 0, 0.8);
connect(upperLegA, lowerLegA, .1, 6);
wheel.angle = Math.PI;
connect(top, upperLegB, -6.28, 6, 0, 0.8);
connect(upperLegB, lowerLegB, .1, 6);
sim.setDefault({enableLimit:false, type:"revolute"});
sim.addJoint({a:lowerLegB.body, b:wheel.body, x1:lowerLegB.x, y1:lowerLegB.y + 0.7});

sim.start();
sim.mouseDrag();

var sd:Number = 5, s:Number = 0, t:Number = 0;
addEventListener(Event.ENTER_FRAME, function():void{
	top.angle = Math.cos(t += 0.05) * 0.2;
    if (top.x > 19) sd = -5
	if (top.x < 5) sd = 5;
	s += (sd - s) / 8;
	wheel.body.SetAngularVelocity(s);
});

This chunk of code uses QuickBox2D to create a simple looking character riding a unicycle…

Have a look at the swf…

Read snippet: QuickBox2D Unicycler

QuickBox2D Floating Walker

import com.actionsnippet.qbox.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.Joints.*;

[SWF (backgroundColor=0x000000, width=700, height=600, frameRate=60)]

var sim:QuickBox2D = new QuickBox2D(this, {gravityY:.2});

sim.setDefault({fillColor:0xEFEFEF, fillAlpha:0.5, lineColor:0xFFFFFF});

sim.createStageWalls();

for (var i:int = 0; i<20; i++){
	sim.addCircle({x:1+i, y:1, radius:0.2, restitution:1});
}

var head:QuickObject = sim.addCircle({x:0, y:0, radius:0.5});
var neck:QuickObject = sim.addBox({x:0, y:1, width:0.5, height:2});
var top:QuickObject = sim.addGroup({objects:[head, neck], x:10, y:5, fixedRotation:true});

var upperLegA:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5,groupIndex:-2});
var lowerLegA:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5,groupIndex:-2});

var upperLegB:QuickObject = sim.addBox({x:10, y:7.5, width:0.25, height:1.5,groupIndex:-2});
var lowerLegB:QuickObject = sim.addBox({x:10, y:9, width:0.25, height:1.5,groupIndex:-2});

var anchor:b2Vec2 = new b2Vec2();
function connect(a:QuickObject, b:QuickObject, lower:Number, upper:Number, offX:Number=0, offY:Number = 0):QuickObject{
	 var min:Number = Math.min(a.y, b.y);
     var max:Number = Math.max(a.y, b.y);
     anchor.y = min + (max - min) * 0.5 + offY;
     min = Math.min(a.x, b.x);
     max = Math.max(a.x, b.x);
     anchor.x = min + (max - min) * 0.5 + offX;
	 return sim.addJoint({a:a.body, b:b.body, x1:anchor.x, y1:anchor.y, lowerAngle:lower, upperAngle:upper});
}

sim.setDefault({type:"revolute", collideConnected:false, enableLimit:true, enableMotor:true, maxMotorTorque:250, lineColor:0xFFFFFF});

var upperLegAJoint:QuickObject = connect(top, upperLegA, -1, 1, 0, 0.8);
var upperLegBJoint:QuickObject = connect(top, upperLegB, -1, 1, 0, 0.8);

var lowerLegAJoint:QuickObject = connect(upperLegA, lowerLegA, -1, 1);
var lowerLegBJoint:QuickObject = connect(upperLegB, lowerLegB, -1, 1);

sim.start();
sim.mouseDrag();
 

var j:b2RevoluteJoint;
var t:Number = -Math.PI * 0.5;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	
	var s1:Number = 1*Math.sin(t);
	var s2:Number = 1*Math.sin(t+Math.PI);
	t+= 0.05;
	
	top.body.SetAngularVelocity(s1 * 0.25);
	
	j =  upperLegAJoint.joint as b2RevoluteJoint;
    j.SetMotorSpeed(s1);
	
	j =  upperLegBJoint.joint as b2RevoluteJoint;
    j.SetMotorSpeed(s2);
	 
	j = lowerLegAJoint.joint as b2RevoluteJoint;
	j.SetMotorSpeed(-s2);
	
	j = lowerLegBJoint.joint as b2RevoluteJoint;
	j.SetMotorSpeed(-s1);
}

Experimenting with primitive robot designs… this was just an improvised design – it looks like it may make sense to break out a pencil and some paper – or my wacom… to get something interesting…


Have a look at the swf…


Read snippet: QuickBox2D Floating Walker

QuickBox2D Prismatic Joint

import com.actionsnippet.qbox.*;
import Box2D.Common.Math.*;

[SWF (backgroundColor=0x000000, width=700, height=600, frameRate=60)]

var sim:QuickBox2D = new QuickBox2D(this);

sim.setDefault({fillColor:0xCCCCCC, lineColor:0x3355AA});

sim.createStageWalls();

var box:QuickObject = sim.addBox({x:10, y:10, density:0});
var circle:QuickObject = sim.addCircle({x:10, y:13});

sim.addJoint({type:"prismatic", a:box.body, b:circle.body, axis:new b2Vec2(1, 0), upperTranslation:3, lowerTranslation:-3, enableLimit:true, motorSpeed:10, maxMotorForce:10, enableMotor:true});

sim.start();
sim.mouseDrag();

Simple prismatic joint demo. Prismatic joints are odd, it took me awhile to realize how to use them and what they can be used for… Plan on using them in the creation of some Box2D machines in the near futrure…

Check out the swf

Read snippet: QuickBox2D Prismatic Joint