Tuesday, September 22, 2009

Squiggly - Spell Check Engine Example

We've been waiting for a spell check engine in Flash for a long time. Now, Adobe has released Squiggly. From Adobe Labs :
Squiggly is a spell checking engine for Adobe® Flash® Player and Adobe AIR®. The Squiggly library allows you to easily add spell checking functionality in any Flex 3 based text control.
While the included UI class requires the Flex SDK, the core spell checking engine can be used in pure Flash applications without any dependency on Flex packages.

Currently, only English dictionary is available but you can create your own dictionaries with a bundled AIR app.

The 3 main classes we'll be using are SpellChecker, SpellingDictionary and SpellUI all of which belong to the com.adobe.linguistics.spelling. package. There are several sub packages but they need not be used directly.

Usage :

If we are using the Flex SDK, then we can use the SpellUI class to spell check any Flex component like ,
SpellUI.enableSpelling(textArea, "usa.zwl");
where usa.zwl is the dictionary file.

However, if you are not using the Flex SDK, then the SpellUI class cannot be used. In that case, we can use the SpellChecker class directly to perform spell checking. Here's a sample demo class i've put together.

Hope that's useful for anyone. Happy coding :D

Sunday, August 16, 2009

Creating a game with APE - APEOut - Part 3

In the third and final part of this tutorial, we'll finish off this game by adding collision detection and scoring.Before we start, make sure you've read the first and the second part of this series. So, lets get to it.

Adding collision detection :

In order to add collision detection, we'll need to add an Event listener to the ball. After the ball defnition, add the following code :

ball.addEventListener(CollisionEvent.COLLIDE, onCollision);

Now, we have to code what happens if a collision occurs. Create the onCollision event handler as follows :

private function onCollision(e:CollisionEvent):void
{
var collidingItem:* = e.collidingItem;

if (collidingItem != topWall && collidingItem != bat &&
collidingItem != leftWall && collidingItem != rightWall)
{
--brickCount;
group.removeParticle(collidingItem);
}
}


Here the collidingItem will refer to the object that comes in contact with the ball. Now, we have to remove the object if it is a brick or do nothing if its the bat or the walls. So, we check if the collidingItem is not one of the walls or the bat, then we remove it from the group and reduce the brickCount.

Finishing up the game :

Now, run the game, our bat is moving with the mouse, the ball is bouncing and destroying the bricks that it comes in contact with. Everything is working as it is supposed to. But every good game needs scores, right, so declare a score variable as a Number and a TextField to display the score.We also need a Boolean variable to see if the game is over or not. Here's the final full code :

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;

import org.cove.ape.APEngine;
import org.cove.ape.CircleParticle;
import org.cove.ape.CollisionEvent;
import org.cove.ape.Group;
import org.cove.ape.RectangleParticle;
import org.cove.ape.VectorForce;

/**
* APEOut - A Breakout clone using the ActionScript Physics Engine (APE)
* @author Pradeek
*/

[SWF(width = 600, height = 400)]
public class APEOut extends Sprite
{
private var group:Group;
private var leftWall:RectangleParticle;
private var rightWall:RectangleParticle;
private var topWall:RectangleParticle;
private var bat:RectangleParticle;
private var ball:CircleParticle;
private var brickCount:Number;

private var score:Number;
private var scoreText:TextField;
private var gameOver:Boolean;

public function APEOut():void
{
initAPE();
initObjects();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function initAPE():void
{
APEngine.init();
APEngine.container = this;
APEngine.addForce(new VectorForce(false, 0, 4));
}

private function initObjects():void
{
gameOver = false;

score = 0;
scoreText = new TextField();
scoreText.x = 400;
scoreText.y = 25;
addChild(scoreText);

group = new Group(true);

leftWall = new RectangleParticle( -10, 0, 10, 1000, 0, true, 1, 0.3, 1);
rightWall = new RectangleParticle(610, 0, 10, 1000, 0, true, 1, 0.3, 1);
topWall = new RectangleParticle(0, -10, 1200, 10, 0, true, 1, 0.3, 1);

bat = new RectangleParticle(250, 325, 125, 10, 0, true, 1, 0.50, 1);
bat.alwaysRepaint = true;
bat.setFill(0x0000FF);

ball = new CircleParticle(220, 225, 15, false, 1, 0.65, 1);
ball.setFill(0xFF0000);
ball.addEventListener(CollisionEvent.COLLIDE, onCollision);

var rows:int = 5;
var cols:int = 8;

brickCount = rows * cols;

var currentX:Number = 100;
var currentY:Number = 100;

var brickWidth:Number = 50;
var brickHeight:Number = 10;

for (var i:uint = 0; i < uint =" 0;" rectangleparticle =" new" currentx =" 100;" px =" mouseX;" text = "Score : "> 400)
{
gameOver = true;
group.removeParticle(ball);
scoreText.text = "Game Over. \nYou lose. \nFinal Score : " + score.toString();
}

if (brickCount == 0)
{
gameOver = true;
group.removeParticle(ball);
scoreText.text = "Game Over. \nYou win. \nFinal Score : " + score.toString();
}
}
}
}


Hope the series was a bit useful to you. If you have any questions or suggestions, please drop a comment. Thanks for reading :D

Creating a game with APE - APEOut - Part 2

In part 2 of this tutorial, we're going to add the bricks and add motion for the bat. Make sure you've read the first part of this tutorial and lets get going.

Creating the bricks :

Add the following code to the initObjects method after creating the ball.Also create a private variable brickCount for the number of bricks in the stage.
var rows:int = 5;
var cols:int = 8;

brickCount = rows * cols;

var currentX:Number = 100;
var currentY:Number = 100;

var brickWidth:Number = 50;
var brickHeight:Number = 10;

for (var i:uint = 0; i < rows; i++)
{
for (var j:uint = 0; j < cols; j++)
{
var brick:RectangleParticle = new RectangleParticle(currentX, currentY, rickWidth, brickHeight, 0, true, 1, 0.3, 1);
brick.setFill(Math.random() * 0xFFFFFF);
group.addParticle(brick);
currentX += brickWidth + 5;
}
currentX = 100;
currentY += brickHeight + 5;
}
What we're doing here is simply creating a brick at the position (currentX,currentY) and incrementing with the brickWidth and a gap value. We also set a random color for the bricks. Run the file. You'll see a ball bouncing on the bat and about 40 bricks lined up in 5 rows. When the ball collides with the brick, it just bounces off. Moving the bat : To move the bat just add the line
bat.px = mouseX;
before the APEngine.step() call in the onEnterFrame event handler. If you run the game now, you'll see that the image of the bat doesn't move but if you move your mouse, the ball will fall down. So, add the following line under the bat defnition.
bat.alwaysRepaint = true;

Now, it looks something like a game. We have the bat, the ball and the bricks. All we need is to add collision detection and scores. We'll do that in the next post.
Stay tuned.

Saturday, August 15, 2009

Creating a game with APE - APEOut - Part 1

Following up on my introductory blog post on APE, Today we are going to create a simple Breakout clone with APE. I'm going to call this APEOut having just 1 level. I'll split this tutorial into 3 parts. In the first part, we'll create a bat, ball and the boundaries. In the second part, we'll create the bricks and add movement for the bat. In the third part, we'll add collision detection and scores.
So, lets get started.

package
{
import flash.display.Sprite;
import flash.events.Event;

import org.cove.ape.APEngine;
import org.cove.ape.Group;
import org.cove.ape.VectorForce;

/**
* APEOut - A Breakout clone using the ActionScript Physics Engine
* @author Pradeek
*/

[SWF(width = 600, height = 400)]
public class APEOut extends Sprite
{
private var group:Group;

public function APEOut():void
{
initAPE();
initObjects();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function initAPE():void
{
APEngine.init();
APEngine.container = this;
APEngine.addForce(new VectorForce(false, 0, 4));
}

private function initObjects():void
{
group = new Group(true);
APEngine.addGroup(group);
}

private function onEnterFrame(e:Event):void
{
APEngine.step();
APEngine.paint();
}

}

}

The above code is similar to the one we wrote in the last post. Basically, we're setting up the engine, creating a group and updating and drawing on the ENTER_FRAME event. Next, we create the 3 boundaries - top, left and right and the bat and the ball. Create objects of the RectangleParticle class for topWall, leftWall , rightWall and bat and the CircleParticle class for the ball. Modify the initObjects method as follows :

private function initObjects():void
{
group = new Group(true);

leftWall = new RectangleParticle( -10, 0, 10, 1000, 0, true, 1, 0.3, 1);
rightWall = new RectangleParticle(610, 0, 10, 1000, 0, true, 1, 0.3, 1);
topWall = new RectangleParticle(0, -10, 1200, 10, 0, true, 1, 0.3, 1);

bat = new RectangleParticle(250, 325, 125, 10, 0, true, 1, 0.50, 1);
bat.setFill(0x0000FF);

ball = new CircleParticle(220, 225, 15, false, 1, 0.65, 1);
ball.setFill(0xFF0000);

group.addParticle(leftWall);
group.addParticle(rightWall);
group.addParticle(topWall);

group.addParticle(bat);

group.addParticle(ball);

APEngine.addGroup(group);
}


A little code explanation :
We position three rectangular blocks on the top, left and the right sides. Since they are walls, we're hiding them. We create a bat and a ball and position them appropriately.
Try to run this. You should see the ball bouncing on the bat. If you wait a bit, you'll see that it hits the top and bounces back.
The next step is creating the bricks and making the bat move. We'll do that in the next post. If you have any questions, please post it in the comments. Thanks for reading.

Friday, August 14, 2009

Getting started with Physics in AS3 : APE Tutorial

Today, we're going to see a very simple tutorial for using the Actionscript Physics Engine (APE). There are several Physics engines in the AS3 but APE is probably the easiest to use. So, download the library via SVN here and lets get started.
Here is the code :

package
{
import flash.display.Sprite;
import flash.events.Event;

import org.cove.ape.APEngine;
import org.cove.ape.CircleParticle;
import org.cove.ape.Group;
import org.cove.ape.RectangleParticle;
import org.cove.ape.VectorForce;

[SWF(width = 600, height = 400, backgroundColor='0x000000')]
public class APExample Sprite
{
public function APExample():void
{
initAPE();

initObjects();

addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function initAPE():void
{
// Initialize APE
APEngine.init();

// Set the container for APE
APEngine.container = this;

// Add gravity
APEngine.addForce(new VectorForce(false, 0, 2));
}

private function initObjects():void
{
// Create a group to hold all the objects with collision
var group:Group = new Group(true);

// Create a rectangle for rhe floor
var floor:RectangleParticle = new RectangleParticle(0, 400, 1200, 25, 0, true);

// Create a circle
var circle:CircleParticle = new CircleParticle(225, -100, 25);

// Add the floor to the group
group.addParticle(floor);

// Add the circle to the group
group.addParticle(circle);

// Add the group to the engine
APEngine.addGroup(group);
}

private function onEnterFrame(e:Event):void
{
// Update and Draw
APEngine.step();
APEngine.paint();
}

}

}
Compile and run. You should see a white rectangle at the bottom as the "floor" and the ball will fall down. Experiment a little bit by chaanging the gravity value for some interesting results. For example, you could set a positive value for x which would make the ball move sideways. But still, one ball falling down and bouncing isn't much of an example. In the coming tutorials, we'll be developing a simple game using APE. Stay tuned. :D

UPDATE : Certain compiler errors occur (changes in several classes) if you are using the given download link in the APE homepage. The one i am using here is from svn.
I've also uploaded the project with the APE files for those without SVN. You can download it here. Sorry for the mmistake.

Monday, August 3, 2009

Getting started with Away3D

Today, I decided to play with Away3D and immediately found it to be much better than Papervision. Comparatively, Away3D is much faster than Papervision ( implementation of FP10 features ). So, here is a simple tutorial to get you up and going with Away3D.
In this tutorial, I'll be using Flex Builder to create an ActionScript project. I'm naming it Away3DTest. Now download the latest Away3D build from here. Extract the source to the src folder and type in the following code :


package
{
import away3d.cameras.Camera3D;
import away3d.containers.Scene3D;
import away3d.containers.View3D;
import away3d.core.math.Number3D;
import away3d.core.render.Renderer;
import away3d.materials.BitmapMaterial;
import away3d.primitives.Cube;

import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;

[SWF( backgroundColor = '0x000000')]
public class Away3DTest extends Sprite
{
[Embed(source='texture.jpg')]
private var Texture:Class;

private var scene:Scene3D;
private var camera:Camera3D;
private var view:View3D;

private var cube:Cube;

public function Away3DTest()
{
initAway3D();
initObjects();
}

private function initAway3D():void
{
camera = new Camera3D();
camera.x = 100;
camera.y = 100;
camera.z = -1000;
camera.lookAt( new Number3D() );

scene = new Scene3D();

view = new View3D();
view.x = 200;
view.y = 200;
view.scene = scene;
view.camera = camera;
view.renderer = Renderer.BASIC;
addChild(view);
}

private function initObjects():void
{
cube = new Cube();
cube.material = new BitmapMaterial(Bitmap(new Texture()).bitmapData);
scene.addChild(cube);

addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function onEnterFrame(e:Event):void
{
cube.rotationX += 1;
cube.rotationY += 1;
cube.rotationZ += 1;

view.render();
}

}
}



Here I assume you have a file named texture.jpg in your source directory.Now an explanation of the code :
  1. We create variables for the View3D, Camera3D and the Scene3D class and assign the scene and the camera variable to the view variable. This is setting up the Away3D engine and is written as a seperate function initAway3D()
  2. We create a cube and create a new BitmapMaterial for it using the embedded texture.
  3. We create an ENTER_FRAME event listener which does the rendering using the view.render() method. Meanwhile we'll also rotate the cube on all 3 axes.
  4. Save and run you should get a cube with the texture rotating on all the axes.
Hope that was useful to anyone starting Away3D. Happy coding. :D

Monday, June 8, 2009

Alchemy Tutorial : Sending data to Alchemy and back

Following up on my previous post on getting started with Alchemy, today, we're going to see how to send a variable from Flex to a C method as arguments. In this example, we're just going to pass an integer from Flex to a C function which will return the square of the integer value. Ok, lets get to the code.
The C code : square.c

#include "AS3.h"

static AS3_Val sqre( void* self, AS3_Val num )
{
int a;
a = AS3_IntValue(num);
int square = a*a;
return AS3_Int(square);
}

int main()
{
AS3_Val cMethod = AS3_Function( NULL, sqre );
AS3_Val result = AS3_Object( "sqre : AS3ValType" , cMethod);
AS3_Release( cMethod );
AS3_LibInit( result );
return 0;
}
As you can see, the main function is still pretty much the same. When passing arguments to a C method, that method should always return an AS3_Val object and always accept a pointer in addition to the other parameter.The rest of the code is very simple.
Compile the C code into a swc using
gcc square.c -O3 -Wall -swc -o square.swc
Now, we create an ActionScript project in Flex and import the swc. Type the following code :


package {
import flash.display.Sprite;
import cmodule.square.CLibInit;

public class Squaring extends Sprite
{
public function Squaring()
{
var loader:CLibInit = new CLibInit;
var lib:Object = loader.init();
trace(lib.sqre(5));//Output : 25
}
}
}

Now save and debug. You should get the output as 25. Now that we know how to send and receive data from Alchemy and Flex, we can move on to some real world applications.Hope this post was useful. Happy experimenting :D

Friday, June 5, 2009

Getting Started with Alchemy : Hello World tutorial in Flash CS4 and Flex 3

Today, we are going to do a hello world example for Adobe Alchemy. For those, who don't know what Alchemy is,
Alchemy is a research project that allows users to compile C and C++ code that is targeted to run on the open source ActionScript Virtual Machine (AVM2). The purpose of this preview is to assess the level of community interest in reusing existing C and C++ libraries in Web applications that run on Adobe Flash Player and Adobe AIR.

First up, we have to set up alchemy. You can find the setup instructions in Adobe Labs. InsideRIA also have an article about setting up alchemy. You can find that here.

Now that you have setup Alchemy, lets do the traditional Hello World example with it. First up the C code - helloWorld.c :


#include "AS3.h"

static AS3_Val returnString()
{
char* text = "Hello World";
return AS3_String(text);
}

int main()
{
AS3_Val cMethod = AS3_Function( NULL, returnString );
AS3_Val result = AS3_Object( "returnString : AS3ValType" , cMethod);
AS3_Release( cMethod );
AS3_LibInit( result );
return 0;
}

Some code explanations:
  • AS3_Val is the data type Alchemy uses to represent ActionScript objects.
  • All functions visible to ActionScript have to declared with AS3_Val as the return type.
  • The first step in main() is to declare all methods for ActionScript as AS3_Function instances.
  • Next, create an AS3_Object which will hold references to all these functions.
  • "Release" the unwanted methods by calling AS3_Release.
  • Finally, notify the runtime that the library has been initialized by using AS3_LibInit. Pass the object containing all the functions visible to ActionScript. Note : This should be called last.
Now that we have written our C code, we have to compile and convert it into a SWC. Open Cygwin, turn on Alchemy using the alc-on; command and navigate to the folder where you have saved your C program. Then type the following command :
gcc helloWorld.c -O3 -Wall -swc -o helloworld.swc
This should create the SWC file with the filename helloworld.swc in that folder.If there were any errors in the C program, it will be shown here.

Now that you have the SWC file, we can use it in Flash or Flex to call its functions.

Using the SWC file in Flash CS4 :

  1. Open Flash CS4 and create a new ActionScript 3 document.
  2. In the Properties panel, click on the Edit profile and click on ActionScript 3 Settings.
  3. In the Library path tab, navigate to the SWC file and add it.
  4. In the Actions panel, type the following code :

    //CLibInit is the Alchemy bridge to the C/C++ methods.
    import cmodule.helloworld.CLibInit;

    var loader:CLibInit = new CLibInit;
    var library:Object = loader.init();
    trace(library.returnString());
  5. Save and run the file. The text "Hello World" should be displayed in the Output panel.

Using the SWC file in Flex Builder 3 :

  1. Start Flex Builder 3 and create a new ActionScript project.
  2. Right-click the project, select Properies and select ActionScript Build Path. In the Library path tab, add the SWC file.
  3. Add the following code : (My ActionScript project's name is HelloWorld )

    package
    {
    import flash.display.Sprite;

    import cmodule.helloworld.CLibInit;

    public class HelloWorld extends Sprite
    {
    public function HelloWorld()
    {
    var loader:CLibInit = new CLibInit;
    var lib:Object = loader.init();
    trace(lib.returnString());
    }
    }
    }
  4. Save and debug the application. You should see the "Hello World" in the Console.
Congratulations, you have written a function in a C program and called that function in ActionScript using Adobe Alchemy. Hope this post was useful to you. I'll post more in the coming days. Have fun :D

Monday, June 1, 2009

Flash Builder 4 and Flash Catalyst are on Labs

Looks like Adobe finally released the betas of Flash Builder 4 and Flash Catalyst on Adobe Labs. Read more at Ryan Stewart's blog. Happy experimenting :D


EDIT : Looks like Flash Catalyst is free ( Adobe is providing a serial number below the download link) but Flash Builder 4 is a 30 day trial. You can extend the trial if you have a valid Flex Builder 3 serial key.

Sunday, May 31, 2009

Creating Zip files with Adobe AIR with the nochump library

Following up on my previous post, here's how to archive a bunch of files and make a zip file.

After getting all the files you want to put in the archive, create a new ZipEntry object for each file and add it to a ZipOutput object using the putNextEntry() of the ZipOutput class. Then pass the ByteArray data of the file to the write() method of the ZipOutput class and close the entry by using the closeEntry() method. Finally, call the finish() method once you have done the same for all the files.

Here's the code snippet :

import flash.events.FileListEvent;
import flash.filesystem.*;

import nochump.util.zip.*;

private var zipInput:File = new File();
private var zipOutput:File = new File();
private var zipFile:ZipOutput;

private var files:Array = new Array();

private function loadFiles():void
{
zipInput.browseForOpenMultiple("Open ZIP file");
zipInput.addEventListener(FileListEvent.SELECT_MULTIPLE, onSelect);
}

private function onSelect(e:FileListEvent):void
{
for(var i:uint = 0;i < e.files.length;i++)
{
var stream:FileStream = new FileStream();
var f:File = e.files[i] as File;
stream.open(f,FileMode.READ);
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData);
var file:Object = new Object();
file.name = f.name;
file.data = fileData;
files.push(file);
}
}

private function createZIP():void
{
zipFile = new ZipOutput();
for(var i:uint = 0; i < files.length; i++)
{
var zipEntry:ZipEntry = new ZipEntry(files[i].name);
zipFile.putNextEntry(zipEntry);
zipFile.write(files[i].data);
zipFile.closeEntry();
}
zipFile.finish();

zipOutput.browseForSave("Select target directory");
zipOutput.addEventListener(Event.SELECT, onSave);
}

private function onSave(e:Event):void
{
var archiveFile:File = e.target as File;
if(!archiveFile.exists)
{
var stream:FileStream = new FileStream();
stream.open(archiveFile,FileMode.WRITE);
stream.writeBytes(zipFile.byteArray);
stream.close();
}
}

As usual you can download the project archive here. Happy experimenting :D

Saturday, May 30, 2009

Extracting Zip files in Adobe AIR with the nochump library

Today, I'm going to show you how you can use the nochump library to extract zip files with Adobe AIR.

The ZipFile class constructor takes an IDataStream object as the parameter.Here you can use a ByteArray or a FileStream object which contains the data of the zip file. The entries property of the ZipFile object contains all the files in the archive as ZipEntry objects. Here the directory itself(excluding the files inside it) also counts as a ZipEntry object, so make sure to check using the isDirectory property of the ZipEntry object. Finally get the data of a single file using zipFile.getInput() method.

Here's the code :

import flash.filesystem.*;
import flash.net.FileFilter;

import nochump.util.zip.*;

private var zipInput:File = new File();
private var zipOutput:File = new File();
private var zipFile:ZipFile;

private function loadZIP():void
{
var filter:FileFilter = new FileFilter("ZIP","*.zip");
zipInput.browseForOpen("Open ZIP file",[filter]);
zipInput.addEventListener(Event.SELECT, onSelect);
}

private function onSelect(e:Event):void
{
var stream:FileStream = new FileStream();
stream.open(zipInput,FileMode.READ);

zipFile = new ZipFile(stream);
extract.enabled = true;
}

private function extractZIP():void
{
zipOutput.browseForDirectory("Select Directory for extract");
zipOutput.addEventListener(Event.SELECT, onDirSelect);
}

private function onDirSelect(e:Event):void
{
for(var i:uint = 0; i < zipFile.entries.length; i++)
{
var zipEntry:ZipEntry = zipFile.entries[i] as ZipEntry;
// The class considers the folder itself (without the contents) as a ZipEntry.
// So the code creates the subdirectories as expected.
if(!zipEntry.isDirectory())
{
var targetDir:File = e.target as File;
var entryFile:File = new File();
entryFile = targetDir.resolvePath(zipEntry.name);
var entry:FileStream = new FileStream();
entry.open(entryFile, FileMode.WRITE);
entry.writeBytes(zipFile.getInput(zipEntry));
entry.close();
}
}
}

You can download the project archive here. Happy experimenting :D

Wednesday, May 13, 2009

Introducing Simple3D - A library for 3D in Flash Player 10

Simple 3D is a library for developing 3D content in Flash Player 10.Unlike the other major 3D engines like Papervision3D, Away3D, Alternativa3D, Simple3D is just a library of standalone classes for 3D content.Using a standalone class greatly reduces compile size. The compile size of the SWF is around 3KB. Currently, the library contains 5 primitives and an ASE parser. I'm working on a couple more parsers and i'll release it soon.

Here is a simple sphere demo.




























Download : Simple3D Google Code Page

If you guys have any ideas to improve the code, or would like to contribute to the library, just drop a comment. I have created a Google Group for discussion.You can find it here.

Happy coding :D

Friday, May 8, 2009

Flash CS4 Tutorial : Using the drawTriangles method to render 3D objects

I’d like to say hello and welcome to those of you reading my feeds via MXNA. In this tutorial, we are going to use Flash Player 10’s 3D capabilities to render a cube. The drawTriangles method added to the Graphics class is used to render 3D objects in FP10. Lets get started.

First up,create a new document class. Here we’re going to name it Cube3D. Open the Cube3D.as file and type in the following code.

 

package    
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;

    public class Cube3D extends Sprite
    {
        private var matrix3D:Matrix3D;
        private var vertices:Vector.<Number>;
        private var projectedVertices:Vector.<Number>;
        private var UVData:Vector.<Number>;
        private var indices:Vector.<int>;
        private var cube:Sprite;

        public function Cube3D()
        {
            matrix3D = new Matrix3D();
            vertices = Vector.<Number>([50,-50,50,
                                         50,-50,-50,
                                        -50,-50,-50,
                                        -50,-50,50,
                                        50,50,50,
                                        50,50,-50,
                                        -50,50,-50,
                                        -50,50,50
                                        ]);
            projectedVertices = new Vector.<Number>;
            UVData = new Vector.<Number>;
            indices = Vector.<int>([3,1,0, 3,2,1, 5,7,4, 5,6,7, 1,4,0, 1,5,4, 2,5,1, 2,6,5, 3,6,2, 3,7,6, 7,0,4, 7,3,0]);

            cube = new Sprite();
            addChild(cube);

            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(e:Event):void
        {
            cube.x = cube.y = 200;

            matrix3D.appendRotation(1,Vector3D.X_AXIS);
            matrix3D.appendRotation(1,Vector3D.Y_AXIS);
            matrix3D.appendRotation(1,Vector3D.Z_AXIS);           

            Utils3D.projectVectors(matrix3D,vertices,projectedVertices,UVData);

            cube.graphics.clear();
            cube.graphics.beginFill(0x0066FF);
            cube.graphics.lineStyle(1,0x0000FF,1);
            cube.graphics.drawTriangles(projectedVertices, indices);
            cube.graphics.endFill();
        }
    }
}

Now lets take a look at the code:

Now we can use the Vector class to store data instead of Arrays. Vectors are similar to arrays but allow you to store only one type of data. The vertices vector stores the xyz co-ordinates of the 8 vertices of the cube. In order to draw a 3D object, we use the drawTriangles method. The syntax for this method is

drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = “none”)

For the indices parameter, we have to split the cube into triangles. A good way for that is to take 1 side of a cube, and split it into 2 triangles. Read the drawTriangles section of this post by senocular for better understanding of splitting an object into triangles. A section from the post:

Square Triangles indices

As you can see, a square can be split up into 2 triangles.For the square, the indices are 0,1,2 and 1,2,3. Similarly using the same technique for the cube’s 6 sides, we can calculate the indices.

Look at the following code:

matrix3D.appendRotation(1,Vector3D.X_AXIS);

matrix3D.appendRotation(1,Vector3D.Y_AXIS);

matrix3D.appendRotation(1,Vector3D.Z_AXIS);

This is equivalent to rotating through the X,Y&Z axes by 1 degree. Hence this code is executed in every frame. Now take a look at the next line :

Utils3D.projectVectors(matrix3D,vertices,projectedVertices,UVData);

The syntax for the projectVectors method is projectVectors(m:Matrix3D, verts:Vector.<Number>, projectedVerts:Vector.<Number>, uvts:Vector.<Number>)

This method, using a projection Matrix3D object, projects a Vector of three-dimensional space coordinates ( verts ) to a Vector of two-dimensional space coordinates ( projectedVerts ). This method gives us the 2D vertices (projectedVertices) to use in the drawTriangles method.

Here is the final cube :



And with a little experimenting, here is a pyramid :




Feel free to drop a comment if you want to kknow anything.
Happy experimenting :D

FXG Tutorial : Understanding Paths

Continuing on the FXG Tutorials, in this tutorial, we will be seen Paths in FXG. Paths represent the outline of a shape in FXG. Paths are created using the Path element and the co-ordinates are given in its data attribute. A Path element supports fills,strokes,filters and blendmodes.



Path data contains numbers and specific letters which specify instructions (M indicates a moveto command, the L indicate lineto command, and the z indicates a closepath command).


Here is the example:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<fx:Library>

<fx:Definition name="Triangle">
<Group>
<Path data="M 100 100 L 50 200 L 150 200 z">
<fill>
<SolidColor color="#FF0000" />
</fill>
<stroke>
<SolidColorStroke weight="3" color="#0000FF" />
</stroke>
</Path>
</Group>
</fx:Definition>

<fx:Definition name="Square">
<Group>
<Path data="M 100 100 L 200 100 L 200 200 L 100 200 z">
<fill>
<SolidColor color="#FF0000" />
</fill>
<stroke>
<SolidColorStroke weight="3" color="#0000FF" />
</stroke>
</Path>
</Group>
</fx:Definition>

</fx:Library>

<Group>
<layout> <HorizontalLayout/> </layout>
<fx:Triangle/>
<fx:Square/>
</Group>

</Application>

As you can see, in the Path data of the Triangle,we have . This merely says : First, Move to 100,100. Then draw a Line to 50,200. Then draw a Line to 150,200. Then close the Path. We can use this to draw any shape that we want easily. You can read more here. Happy experimenting :D. Feel free to drop a comment about anything. Happy experimenting :D

FXG Tutorial : Creating and using Symbols

In the previous tutorial, I showed you how to create a simple Hello World tutorial in FXG. In this tutorial, we will be creating and using symbols. Symbols are nothing but a set of graphics with a defined name which can used to use it multiple times without having to rewrite the code.Here is the code:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<fx:Library>
<fx:Definition name="Square">
<Group>
<Rect width="200" height="200">
<fill>
<SolidColor color="#FF0000" />
</fill>
</Rect>
</Group>
</fx:Definition>

<fx:Definition name="Circle">
<Group>
<Ellipse width="200" height="200">
<fill>
<SolidColor color="#FF0000" />
</fill>
</Ellipse>
</Group>
</fx:Definition>

<fx:Definition name="SampleText">
<Group>
<SimpleText text="This is a sample text"/>
</Group>
</fx:Definition>
</fx:Library>

<Group>
<layout>
<VerticalLayout/>
</layout>

<fx:Square/>
<fx:Circle/>
<fx:SampleText/>
</Group>

</Application>


We can create symbols with the Definition tag. The definitions must be placed inside of the Library tag. As you can see, in the Definition tag, the name attribute is used to specify the name for the symbol. FXG also allows 2D transformations with the Matrix class. We can also apply Flex effects,filters,transitions,etc. in FXG.Happy Experimenting :D

FXG Tutorial : Getting Started with a Hello World Example.

FXG is an XML based graphics interchanged format for the Flash Platform. In this tutorial,we are going to get started with FXG with a simple Hello World example. So after you set up Flex Builder with the latest nightly build of Flex 4, (You can see how here if you don’t know.) we can start.

FXG documents have a logical structure. The Graphic element serves as the root for any FXG document. The Group elementis used to group related graphic elements.Currently, basic shapes such as Rectangle and Ellipse can provided but we can easily create our required shapes with the given functions.We can add text with the SimpleText tag which provides simple text formatting as well.

Here is the Hello World code:



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns="library://ns.adobe.com/flex/spark">

<Graphic>
<Group>
<Rect width="200" height="200">
<fill>
<SolidColor color="#000000"/>
</fill>
<stroke>
<SolidColorStroke weight="3" color="#FF0000"/>
</stroke>
</Rect>
<SimpleText text="Hello World" x="50" y="50"/>
</Group>
</Graphic>

</Application>


This will create a black square with a red stroke with the text “Hello World”. I’ll be posting more tutorials on FXG soon. Happy experimenting :D

New IDE for Pixel Blender - Conduit

A company called Lacquer has just released the first 3rd party tool for creating Pixel Blender filters named Conduit. This application lets you to create Pixel Blender filters in a visual design environment using drag and drop manipulation, without the need to learn the Pixel Blender language. It exports a Pixel Blender bytecode (.pbj) file which can be used in Flash Player 10 as filters,fills,etc. As far as pricing is concerned

Conduit for Flash Pixel Bender is currently in beta testing. For a limited time, the product can be preordered for 50 euros (about 68 USD*).Preorders include download access to the latest beta versions for both Mac and Windows (please note that the Windows beta is not yet available but will be released in October 2008).

And for those who want a free edition, there is also Conduit Live Home which has a couple of limitations :

  • Only iSight (Apple web camera) is supported for video capture
  • Video record-to-disk is not available
  • Maximum image and video resolution that can be imported is 320*240 pixels
  • Export is not available

Currently, only the Mac version is available for download. The Windows version is expected to be available in October 2008.

Conduit Live Home can be downloaded at Conduit Live Home.

You can find intros and tutorials here.

ASDoc for MXML files

The Flex SDK page has a spec titled “ASDoc in MXML“.

Currently there is no way for users to add documentation to components defined in mxml files. The asdoc tool doesn’t read the comments in mxml files. Increasingly more components in the flex framework are being written in mxml.

Adding support for mxml in the asdoc tool would help developers to generate documentation for their components.

Several customer have also added requests in JIRA to support class level comments in mxml files.

So now you can add ASDoc comments by the syntax <!— asdoc comment –> . The — are necessary for the compiler to understand that they are ASDoc comments.

To get the full details chect out the spec : ASDoc in MXML.

AlivePDF Tutorial : How to create a PDF file with Flex/AIR

Here, we are going to see how to use the alivepdf library written by Thibault Imbert. This library allows us to create pdf content with Flex. In this tutorial, we will be using Adobe AIR in order to save the file. So lets get started. First create a new Flex project and select Desktop Application as the type. Download the AlivePDF library here. Copy the swc file and paste it in the libs folder. Now in the main application file, type the following code.


<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import org.alivepdf.pdf.PDF;
import org.alivepdf.saving.Method;
import org.alivepdf.fonts.*;
import org.alivepdf.pages.Page;
import org.alivepdf.display.Display;
import org.alivepdf.layout.*;

private var pdf:PDF;
private var file:File;
[Embed( source="/assets/o-png24.png", mimeType="application/octet-stream" )]
private var pngBytes:Class;
public function generate ():void
{
var pdf:PDF = new PDF( Orientation.PORTRAIT, Unit.MM, Size.A4 );
pdf.setDisplayMode( Display.FULL_PAGE, Layout.SINGLE_PAGE );
var newPage:Page = new Page ( Orientation.PORTRAIT, Unit.MM, Size.A4 );
pdf.addPage( newPage );
pdf.setFont(FontFamily.ARIAL , Style.NORMAL, 12);
pdf.addText("This is a sample text",5,15);
pdf.drawCircle(25,35,15);
pdf.addPage();
pdf.addImageStream( new pngBytes() as ByteArray );
var fs:FileStream = new FileStream();
file = File.desktopDirectory.resolvePath("testPage.pdf");
fs.open( file, FileMode.WRITE);
var bytes:ByteArray = pdf.save(Method.LOCAL);
fs.writeBytes(bytes);
fs.close();
}
]]>
</mx:Script>
<mx:Button click="generate()" label="Generate PDF" horizontalCenter="0" verticalCenter="0"/>
</mx:WindowedApplication>

and Run the application.

The main class here is PDF. The addPage method adds a new page. Similarly, there are a lot of options such as addImage, addText and also graphic methods such as drawCircle. drawRect,etc.You can look at the documentation for this given in the zip file.

Happy experimenting :D

Thursday, May 7, 2009

Dynamically changing Pixel Blender data at runtime

In my previous post, i had demonstrated the use of Pixel blender filters in Flex. In this post, we will be modifying the file that we did last time so that the user can change the red,blue and green channels and the alpha values at runtime.So if you haven’t done so , finish the previous tutorial. We can access the data of the Pixel Blender filter by the data property of the Shader class.The data property is an object of type ShaderData and it contains all the variables and parameters of the filter. The parameters are available as variables of type ShaderParameter. Here, we are going to use the same filter we used last time and we are going to allow the user to change the values of the color parameter at runtime with a Slider. Open the mxml file that you used for the previous tutorial and make the changes as :



<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://ns.adobe.com/mxml/2009" xmlns:gumbo="library:adobe/flex/gumbo" xmlns:mx="library:adobe/flex/halo" applicationComplete="init()">
<Script>
<![CDATA[
import flash.display.*;
import flash.filters.ShaderFilter;
[Bindable]private var shader:Shader;
private var shaderFilter:ShaderFilter;
[Embed(source="assets/RGBAEdit.pbj", mimeType="application/octet-stream")]
private var ImgFilter:Class;

private function init():void
{
shader = new Shader(new ImgFilter());
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}

private function apply(e:Event):void
{
shader.data.color.value[0] = rVal.value;
shader.data.color.value[1] = gVal.value;
shader.data.color.value[2] = bVal.value;
shader.data.color.value[3] = aVal.value;
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}
]]>
</Script>

<mx:Panel id="panel" title="Pixel Blender Test"> <mx:Image id="img" source="@Embed('assets/test.png')"/>

<mx:HBox>

<mx:Label text="Red"/>

<mx:HSlider id="rVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

<mx:Label text="Green"/>

<mx:HSlider id="gVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

</mx:HBox>

<mx:HBox>

<mx:Label text="Blue"/>

<mx:HSlider id="bVal" liveDragging="true" minimum="0" maximum="1" value="0" change="apply(event)"/>

<mx:Label text="Alpha"/>

<mx:HSlider id="aVal" liveDragging="true" minimum="0" maximum="1" value="1" change="apply(event)"/>

</mx:HBox>

</mx:Panel>

</Application>

Pixel Blender Tutorial : Using Pixel Blender in Flex

Pixel Blender Toolkit is a new graphics programming language being developed by Adobe. Pixel Blender Toolkit can be used to create Pixel Blender filters and effects. You can find a lot of sample filters in the Gallery in Adobe Labs and in the Pixel Blender Exchange.  The Pixel Blender reference(which is in the docs folder inside your Pixel Blender Toolkit Folder with the name “PixelBenderLanguage10“) explains the basics of the language. Start the Adobe Pixel Blender Toolkit and click on “Create a new Filter” button. You’ll see that a small program is automatically generated. Type the following code and save it with any filename.

 
<languageVersion : 1.0;>

kernel RGBAEdit <
namespace : "My Filters";
vendor : "Pradeek";
version : 1;
description : "Editing RGBA values of an image";
>
{
input image4 image;
parameter float4 color
<
minValue:float4(0, 0, 0, 0);
maxValue:float4(1, 1, 1, 1);
defaultValue:float4(1, 1, 0, 1);
>;
output pixel4 result;

void evaluatePixel()
{
result = sampleNearest(image,outCoord());
result *= color;
}
}


Press Run. You will be prompted to load a image. Load it and run. You will see the image and the parameters on the side with which you can change the red,blue,green colors and the alpha of the image.Click File and “Export Kernel Filter for Flash Player“. This creates a Pixel Blender Byte Code file (.pbj file) which we can use in flex.



Now, create a Flex project and create a folder named assets inside the src folder and copy paste the .pbj file that you generated and a sample image into the assets folder. Now type in the following code in your mxml file. I have named the byte code file as RBGAEdit.pbj and the sample image file as test.png.




<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://ns.adobe.com/mxml/2009" xmlns:gumbo="library:adobe/flex/gumbo" xmlns:mx="library:adobe/flex/halo" applicationComplete="init()">

<Script>
<![CDATA[

import flash.display.*;
import flash.filters.ShaderFilter;

private var shader:Shader;
private var shaderFilter:ShaderFilter;

[Embed(source="assets/RGBAEdit.pbj", mimeType="application/octet-stream")]
private var ImgFilter:Class;

private function init():void
{
shader = new Shader(new ImgFilter());
shaderFilter = new ShaderFilter(shader);
img.filters = [shaderFilter];
}

]]>
</Script>

<mx:Image id="img" source="@Embed('assets/test.png')"/>

</Application>


This is just a basic usage of the Pixel Blender Toolkit. You can use it as



  • a filter (ShaderFilter)

  • a blend mode

  • a fill and

  • a number cruncher



Happy experimenting :D

Hello World Application in Gumbo

I thought I should follow up on my previous post with a very simple Hello World application.

Here is the code:



<Application xmlns="http://ns.adobe.com/mxml/2009">
<Button label="Hello World">
</Button>
</Application>

Thats it. As you can see there is no more <mx:…> stuff. Just plain <Button/>. There aren’t many Gumbo components ,so this is just the beginning. I’ll put up more stuff once I make them.

Gumbo!!! Setup Flex 4 in Flex Builder 3

So I finally decided to jump into Flex 4 (codenamed “Gumbo”).Gumbo has a lot of changes from Flex 3. Check out this article for what’s new in Flex 4 . Gumbo doesn’t have a stable release yet so download a nightly build. Gumbo needs Flash Player 10, so you have to download that as well. So lets get started.

First download and install Flash Player 10 (Astro).

Follow the instructions on the page. Next, download the latest nightly build of Gumbo here and extract

it to a folder in your computer. Start Flex Builder and select Window -> Preferences . Choose “Installed Flex SDKs” in the Flex category and click the Add button. Browse and select the folder where you unzipped the SDK and click OK to add the SDK. Select the checkbox near Flex 4 to make it the default SDK if you want to.

Creating a Flex 4 Project:

Create a new project as you normally would. Right click the project, select Properties and select “Flex Compiler”. Under the HTML Wrapper, change the “Require Flash Player version” as 10.0.0. If you did not set Flex 4 SDK as the default SDK, then change the Flex SDK version to Flex 4 using the combo box and click OK.

Congrats! ,You have set-up your first Flex4 project in Flex Builder 3.

I’ll put up code samples and sample apps. Feel free to drop a comment if you found this useful.

Hello world!

Hey guys. This is my personal blog on my random experiments . Feel free to drop comments.