Posted: September 5th, 2010 | Author: admin | Filed under: Uncategorized | No Comments »
ok — so, last time I was really excited about cocos2D for it’s flash-like features. Because I use the flash graphics API extensively, I was looking for something similar in the iPhone API. unfortunately, it’s not as straight forward, but Cocos2D once again came to the rescue.
there are 2 ways generally to draw in Cocos2d. One is taking advantage of the ‘draw’ function that every instance of CCNode, CCSprite and CCLayer inherit. it’s taking advantage of the openGL engine, but for most cases the result is a bit rough looking… you can draw lines, basic shapes and fills. It’s really fast and it saves you a lot of the hassle of getting the graphic context and all that. here’s how you draw a simple line — “draw” is overriding a function that gets called every single frame — you you are essentially redrawing all the time.
-(void) draw
{
CGSize size = [[CCDirector sharedDirector] winSize];
glColor4f(1.0, 0.0, 0.0, 1.0);
glLineWidth(2.0);
glEnable(GL_LINE_SMOOTH);
ccDrawLine(startPoint, endPoint);
}
The other way of drawing in Cocos2D is using whats called Render Texture. The general idea is that you take an image and burn it’s texture in a certain position. it’s really straight forward and it lets you control the type of brush/shape with the image you’re using. The basic implementation is something like this:
@implementation RenderTextureTest
-(id) init
{
if( (self = [super init]) ) {
CGSize s = [[CCDirector sharedDirector] winSize];
CCLabel* label = [CCLabel labelWithString:@"Render Texture Test" fontName:@"Arial" fontSize:32];
[self addChild:label z:0];
[label setPosition: ccp(s.width/2, s.height-50)];
// create a render texture, this is what we're going to draw into
target = [[CCRenderTexture renderTextureWithWidth:s.width height:s.height] retain];
[target setPosition:ccp(s.width/2, s.height/2)];
// note that the render texture is a cocosnode, and contains a sprite of it's texture for convience,
// so we can just parent it to the scene like any other cocos node
[self addChild:target z:1];
// create a brush image to draw into the texture with
brush = [[CCSprite spriteWithFile:@"brush.png"] retain];
[brush setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }];
[brush setOpacity:100];
self.isTouchEnabled = YES;
// Save Image menu
[CCMenuItemFont setFontSize:16];
CCMenuItem *item = [CCMenuItemFont itemFromString:@"Save Image" target:self selector:@selector(saveImage:)];
CCMenu *menu = [CCMenu menuWithItems:item, nil];
[self addChild:menu];
[menu setPosition:ccp(s.width-80, s.height-80)];
}
return self;
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint start = [touch locationInView: [touch view]];
start = [[CCDirector sharedDirector] convertToGL: start];
// begin drawing to the render texture
[target begin];
//move the brush to position
[brush setPosition:ccp(start.x, start.y)];
// draw the texture
[brush visit];
// finish drawing and return context back to the screen
[target end];
}
When I was playing around with these methods my first instinct was to create a bunch of sprites and draw on the at the same time to get a cool effect with rotation/scale etc. That proved to be a very bad idea with RenderTexture. Sprites are extremely expensive, memory-wise, and especially when they’re big. Very quickly I brought the FPS down to 12 (from 60). What I had to do is create more complex math and keep the sprite count at 1 which works really well.
Posted: August 15th, 2010 | Author: admin | Filed under: Uncategorized | 3 Comments »
This is really the one line advice I needed. I’ve dabbled with iPhone apps for a couple of months now, but building temperature converters, table views and sliders bored me to death! So it wasn’t until I went out for some hummus with my friend that he suggested I download the Cocos2D framework. 2 days later I’m hooked. and basically, I just want to put down some things so I don’t forget — stuff that would help me translate AS3 to xCode. The stuff below is really all from the first page of the beginner tutorials, but it is so similar to how flash works (or at least, how I’m used to work with flash) that I wanted to point it out.
Here are some early findings:
how to create a sprite and add it to the display list:
CCSprite *mySprite;
mySprite = [CCSprite spriteWithFile: @"image.png"];
mySprite.position = ccp( 100, 100 );
[self addChild:mySprite];
how to add an enterFrame Event:
// schedule a repeating callback on every frame
[self schedule:@selector(nextFrame:)];
and how the enterFrame function looks like:
- (void) nextFrame:(ccTime)dt {
mySprite.position = ccp( mySprite.position.x + 100*dt, mySprite.position.y );
if (mySprite.position.x > 480+32) {
mySprite.position = ccp( -32, mySprite.position.y );
}
}
Posted: January 8th, 2010 | Author: admin | Filed under: Uncategorized | 8 Comments »
One of the challanges in the design of www.flurrious.com was getting those circular sliders in. Of course you can fake it and create an animation of a slider and control the timeline from 0-100, but that’s lame and not so easy to modify (like change the radius, sweep angle etc.). so, I set to create a circular slider.
I had the basic principles in place: create a circle, and create a beginSwipe andgle and an endSwipe angle. done:

the code looks something like this:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
/**
* @author iasseo
*/
public class CircularSlider extends MovieClip
{
private var _circ : Sprite;
private var _startAngle : Number = 90;
private var _angleRange : Number = 30;
private var _angleShape : Sprite;
private var _radius : Number = 250;
private var topAngle : Number;
private var bottmAngle : Number;
public function CircularSlider()
{
calcAngles();
drawCircle();
initAngle();
addEventListener(Event.ENTER_FRAME, onEF);
}
private function calcAngles() : void
{
topAngle = _startAngle - _angleRange - 90;
topAngle = topAngle / 180 * Math.PI;
bottmAngle = _startAngle + _angleRange - 90;
bottmAngle = bottmAngle / 180 * Math.PI;
}
private function initAngle() : void
{
_angleShape = new Sprite();
_angleShape.x = stage.stageWidth/2;
_angleShape.y = stage.stageHeight/2;
addChild(_angleShape);
}
private function drawAngle() : void
{
_angleShape.graphics.lineStyle(2, 0xff0000);
_angleShape.graphics.lineTo(Math.cos(topAngle)*_radius, Math.sin(topAngle)*_radius);
_angleShape.graphics.lineStyle(2, 0x00ff00);
_angleShape.graphics.lineTo(Math.cos(bottmAngle)*_radius, Math.sin(bottmAngle)*_radius);
_angleShape.graphics.lineStyle(2, 0xff0000);
_angleShape.graphics.lineTo(0, 0);
}
private function drawCircle() : void
{
_circ = new Sprite();
_circ.graphics.lineStyle(1,0xffffff);
_circ.graphics.drawCircle(0, 0, _radius);
_circ.graphics.endFill();
_circ.x = stage.stageWidth/2;
_circ.y = stage.stageHeight/2;
addChild(_circ);
}
private function onEF(e:Event):void
{
_angleRange = Math.abs(stage.stageHeight/2 - mouseX);
_angleShape.graphics.clear();
calcAngles();
drawAngle();
}
}
}
Next, I needed to place the scroll handlebar at the top of the sweep (top of green line in picture), and have it be draggable to the bottom of the sweep. To do that, I calculated the X,Y position of the top and bottom (which I already have in the code), and upon click, I created a rectangle that represented the bounding box for the drag operation. Then, I calculated the percentage point of the handle inside that bounding box to get the 0-1 result, and using the Y position, extracted what the X position would be:

The only problem is that now, when I remove the guides (the circle and angles), I am left with only the slider… and I need the arc so the slider has some visual representation. There are 2 solutions for that. Simple solution: mask the circle… easy to do. here’s the result:

A solution that’s a bit more complex is to DRAW the arc.. that’s where I was happy to find this nice post by the algorythmist. So, using this code, you can then create a nice circular slider:

now all that’s left to do is output the percentage from the slider and you got yourself a nice circular slider!
here’s the final code:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
/**
* @author iasseo
*/
public class CircularSlider extends MovieClip
{
private var _circ : Sprite;
private var _startAngle : Number = 90;
private var _angleRange : Number = 30;
private var _angleShape : Sprite;
private var _radius : Number = 250;
private var topAngle : Number;
private var bottmAngle : Number;
private var _handle : Sprite;
private var _box : Sprite;
private var _handleHolder : Sprite;
private var _mask : Sprite;
public function CircularSlider()
{
calcAngles();
drawCircle();
initAngle();
drawAngle();
drawSegments();
createHandle();
}
private function createHandle() : void
{
_handleHolder = new Sprite();
_handleHolder.x = stage.stageWidth/2;
_handleHolder.y = stage.stageHeight/2;
addChild(_handleHolder);
_handle = new Sprite();
_handle.graphics.beginFill(0xcccccc);
_handle.graphics.drawCircle(0, 0, 10);
_handle.graphics.endFill();
_handle.buttonMode = true;
_handle.x = Math.cos(topAngle)*_radius;
_handle.y = Math.sin(topAngle)*_radius;
_handleHolder.addChild(_handle);
_handle.addEventListener(MouseEvent.MOUSE_DOWN, onStartDrag);
}
private function onStartDrag(e : MouseEvent) : void
{
makeBox();
drawBox();
var rect : Rectangle = _box.getRect(_box);
_handle.startDrag(false, rect);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onStopDrag);
}
private function onMouseMove(e : MouseEvent) : void
{
e.updateAfterEvent();
var rect : Rectangle = _box.getRect(_box);
var dist : Number = rect.height;
var per : Number = (_handle.y + dist/2)/dist;
var a : Number = _startAngle - _angleRange;
var b : Number = _startAngle + _angleRange;
var r : Number = b-a;
var targetAngle :Number = a + r*per;
targetAngle = targetAngle / 180 * Math.PI;
_handle.x = Math.sin(targetAngle)*_radius + 2;
}
private function onStopDrag(e : MouseEvent) : void
{
removeBox();
_handle.stopDrag();
_handle.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function removeBox() : void
{
_box.graphics.clear();
removeChild(_box);
}
private function drawBox() : void
{
_box.graphics.lineStyle(1,0xffffff, 0);
_box.graphics.moveTo(Math.cos(topAngle)*_radius, Math.sin(topAngle)*_radius);
_box.graphics.lineTo(_radius, Math.sin(topAngle)*_radius);
_box.graphics.lineTo(_radius, Math.sin(bottmAngle)*_radius);
_box.graphics.lineTo(Math.cos(topAngle)*_radius, Math.sin(bottmAngle)*_radius);
_box.graphics.lineTo(Math.cos(bottmAngle) * _radius, Math.sin(topAngle)*_radius);
}
private function makeBox() : void
{
_box = new Sprite();
_box.x = stage.stageWidth/2;
_box.y = stage.stageHeight/2;
_box.mouseEnabled = false;
_box.mouseChildren = false;
addChild(_box);
}
private function calcAngles() : void
{
topAngle = _startAngle - _angleRange - 90;
topAngle = topAngle / 180 * Math.PI;
bottmAngle = _startAngle + _angleRange - 90;
bottmAngle = bottmAngle / 180 * Math.PI;
}
private function drawSegments() : void
{
_angleShape.graphics.lineStyle(2, 0x0000ff);
// FROM THE ALGORYTHMIST -- http://algorithmist.wordpress.com/2009/12/01/drawing-circular-segments-in-actionscript/
// now that start and end angle are fixed, draw a set of quads no more than PI/4 in arc at once
var angleDelta:Number = bottmAngle - topAngle;
var numSeg:Number = Math.ceil(angleDelta*4.0/Math.PI);
var arc:Number = angleDelta/numSeg;
// p is the vector from the origin of the wedge to (p0X,p0Y)
// q is the vector from the origin of the wedge to (p2X,p2Y)
// the vector p+q bisects the angle between p and q. The middle interpolation point is
// 'radius' units along that bisector.
var pX:Number = _radius*Math.cos(topAngle);
var pY:Number = _radius*Math.sin(topAngle);
var p0X:Number = pX;
var p0Y:Number = pY;
var qX:Number = 0;
var qY:Number = 0;
var angle:Number = topAngle;
// initial point at startAngle
var startX:Number = _radius*Math.cos(topAngle);
var startY:Number = _radius*Math.sin(topAngle);
_angleShape.graphics.moveTo( startX, startY );
var radInv:Number = 1.0/_radius;
// approximate each arc with a quad. Bezier
for( var i:uint=0; i<numSeg; ++i )
{
angle += arc;
qX = _radius*Math.cos(angle);
qY = _radius*Math.sin(angle);
var p2X:Number = qX;
var p2Y:Number = qY;
// unit vector in direction of bisector - alternative approach is two more trig. calcs to compute the coordinates.
// let's have some fun and do it a different way.
var dX:Number = (pX+qX)*radInv;
var dY:Number = (pY+qY)*radInv;
var d:Number = Math.sqrt(dX*dX + dY*dY);
dX /= d;
dY /= d;
// middle interpolation point is a distance of 'radius' units along direction of bisecting unit vector
var p1X:Number = _radius*dX;
var p1Y:Number = _radius*dY;
// compute control point so that quad. Bezier passes through (p0X,p0Y), (p1X,p1Y), and (p2X,p2Y) at t=0.5
var cX:Number = 2.0*p1X - 0.5*(p0X + p2X);
var cY:Number = 2.0*p1Y - 0.5*(p0Y + p2Y);
// You can compute the control point directly with nothing but sin & cos, but if memory serves it takes
// four more trig comps. for a total of six per loop iteration.
_angleShape.graphics.curveTo(cX, cY, p2X, p2Y);
// end point is start point for next iteration
p0X = p2X;
p0Y = p2Y;
pX = qX;
pY = qY;
}
}
private function initAngle() : void
{
_angleShape = new Sprite();
_angleShape.x = stage.stageWidth/2;
_angleShape.y = stage.stageHeight/2;
addChild(_angleShape);
}
private function drawAngle() : void
{
_angleShape.graphics.lineStyle(2, 0xff0000);
_angleShape.graphics.lineTo(Math.cos(topAngle)*_radius, Math.sin(topAngle)*_radius);
_angleShape.graphics.lineStyle(2, 0x00ff00);
_angleShape.graphics.lineTo(Math.cos(bottmAngle)*_radius, Math.sin(bottmAngle)*_radius);
_angleShape.graphics.lineStyle(2, 0xff0000);
_angleShape.graphics.lineTo(0, 0);
}
private function drawCircle() : void
{
_circ = new Sprite();
_circ.graphics.lineStyle(1,0xffffff);
_circ.graphics.drawCircle(0, 0, _radius);
_circ.graphics.endFill();
_circ.x = stage.stageWidth/2;
_circ.y = stage.stageHeight/2;
// TO MASK OUT THE CIRCLE, YOU CAN USE THIS:
/*_mask = new Sprite();
_mask.x = stage.stageWidth/2;
_mask.y = stage.stageHeight/2;
_mask.mouseEnabled = false;
_mask.mouseChildren = false;
addChild(_mask);
_mask.graphics.beginFill(0xff0000, 1);
_mask.graphics.drawRect(Math.cos(topAngle)*_radius, Math.sin(topAngle)*_radius, _radius-Math.cos(topAngle)*_radius + 1, _radius/2-Math.sin(topAngle)*_radius);
*
*/
_circ.mask = _mask;
addChild(_circ);
}
}
}
Posted: January 7th, 2010 | Author: admin | Filed under: Uncategorized | No Comments »
So, like I said in my last post, I’m going to dedicate these few next posts to go over some of the techniques I used to create Flurrious.com.
The first thing I want to go over is the creation of the drawing application. The architecture of it is pretty simple, but crucial to making it work well, and having it be extendable and modular. My first step was to create the canvas. since a snowflake has an ice crystal formation, it has to have 6 sides. So my first step is to draw 6 triangles that form a hexagon:

The code for this is pretty simple, looks like this:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
/**
* @author iasseo
*/
public class SnowFlake extends MovieClip
{
private const SLICES : Number = 6;
private const RADIUS : Number = 300;
private var _sliceArray : Array = new Array();
private var _angle : Number;
public function SnowFlake()
{
_angle = Math.PI / SLICES;
createFlakeStage();
}
private function createFlakeStage() : void
{
for (var n : Number = 0;n < SLICES; n++)
{
var slice : Sprite = createSlice(_angle);
slice.x = stage.stageWidth / 2;
slice.y = stage.stageHeight / 2;
slice.rotation = 360 / SLICES * n;
_sliceArray.push(slice);
addChild(slice);
}
}
private function createSlice(angle : Number) : Sprite
{
var slice : Sprite = new Sprite();
slice.graphics.moveTo(0, 0);
slice.graphics.lineStyle(1,0);
slice.graphics.beginFill(0,.1);
slice.graphics.lineTo(Math.cos((angle)-Math.PI/2)*RADIUS, Math.sin((angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(Math.cos(-(angle)-Math.PI/2)*RADIUS, Math.sin(-(angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(0, 0);
slice.graphics.endFill();
slice.graphics.moveTo(0, 0);
slice.graphics.lineTo(0,Math.sin((_angle)-Math.PI/2)*RADIUS);
slice.graphics.endFill();
return slice;
}
}
}
Now, even though this is my canvas which I’m using to capture the mouse events, I’m going to draw the actual shapes on a separate Sprite, so I can have better control. In order to do that, I’m going to place 6 empty Sprites in the center of the hexagon, each one rotated, just like the triangles I drew. I’ll add a new function – createShapeHolders() – to the constructor (notice that I’m disabling all MouseEvents for these ’shapes’, because I want to control them from the canvas I drew earlier). For each of the triangles (which are separate Sprites), I’m going to add a MouseEvent, which will trigger the drawing application. I’m going to add that to the ‘for loop’ in the createFlakeStage() function, and I’m also adding 3 MouseEvent functions: beginShape, renderShape and endShape.
When I click on any of the triangles now, beginShape() will save the slice I clicked on as _slice (added as a private var to the class), and trigger a MOUSE_MOVE event. Then, as I move the mouse, the renderShape() function will draw on all 6 sides of the hexagon:

CLICK TO SEE THIS IN ACTION
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
/**
* @author iasseo
*/
public class SnowFlake extends MovieClip
{
private const SLICES : Number = 6;
private const RADIUS : Number = 300;
private var _sliceArray : Array = new Array();
private var _angle : Number;
private var _shapeHolders : Vector.<Sprite> = new Vector.<Sprite>();
private var _slice : Sprite;
public function SnowFlake()
{
_angle = Math.PI / SLICES;
createFlakeStage();
createShapeHolders();
}
private function createShapeHolders() : void
{
for (var n : Number = 0;n < SLICES; n++)
{
var shape : Sprite = new Sprite();
shape.mouseEnabled = false;
shape.mouseChildren = false;
shape.x = stage.stageWidth / 2;
shape.y = stage.stageHeight / 2;
_shapeHolders.push(shape);
shape.rotation = 360 / SLICES * n;
addChild(shape);
}
}
private function createFlakeStage() : void
{
for (var n : Number = 0;n < SLICES; n++)
{
var slice : Sprite = createSlice(_angle);
slice.x = stage.stageWidth / 2;
slice.y = stage.stageHeight / 2;
slice.rotation = 360 / SLICES * n;
slice.addEventListener(MouseEvent.MOUSE_DOWN, beginShape);
slice.alpha = 1;
_sliceArray.push(slice);
addChild(slice);
}
}
private function createSlice(angle : Number) : Sprite
{
var slice : Sprite = new Sprite();
slice.graphics.moveTo(0, 0);
slice.graphics.lineStyle(1,0);
slice.graphics.beginFill(0,.1);
slice.graphics.lineTo(Math.cos((angle)-Math.PI/2)*RADIUS, Math.sin((angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(Math.cos(-(angle)-Math.PI/2)*RADIUS, Math.sin(-(angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(0, 0);
slice.graphics.endFill();
slice.graphics.moveTo(0, 0);
slice.graphics.lineTo(0,Math.sin((_angle)-Math.PI/2)*RADIUS);
slice.graphics.endFill();
return slice;
}
private function beginShape(e : MouseEvent) : void
{
_slice = e.target as Sprite;
for (var i : Number = 0;i < SLICES; i++)
{
_shapeHolders[i].graphics.lineStyle(1,0xFFFFFF);
_shapeHolders[i].graphics.moveTo(_slice.mouseX, _slice.mouseY);
}
stage.addEventListener(MouseEvent.MOUSE_MOVE, renderShape);
stage.addEventListener(MouseEvent.MOUSE_UP, endShape);
}
private function renderShape(e : MouseEvent) : void
{
for (var i : Number = 0;i < SLICES; i++)
{
_shapeHolders[i].graphics.lineTo(_slice.mouseX, _slice.mouseY);
}
}
private function endShape(e : MouseEvent) : void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, renderShape);
stage.removeEventListener(MouseEvent.MOUSE_UP, endShape);
}
}
}
Now the only problem is that it doesn’t look like a symmetrical drawing… it basically copies the shape you’re drawing and places it in a circle. Now we need to add a reflection to the shape. So, to do that, we’ll have to add 2 Sprites to each of the ’shapes’ we created in the createShapeHolders() function. One of those shapes we’ll flip horizontally (scaleX = -1) and then, each time we trigger beginShape and renderShape, we’ll use the FP10 copyFrom() function to create a reflection effect. All we have left to do now is to hide the canvases, and start drawing! here is the result:

CLICK HERE TO SEE IT IN ACTION – CLICK AND DRAG NEAR THE CENTER OF THE STAGE
and here is the final code:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
/**
* @author iasseo
*/
public class SnowFlake extends MovieClip
{
private const SLICES : Number = 6;
private const RADIUS : Number = 300;
private var _sliceArray : Array = new Array();
private var _angle : Number;
private var _shapeHolders : Vector.<Sprite> = new Vector.<Sprite>();
private var _slice : Sprite;
public function SnowFlake()
{
_angle = Math.PI / SLICES;
createFlakeStage();
createShapeHolders();
}
private function createShapeHolders() : void
{
for (var n : Number = 0;n < SLICES; n++)
{
var shape : Sprite = new Sprite();
shape.mouseEnabled = false;
shape.mouseChildren = false;
shape.addChild(new Sprite());
shape.addChild(new Sprite());
shape.getChildAt(1).scaleX = -1;
shape.x = stage.stageWidth / 2;
shape.y = stage.stageHeight / 2;
_shapeHolders.push(shape);
shape.rotation = 360 / SLICES * n;
addChild(shape);
}
}
private function createFlakeStage() : void
{
for (var n : Number = 0;n < SLICES; n++)
{
var slice : Sprite = createSlice(_angle);
slice.x = stage.stageWidth / 2;
slice.y = stage.stageHeight / 2;
slice.rotation = 360 / SLICES * n;
slice.addEventListener(MouseEvent.MOUSE_DOWN, beginShape);
slice.alpha = 0;
_sliceArray.push(slice);
addChild(slice);
}
}
private function createSlice(angle : Number) : Sprite
{
var slice : Sprite = new Sprite();
slice.graphics.moveTo(0, 0);
slice.graphics.lineStyle(1,0);
slice.graphics.beginFill(0,.1);
slice.graphics.lineTo(Math.cos((angle)-Math.PI/2)*RADIUS, Math.sin((angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(Math.cos(-(angle)-Math.PI/2)*RADIUS, Math.sin(-(angle)-Math.PI/2)*RADIUS);
slice.graphics.lineTo(0, 0);
slice.graphics.endFill();
slice.graphics.moveTo(0, 0);
slice.graphics.lineTo(0,Math.sin((_angle)-Math.PI/2)*RADIUS);
slice.graphics.endFill();
return slice;
}
private function beginShape(e : MouseEvent) : void
{
_slice = e.target as Sprite;
for (var i : Number = 0;i < SLICES; i++)
{
var side1 : Sprite = _shapeHolders[i].getChildAt(0) as Sprite;
var side2 : Sprite = _shapeHolders[i].getChildAt(1) as Sprite;
side1.graphics.lineStyle(1,0xFFFFFF);
side1.graphics.moveTo(_slice.mouseX, _slice.mouseY);
side2.graphics.copyFrom(side1.graphics);
}
stage.addEventListener(MouseEvent.MOUSE_MOVE, renderShape);
stage.addEventListener(MouseEvent.MOUSE_UP, endShape);
}
private function renderShape(e : MouseEvent) : void
{
for (var i : Number = 0;i < SLICES; i++)
{
var side1 : Sprite = _shapeHolders[i].getChildAt(0) as Sprite;
var side2 : Sprite = _shapeHolders[i].getChildAt(1) as Sprite;
side1.graphics.lineTo(_slice.mouseX, _slice.mouseY);
side2.graphics.copyFrom(side1.graphics);
}
}
private function endShape(e : MouseEvent) : void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, renderShape);
stage.removeEventListener(MouseEvent.MOUSE_UP, endShape);
}
}
}
Posted: January 6th, 2010 | Author: admin | Filed under: Uncategorized | No Comments »
I haven’t posted anything is the past few weeks because I was busy working on Flurrious.com — Digitas’ ‘09 holiday card. It let’s you draw a snowflake and send it to a friend — and watch all of the other snowflakes other people make. For each snowflake sent, Digitas donates $1 to UNICEF.
The site has done MUCH better than expected — over 23,000 snowflakes were made (in less than 2 weeks), and almost $7,000 donated to UNICEF. The site is pretty small at 200kb, but so far we’ve served over 600GB of data to users (most of it is probably the snowflakes that are being saved as PNGs on the server).

To create this application I had to do an extensive brush-up on my flash drawing API skills. I’m using some of the new features from FP10 like IGraphicsPath and the 3D rotations (as well as Papervision3D). That graphics data is being saved in Vector arrays, and is stored on the database. When you view a snowflake, that data is being passed back to flash, and then get’s drawn again with the same API.
In the next few posts I’ll talk about some of the techniques I used to create the application. some of the highlights in my opinion are: saving and recreating vector data, creating smooth lines, and creating the circular slidres. Creating the snowflake generative drawing I think was the least challenging thing in the site…
-itai
Posted: October 31st, 2009 | Author: admin | Filed under: Uncategorized | No Comments »
after some thought of how to make this more practical, I decided to make another version.
In this version the 2 boxes next to the selected box and the 2 above and below grow as well, and the response and alignment is much better.
here’s what it looks like now:

here is the source
Posted: October 5th, 2009 | Author: admin | Filed under: Uncategorized | 1 Comment »
today at Max2009 it was announced that CS5 Flash Professional will have an export option for the iPhone!! hurray!
http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/
Posted: September 30th, 2009 | Author: admin | Filed under: Uncategorized | 1 Comment »
I came across a really cool panel for flash CS4 IDE that lets you create SWFs with multiple fonts that you can access in run-time.
check it out:
http://blog.johannest.com/2009/09/28/runtime-font-publisher-a-flash-cs4-extension/
Posted: September 28th, 2009 | Author: admin | Filed under: Uncategorized | No Comments »
I was messing around with Kaleidoscopes last year, and refactored an AS2 kaleidoscope that Quasimondo posted in 2005. I was looking for that code, and found it laying around, so I thought I’d post it if anyone’s interested to see a way of doing it in AS3. Please note that if you want to use this for commercial use, you will need to contact Quasimondo because it’s based on his code. If you need more sources for Kaleidoscopes, you can check out the book ActionScript 3.0 Image Effects by Todd Yard (Friends Of Ed).

source
Posted: September 16th, 2009 | Author: admin | Filed under: Effects, Uncategorized | 1 Comment »
This is a simple class I created for some transition effect. It’s really simple, but the effect is cool.
I’m basically taking any displayObject and creating a grid of bitmap copies of it. then animating them with BetweenAS3 tween engine (if you haven’t heard of it, it’s worth checking out — really fast and clean engine from LibSpark). I’m planning on decoupling the animation from the grid creation, so you could create different animations with the segments (or tie them in with a particle system), so that might be coming soon.
To use it, all you need to do call it like this:
new ExplodeBitmap(sprHolder, explodingSpr, widthSegments, heightSegments, smoothing);
here’s what it looks like (with randomized segment width and height):

source