Showing posts with label as3. Show all posts
Showing posts with label as3. Show all posts

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

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