By Zevan | April 19, 2009
Actionscript:
-
var mouseSpeedX:Number = 0;
-
var prevX:Number = 0;
-
-
var pends:Array = new Array();
-
for (var i:int = 0; i<10; i++){
-
pends.push(makePendulum(100+ i * 40, 100, 15, 100 + i * 10));
-
}
-
-
addEventListener(Event.ENTER_FRAME, onRun);
-
function onRun(evt:Event):void {
-
// mouseSpeed
-
mouseSpeedX = prevX - mouseX;
-
prevX = mouseX;
-
-
for (var i:int = 0; i<pends.length; i++) pends[i]();
-
}
-
-
function makePendulum(xp:Number, yp:Number, rad:Number, leng:Number):Function {
-
var rot:Number = 0;
-
var rotDest :Number = 0;
-
var rotVel:Number = 0
-
var string:Shape = Shape(addChild(new Shape()));
-
var ball:Sprite = Sprite(addChild(new Sprite()));
-
ball.buttonMode = true;
-
with(ball.graphics) beginFill(0xFF0000), drawCircle(0,leng, rad);
-
ball.x = xp;
-
ball.y = yp;
-
string.x = ball.x;
-
string.y = ball.y;
-
ball.addEventListener(MouseEvent.ROLL_OVER,function(){
-
rotDest = mouseSpeedX;
-
});
-
return function(){
-
// force rotDest back to 0
-
rotDest *= .8;
-
// elasticity (hooke's)
-
rotVel += (-1.9 * (rot - rotDest) - rotVel) / 4;
-
rot += rotVel
-
ball.rotation = rot;
-
// draw string:
-
string.graphics.clear();
-
string.graphics.lineStyle(0,0);
-
var pnt:Point = ball.localToGlobal(new Point(0, leng))
-
string.graphics.curveTo(0, leng / 2, pnt.x - ball.x, pnt.y-ball.y);
-
}
-
}
This is a variation on something I wrote in response to a student question. It creates a few pendulums that can be pushed with the mouse.
Posted in motion | Tagged actionscript, flash |
By Zevan | April 18, 2009
Actionscript:
-
// build some functions:
-
var redGradient:Function = sl(16, add(100, mult(5)));
-
-
// grid positioning
-
var xPos:Function = add(50, mult(30, cInt(div(4))));
-
var yPos:Function = add(50, mult(30, mod(4)));
-
-
// create some shapes:
-
var shapes:Array = createShapes(this, 22, [["beginFill", 0xCCCCCC], ["drawCircle", 0, 0, 10], ["endFill"], ["lineStyle",1, redGradient], ["drawRect", -5, -5, 10, 10]], {x:yPos, y:xPos, rotation:mult(10)});
-
-
function createShapes(par:DisplayObjectContainer, num:Number,
-
funcs:Array, props:Object):Array {
-
var shapes:Array = [];
-
for (var i:int = 0; i<num; i++){
-
shapes[i] = par.addChild(new Shape());
-
for (var j:int = 0; j<funcs.length; j++) {
-
var a:Array = funcs[j].concat();
-
for (var k:int = 0; k<a.length; k++){
-
if (a[k] is Function){
-
a[k] = a[k](i);
-
}
-
}
-
for (var key:String in props){
-
var v:* = props[key];
-
if (v is Function){
-
shapes[i][key] = v(i);
-
}else{
-
shapes[i][key] = v;
-
}
-
}
-
shapes[i].graphics[a[0]].apply(shapes[i].graphics, a.slice(1));
-
}
-
}
-
return shapes;
-
}
-
-
// function building blocks
-
const F:Function = function(a:*):*{return a};
-
-
function cInt(f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return int(f(n));
-
}
-
}
-
-
function mod(m:Number, f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return f(n) % m;
-
}
-
}
-
-
function div(d:Number, f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return f(n) / d;
-
}
-
}
-
-
function mult(scalar:Number, f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return f(n) * scalar;
-
}
-
}
-
-
function add(off:Number, f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return f(n) + off;
-
}
-
}
-
// shift left
-
function sl(amount:int, f:Function=null):Function{
-
if (f == null) f = F;
-
return function(n:Number):Number {
-
return f(n) <<amount
-
}
-
}
This is an unusual snippet I wrote a couple weeks back.... not sure where I was going with this really... has some interesting ideas in it.
Posted in misc | Tagged actionscript, flash |
By Zevan | April 17, 2009
Actionscript:
-
var boxDefaults:Object = {x:10, y:10, width:100, height:100, lineThickness:0, lineColor:0x000000, lineAlpha:1, fillColor:0xCCCCCC, fillAlpha:1}
-
function drawBox(params:Object=null):void {
-
var p:Object=setDefaults(boxDefaults, params);
-
graphics.lineStyle(p.lineThickness, p.lineColor, p.lineAlpha);
-
graphics.beginFill(p.fillColor, p.fillAlpha);
-
graphics.drawRect(p.x, p.y, p.width, p.height);
-
}
-
-
function setDefaults(defaults:Object, params:Object=null):Object {
-
if (params==null) {
-
params = new Object();
-
}
-
for (var key:String in defaults) {
-
if (params[key]==null) {
-
params[key]=defaults[key];
-
}
-
}
-
return params;
-
}
-
-
// test it out... notice that all object properties are optional and have default values
-
drawBox();
-
-
drawBox({x:200, y:200, lineColor:0xFF0000, lineThickness:2, fillColor:0xCCCC00});
-
-
drawBox({x:200, y:320, width:50, height:150, lineAlpha:0, fillColor:0x416CCF});
This is a technique I've been using recently... inspired by tweening engines. I find this to be suitable when a function or object constructor has lots and lots of arguments (80% of the time if I have a function or object constructor with too many arguments I re-think my design, but every now and then I use this technique).
Basically, the function or object constructor takes one argument of type Object - once passed into the function this Object argument is passed to the setDefault() function which populates it with any properties that it's missing - each property has a default value. As a result you end up with an easy to read function call with a variable number of arguments and well thought out default values.
This snippet just draws a box (not very interesting or usefull) - I wanted to showcase the technique using a simple function. As a real world example... I recently used this technique in a mini-library I created for use with Box2D... will be posting the library in the next few days.... it's a library for fast prototyping and custom rendering.
By Zevan | April 16, 2009
Actionscript:
-
const TWO_PI:Number=Math.PI*2;
-
// x, y, max radius, notch number
-
drawVerts(calcGear(200, 200, 50, 9));
-
-
drawVerts(calcGear(400, 200, 30, 3));
-
-
drawVerts(calcGear(300, 350, 30, 5));
-
-
drawVerts(calcGear(400,400, 30, 2));
-
-
function calcGear(x:Number, y:Number, maxRad:Number, s:int):Array {
-
var verts:Array = new Array();
-
var step:Number=TWO_PI / (s * 4);
-
var mod:Number=0;
-
for (var i:Number = 0; i<=TWO_PI; i+=step) {
-
var r:Number = (int(mod)%2+1) * maxRad;
-
mod+=.5;
-
verts.push(x + r * Math.cos(i));
-
verts.push(y + r * Math.sin(i));
-
}
-
return verts;
-
}
-
-
// could use draw path here instead;
-
function drawVerts(verts:Array):void{
-
graphics.lineStyle(0,0x000000);
-
graphics.moveTo(verts[0], verts[1]);
-
for (var i:int = 2; i<verts.length; i+=2) {
-
graphics.lineTo(verts[i], verts[i + 1]);
-
}
-
graphics.lineTo(verts[0], verts[1]);
-
}
Needed to draw some gear shapes today...