Browse the notebook

Tag: as3

QuickBox2D Gear Joint

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

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

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

sim.setDefault({fillColor:0x113366, fillAlpha:0.8, lineColor:0x3355AA});
sim.createStageWalls();

var boxA:QuickObject = sim.addBox({x:10, y:8, width:4, height:0.5, density:10});
var boxB:QuickObject = sim.addBox({x:5, y:5, density:10});
boxB.body.SetLinearVelocity(new b2Vec2(5, 0));
 
var rev1:QuickObject = sim.addJoint({type:"revolute", a:sim.w.GetGroundBody(), b:boxA.body, anchor:boxA.body.GetWorldCenter()})
			
var rev2:QuickObject = sim.addJoint({type:"prismatic", a:sim.w.GetGroundBody(), axis:new b2Vec2(1, 0), b:boxB.body, anchor:boxB.body.GetWorldCenter()})
																					 
sim.addJoint({type:"gear", a:boxA.body, b:boxB.body, joint1:rev1.joint, joint2:rev2.joint});
			 
sim.start();
sim.mouseDrag();

Simple gear joint demo – meant to serve as a reference for QuickBox2D…


Have a look at the swf…

Read snippet: QuickBox2D Gear Joint

QuickBox2D Connect to GroundBody

import com.actionsnippet.qbox.*;

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

var sim:QuickBox2D = new QuickBox2D(this);

sim.setDefault({fillColor:0x113366, fillAlpha:0.8, lineColor:0x3355AA});

sim.createStageWalls();

var boxA:QuickObject = sim.addBox({x:10, y:8, width:4, height:0.5, angularDamping:1});
var boxB:QuickObject = sim.addBox({x:7, y:8, width:3, height:0.25, angle:-.5, angularDamping:1});
var boxC:QuickObject = sim.addBox({x:12, y:2, width:2, height:1});

var rev:QuickObject = sim.addJoint({type:"revolute", a:boxA.body, b:sim.w.GetGroundBody()});
// add a red dot to boxA
with (boxA.userData.graphics) lineStyle(), beginFill(0xFF0000), drawCircle(0,0,2);

var rev2:QuickObject = sim.addJoint({type:"revolute", a:boxB.body, b:sim.w.GetGroundBody()});
with (boxB.userData.graphics) lineStyle(), beginFill(0xFF0000), drawCircle(0,0,2);

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

In order to use gear joints (covered in tomorrows post) you’ll need to know how to connect to the ground body…

Check out the swf…

Read snippet: QuickBox2D Connect to GroundBody

QuickBox2D Revolute Walker

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

[SWF (backgroundColor=0x222222, width=700, height=600)]

var sim:QuickBox2D = new QuickBox2D(this);
 
sim.setDefault({fillColor:0x000000, lineColor:0xCCCCCC});
sim.createStageWalls();

var legA:QuickObject = sim.addBox({x:5, y:11, width:2, height:0.2,groupIndex:-2});
var three:QuickObject = sim.addBox({x:6.8 + 1.8, y:11, width:2, height:0.2,groupIndex:-2});
var legB:QuickObject = sim.addBox({x:6.8, y:11, width:2, height:0.5,groupIndex:-2});
sim.setDefault({type:"revolute"});

var anchorX:Number = legA.x + (legB.x - legA.x) / 2;
var anchorY:Number = legA.y;
var revJointA:QuickObject = sim.addJoint({a:legA.body, b:legB.body, x1:anchorX, y1:anchorY,enableMotor:true, maxMotorTorque:80});

anchorX = legB.x + (three.x - legB.x) / 2;

var revJointB:QuickObject = sim.addJoint({a:legB.body, b:three.body, x1:anchorX, y1:anchorY, enableMotor:true, maxMotorTorque:80});

setWalkDir(6);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
  if (legB.x < 4){
	setWalkDir(6);  
  }else if (legB.x > 19){
	setWalkDir(-6);  
  }
}
function setWalkDir(dir:Number):void{
	var j:b2RevoluteJoint;
	j = revJointA.joint as b2RevoluteJoint
	j.SetMotorSpeed(dir);
	j = revJointB.joint as b2RevoluteJoint
	j.SetMotorSpeed(dir * -1);
}

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

This demo is a bit more complex than the last two – mostly because it makes use of motors…


Have a look at the swf…

Read snippet: QuickBox2D Revolute Walker

QuickBox2D Pulley Joint

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

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

var sim:QuickBox2D = new QuickBox2D(this);

sim.setDefault({fillColor:0x113366, fillAlpha:0.8, lineColor:0x3355AA});

sim.createStageWalls();

var boxA:QuickObject = sim.addBox({x:10, y:8, fixedRotation:true});
var boxB:QuickObject = sim.addBox({x:14, y:8, width:2,  fixedRotation:true});

sim.addJoint({type:"pulley", a:boxA.body, b:boxB.body, groundAnchor1:new b2Vec2(boxA.x, 2), groundAnchor2:new b2Vec2(boxB.x, 2)});

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

QuickBox2D pulley joint demo. This post is really meant to serve as part of the docs so it may seem a bit boring in its simplicity…

Have a look at the swf…

Read snippet: QuickBox2D Pulley Joint

QuickBox2D Revolute Ragdoll

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

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

var sim:QuickBox2D = new QuickBox2D(this,{debug:false, frim:true, gravityY:1});

sim.setDefault({fillColor:0x113366, fillAlpha:0.8, lineColor:0x3355AA});

sim.createStageWalls();

var circle:QuickObject = sim.addCircle({x:10, y:10, radius:3});
var head:QuickObject = sim.addCircle({x:5, y:5, radius:0.5});
var torsoA:QuickObject = sim.addBox({x:5, y:6, width:1.5, height:0.8})
var torsoB:QuickObject = sim.addBox({x:5, y:6.5, width:1.25, height:0.8})
var torsoC:QuickObject = sim.addBox({x:5, y:7, width:1.0, height:0.8})
var pelvis:QuickObject = sim.addBox({x:5, y:7.5, width:1.0, height:0.8})
var leftLegA:QuickObject = sim.addBox({x:4.75, y:8.5, width:0.4, height:1.75});
var leftLegB:QuickObject = sim.addBox({x:4.75, y:9.75, width:0.4, height:1.5});
var rightLegA:QuickObject = sim.addBox({x:5.29, y:8.5, width:0.4, height:1.75});
var rightLegB:QuickObject = sim.addBox({x:5.29, y:9.75, width:0.4, height:1.5});
var leftArmA:QuickObject = sim.addBox({x:3.6, y:5.8, width:1.3, height:0.35});
var leftArmB:QuickObject = sim.addBox({x:2.5, y:5.8, width:1.25, height:0.35});
var rightArmA:QuickObject = sim.addBox({x:6.4, y:5.8, width:1.3, height:0.35});
var rightArmB:QuickObject = sim.addBox({x:7.5, y:5.8, width:1.25, height:0.35});

torsoA.body.SetLinearVelocity(new b2Vec2(0, 50));

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, lineColor:0xFFFFFF});

connect(head, torsoA, -.2, .2);
connect(torsoA, torsoB,-.2, .2);
connect(torsoC, torsoB,-.2, .2);
connect(torsoC, pelvis,-.2, .2);

connect(pelvis, leftLegA, -1, 1, 0, -0.5);
connect(leftLegA, leftLegB, -1, 1);

connect(pelvis, rightLegA, -1, 1, 0, -0.5);
connect(rightLegA, rightLegB, -1, 1);

connect(torsoA, leftArmA, -2, 1);
connect(leftArmA, leftArmB, -2, 1);

connect(torsoA, rightArmA, -1, 2)
connect(rightArmA, rightArmB, -1, 2)

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

QuickBox2D alpha 108 is finally finished and different types of joints are now possible. I’ll be auto-posting joint demos over the next few days for each type of Box2D joint. Box2D joints are pretty confusing, I struggled a bit to decide on a good way to handle them in QuickBox2D, any suggestions are welcome.


Have a look at the swf:

Read snippet: QuickBox2D Revolute Ragdoll

Interesting Texture #3

var canvas:BitmapData = new BitmapData(1500,1000,false, 0x000000);
addChild(new Bitmap(canvas));
scaleX = scaleY = .5;

var w:int = canvas.width;
var w10:int = w * 80;
var convert:Number = Math.PI/180;
var size:int = canvas.width * canvas.height;
for (var i:int = 0; i<size; i++){
	var xp:int = i % w;
	var yp:int = int(i / w);
	var xp2:int = xp * 2;
	var c1:int = (255/8) * (Math.cos(xp2 * convert) - Math.sin(yp*(xp2 + 500)/w10));
	if (c1 < 0) c1 = 256 - c1;
	c1 = (c1 << 2 | c1) ;
	canvas.setPixel(xp, yp, c1 <<15 | c1 <<9 | c1 );
}
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var clone:BitmapData = canvas.clone();
canvas.draw(clone, m, null, BlendMode.SUBTRACT);
clone.draw(canvas);
clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
canvas.draw(clone, null, null, BlendMode.ADD);
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]);
canvas.applyFilter(canvas, canvas.rect, new Point(0,0), gray);

Soon I’ll work on a real-time variation. For now, here is one more still…

Read snippet: Interesting Texture #3

Interesting Texture #2

var canvas:BitmapData = new BitmapData(1000,1000,false, 0x000000);
addChild(new Bitmap(canvas));
scaleX = scaleY = .5;

var w:int = canvas.width;
var w10:int = w * 40;
var size:int = canvas.width * canvas.height;
for (var i:int = 0; i<size; i++){
	var xp:int = i % w;
	 
	var yp:int = int(i / w);
	var c1:int = (255/8) * (Math.cos(xp* Math.PI/180 * 2) + Math.sin(yp*(xp + 200)/w10));
	if (c1 < 0) c1 = 256 - c1;
	c1 = (c1 << 1 | c1) ;
	canvas.setPixel(xp, yp, c1 <<15 | c1 <<7 | c1 );
}
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var clone:BitmapData = canvas.clone();
canvas.draw(clone, m, null, BlendMode.SUBTRACT);
clone.draw(canvas);
clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
canvas.draw(clone, null, null, BlendMode.ADD);

Randomly bit shifting on this one is actually getting a good deal of millage.. I know I can easily optimize so that it works in realtime – could even be done in pixelbender… but going to play a bit more first before I optimize….

Read snippet: Interesting Texture #2

Interesting Texture

var canvas:BitmapData = new BitmapData(1000,1000,false, 0x000000);
addChild(new Bitmap(canvas));
scaleX = scaleY = .5;

var w:int = canvas.width;
var w10:int = w * 60;
var size:int = canvas.width * canvas.height;
for (var i:int = 0; i<size; i++){
	var xp:int = i % w;
	 
	var yp:int = int(i / w);
	var c1:int = (255/8) * (Math.cos(xp* Math.PI/180 * 2) + Math.sin(yp*yp/w10));
	if (c1 < 0) c1 = 256 - c1;
	c1 = (c1 << 1 | c1) ;
	canvas.setPixel(xp, yp, c1 <<16 | c1 <<8 | c1 );
}
var m:Matrix = new Matrix();
m.scale(1,-1);
m.translate(0,canvas.height);
var clone:BitmapData = canvas.clone();
canvas.draw(clone, m, null, BlendMode.SUBTRACT);
clone.draw(canvas);
clone.applyFilter(clone, clone.rect, new Point(0,0), new BlurFilter(10,10,1));
canvas.draw(clone, null, null, BlendMode.ADD);

Having one of those days where everything I code doesn’t look right to me… took a little break from other work and created this very unoptimized abstract texture… no animation so here is a bitmap:

Read snippet: Interesting Texture

Gumdrop Torus

var matrix:Matrix3D = new Matrix3D();
 
var verts:Vector.<Number> = new Vector.<Number>();
var pVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();

for (var i:Number = -2; i<2; i+=.04){
	for (var j:Number = -2; j<2; j+=.04){
		for (var k:Number = -2; k<2; k+=.04){
// equation from: http://local.wasp.uwa.edu.au/~pbourke/geometry/gumdrop/
			var yz:Number = j * j + k * k;
		     var s:Number = 4 * (Math.pow(i,4) + Math.pow(yz,2)) 
			 + 17 * i * i *(yz) - 20 * (yz + i * i) + 17;
			if (s <0 && s > -0.5){
				verts.push(i * 60);
				verts.push(j * 60);
				verts.push(k * 60);
				pVerts.push(0), pVerts.push(0);
				uvts.push(0), uvts.push(0), uvts.push(0);
			 }
		}
	}
}

var tVerts:Vector.<Number> = new Vector.<Number>();
matrix.appendRotation(90, Vector3D.X_AXIS);
matrix.appendRotation(45, Vector3D.Y_AXIS);
matrix.appendScale(1.7, 1.7, 1.7);
matrix.transformVectors(verts, tVerts);

var p:Point = new Point();
var brush:BitmapData=new BitmapData(3,3,true,0x41FFFFFF);
var canvas:BitmapData = new BitmapData(500,500,false, 0x000000);
addChild(new Bitmap(canvas));
var dx:Number=0;
var dy:Number=0;
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	dx += (mouseX - dx)/4;
	dy += (mouseY - dy)/4;
	matrix.identity();
	matrix.appendRotation(dy,Vector3D.X_AXIS);
	matrix.appendRotation(dx,Vector3D.Y_AXIS);
	matrix.appendTranslation(250, 250, 0);
	Utils3D.projectVectors(matrix, tVerts, pVerts, uvts);
	canvas.lock();
	canvas.fillRect(canvas.rect, 0x000000);
	var inc:int = 0;
	for (var i:int = 0; i<pVerts.length; i+=2){
	 
        p.x = pVerts[i];
        p.y = pVerts[i+1];
		canvas.copyPixels(brush, brush.rect, p, null, null, true); 
	}
	canvas.unlock();
}

Felt like revisiting implicit surface plotting today…

Have a look at the swf over at wonderfl.net

Read snippet: Gumdrop Torus

Convert Timeline Code to Document Class

For a few different reasons I decided to write some php code to convert timeline code to a document class. The script is done and it seems to work pretty nicely. I’m sure there are a few bugs, but I’ve tested around 30 snippets from this site and they all worked.

To test it out:

1) just take the below code (or any other timeline code), copy it to your clipboard
(The code doesn’t have to be small, I did a test with 300 lines of timeline code and it worked just fine)

x = stage.stageWidth / 2;
y = stage.stageHeight / 2;
var xp:Number = 0, yp:Number = 0;
var r:Number = 0, t:Number = 0;
var speed:Number = .07;
var scale:Number = 20;
var plot0:Shape = Shape(addChild(new Shape()));
var plot1:Shape = Shape(addChild(new Shape()));
plot0.graphics.lineStyle(0,0x000000);
plot1.graphics.lineStyle(0,0x000000);
addEventListener(Event.ENTER_FRAME, onLoop);
function onLoop(evt:Event):void {
	 r =  scale * Math.sqrt(t);
	 xp =  r * Math.cos(t);
	 yp =  r * Math.sin(t);
	 t += speed;
	plot0.graphics.lineTo(xp, yp);
	plot1.graphics.lineTo(-xp, -yp);
}

2) go to this page and follow the instructions:
https://actionsnippet.com/timeline_to_doc.php

I used this script to convert a few snippets from this site to work on wonderfl.net…

Have a look at them here.

In the next few days I may add a button to all code snippets that allows you to convert the code to a doc class…

The script adds import statements automatically, I may however have missed a few packages, so if the generated code is missing an import statement, let me know and I’ll fix it…

Read snippet: Convert Timeline Code to Document Class