October 26th, 2010
Posted in Actionscript | No Comments »
August 30th, 2010
Use UILoader to load the external swf and on the INIT event we will be able to get the loaded swf total frames. Don't forget to drag the UILoader component (from the components panel, ctr+F7) into your library, and import fl.containers.*.
Actionscript:
import fl.containers .*;
var swfLoader:UILoader = new UILoader( ) ;
swfLoader.scaleContent = false ;
swfLoader.addEventListener ( Event.INIT , loader_init) ;
function loader_init( evt:Event) :void
{
var mc:MovieClip = swfLoader.content as MovieClip ;
trace ( mc.totalFrames ) ;
}
var urlReq:URLRequest = new URLRequest( "to_be_loaded.swf" ) ;
swfLoader.load ( urlReq) ;
I recently used this technique to build video like player (play, stop, seek) for swf's.
Posted in Actionscript | No Comments »
August 26th, 2010
I am releasing a new game (in-house build), Gems Swapping Knight
It's a classic match 3 gems puzzle game. In this version the engine only recognizes 3 gems in a row (not 4 or 5), in the future I do plan to change this and also add more fun stuff into the game like bombs. Initially it was planned as a demo for a potential client, but I soon realized that I would rather build the game for myself, and release it here.
The game is build using actionscript 3, it took me around 4 days to build a working version and several days to build the graphics and put it all together, all this while working on other projects. I am planning to release the source code in the future.
Here are the game instructions:
The goal of the game is to gain higher scores by matching three gems of the same color, vertical or horizontal. You can only move a gem up, down, left or right. When a chain of three gems is formed, they disappear, the gems on top fall down and the empty space is filled with random new gems.
Every 10 matches earns you a special coin. You use this coins to get a new mix of gems in the case you see that no more moves are possible.
To move the gems, you click on the gem you wish to swap, click again on the gem you wish to be swapped with or hold down your mouse, move your pointer over the gem to be swapped with, and release your button.
The game is over when you have zero coins and no more moves are possible.
Give Gems Swapping Knight a try !
Tags: flash game Posted in games | No Comments »
June 23rd, 2010
This is a very basic text animation engine, but it allows you to build your own animation styles and it's fairly easy to understand how it works.
Download the source file. .
I developed this animation engine while working on the Semicolon Wars game . The whole purpose was to identify punctuations and blank spaces in any given sentence (it's a punctuation game). Once the function worked as I wanted, I realized that I can use this function as an animation engine.
How it works.
It takes the string you want to animate and for each character in the string it creates a new MovieClip that contains a dynamic TextField.
Actionscript:
function animateText( textToAnimate:String , animationType:String ) {
var totalCharacters:int = textToAnimate.length ;
for ( var i:int = 0 ; i<= totalCharacters; i++)
{
var myChar:charMc = new charMc( ) ;
textContainer.addChild ( myChar) ;
var mcRef:MovieClip = myChar as MovieClip ;
mcRef.name = "myCharMc" + i;
myChar.letterText .autoSize = TextFieldAutoSize.LEFT ;
myChar.letterText .text = textToAnimate.charAt ( i) ;
}
}
To create the charMc class, create a dynamic textfield (embed the font, set the Anti-alias for animation), name it "letterText". With the textfield selected hit "F8" (convert to symbol), type MovieClip, check the "Export to Actionscript" box and in the Class box name it "charMc".
Now we have to arrange the MovieClips x, y positions.
Actionscript:
function animateText( textToAnimate:String , animationType:String )
{
//clean up
while ( textContainer.numChildren > 1 )
{
textContainer.removeChildAt ( textContainer.numChildren -1 ) ;
}
var margin:int = 20 ;
var cX:int = margin;
var cY:int = margin;
var rightLimit:int = textContainer.width - margin;
var totalCharacters:int = textToAnimate.length ;
var metrics:TextLineMetrics;
for ( var i:int = 0 ; i<= totalCharacters; i++)
{
var myChar:charMc = new charMc( ) ;
textContainer.addChild ( myChar) ;
var mcRef:MovieClip = myChar as MovieClip ;
mcRef.name = "myCharMc" + i;
myChar.letterText .autoSize = TextFieldAutoSize.LEFT ;
myChar.letterText .text = textToAnimate.charAt ( i) ;
metrics = myChar.letterText .getLineMetrics ( 0 ) ;
if ( cX> rightLimit)
{
cY += metrics.height ;
cX = margin;
var reverCounter:int = i;
while ( textToAnimate.charAt ( reverCounter) != " " )
{
reverCounter--;
}
for ( var lb:int = reverCounter+1 ; lb <= i; lb++)
{
var myMc:MovieClip = textContainer.getChildByName ( "myCharMc" + lb) as MovieClip ;
myMc.y = cY;
myMc.x = cX;
metrics = myMc.letterText .getLineMetrics ( 0 ) ;
cX += metrics.width ;
}
}
else
{
myChar.x = cX;
myChar.y = cY;
cX += metrics.width ;
}
animateMc( mcRef, myComboBox.selectedItem .label , i*0 .01 ) ;
}
}
The metrics = myMc.letterText.getLineMetrics(0); does the trick we need to correctly space the movieclips.
To animate we create a simple animateMc function:
Actionscript:
function animateMc( targetMc:MovieClip , animationType:String , delayAmount:Number ) {
switch ( animationType) {
case "writeOn" :
TweenLite.from ( targetMc, 1 , { alpha:0 , ease:Linear.easeOut , overwrite:true , delay:delayAmount} ) ;
break ;
case "flyIn" :
TweenLite.from ( targetMc, 1 , { alpha:0 , z:-500 , ease:Sine.easeOut , overwrite:true , delay:delayAmount} ) ;
break ;
case "3DSpin" :
targetMc.visible =false ;
targetMc.z = -500 ;
var myPath:Array = new Array ( ) ;
myPath.push ( { z:-200 , rotationX:randRange( -360 , 360 ) , rotationY:randRange( -360 , 360 ) , rotationZ:randRange( -360 , 360 ) } ) ;
myPath.push ( { z:-400 , rotationX:randRange( -360 , 360 ) , rotationY:randRange( -360 , 360 ) , rotationZ:randRange( -360 , 360 ) } ) ;
Tweener.addTween ( targetMc, { z:0 , rotationX:0 , rotationY:0 , rotationZ:0 , _bezier:myPath, time :3 , transition:"easeoutquad" , delay:delayAmount, onStart:tweenStart} ) ;
break ;
case "randomColor" :
targetMc.visible =false ;
TweenLite.from ( targetMc, 2 , { tint:randomColors[ randRange( 0 , randomColors.length ) ] , rotationZ:randRange( -360 , 360 ) , ease:Linear.easeOut , overwrite:true , delay:delayAmount, onStart:tweenStart} ) ;
break ;
}
function tweenStart( ) {
targetMc.visible =true ;
}
}
Thanks to the TweenLite and Tweener tween engines you can easily animate any MovieClip propriety (3D position, alpha, color, blur etc).
Get the source files and make some great animations on your own.
Tags: actionscript animation , text animation Posted in Actionscript | No Comments »
June 21st, 2010
The front end is html and css, powered by flash p2p and javascript
I just wanted to see if I can build a shoutbox/group chat app that has the front end build in html and styled with css. And here it is: Shoutbox/Chat in HTML, CSS, powered by JavaScript and Flash Player 10.1 . Open a few of them in different windows to see how it works.
This technique would let any designer implement it's own front end looks via the CSS styling. Download the files from here and try a different look.
Here is the JavaScript functionality (located in the "shoutbox.js" file):
JavaScript:
function onLoadedSwf( ) {
var flashobj = document.getElementById ( "flash_obj" ) ;
flashobj.focus ( ) ;
}
function onConnected( ) {
var chatiframe = document.getElementById ( "chat_iframe" ) ;
chatiframe.style .visibility = "visible" ;
chatiframe.style .height = "300px" ;
var shoutbox_elem = document.getElementById ( "shout_box" ) ;
shoutbox_elem.style .visibility = "visible" ;
shoutbox_elem.style .height = "80px" ;
var flashobj = document.getElementById ( "flash_obj" ) ;
flashobj.style .height = "0px" ;
flashobj.style .visibility = "hidden" ;
sendToJavaScript( "connected" , "" ) ;
}
function getFlashMovie( movieName) {
var isIE = navigator.appName .indexOf ( "Microsoft" ) != -1 ;
return ( isIE) ? window[ movieName] : document[ movieName] ;
}
function sendMessage( value) {
getFlashMovie( "flash_obj" ) .sendToFlash ( value) ;
document.getElementById ( 'chatmessage' ) .value = "" ;
}
function sendToJavaScript( user, message) {
var oIframe = document.getElementById ( "chat_iframe" ) ;
var oDoc = oIframe.contentWindow || oIframe.contentDocument ;
if ( oDoc.document ) {
oDoc = oDoc.document ;
}
oDoc.write ( "<br />" + user + ": " + message) ;
oIframe.contentWindow .scrollTo ( 0 , oDoc.body .scrollHeight ) ;
return true ;
}
function onEnter( e) {
var keynum
if ( window.event ) { keynum = e.keyCode } else if ( e.which ) { keynum = e.which }
if ( keynum == 13 ) { sendMessage( document.getElementById ( 'chatmessage' ) .value ) ;}
}
function onEnterUp( e) {
var keynum
if ( window.event ) { keynum = e.keyCode } else if ( e.which ) { keynum = e.which }
if ( keynum == 13 ) { document.getElementById ( 'chatmessage' ) .value = "" ;}
}
Also here is the actionscript code.
Actionscript:
const StratusAddress:String = "rtmfp://stratus.rtmfp.net/your-own-stratus-ley/" ;
var nc:NetConnection ;
var netGroup:NetGroup;
var user:String ;
var messageIncrement:int = 0 ;
var myGroupName:String = "your-shoutbox-adress" ;
function connect ( ) :void
{
conMc.visible = true ;
user = usr.text ;
nc = new NetConnection ( ) ;
nc.addEventListener ( NetStatusEvent.NET_STATUS ,netStatus) ;
nc.connect ( StratusAddress) ;
}
function setupGroup( ) :void
{
var groupspec:GroupSpecifier = new GroupSpecifier( myGroupName) ;
groupspec.serverChannelEnabled = true ;
groupspec.postingEnabled = true ;
netGroup = new NetGroup( nc,groupspec.groupspecWithAuthorizations ( ) ) ;
netGroup.addEventListener ( NetStatusEvent.NET_STATUS ,netStatus) ;
}
function netStatus( event:NetStatusEvent) :void
{
switch ( event.info .code )
{
case "NetConnection.Connect.Success" :
setupGroup( ) ;
break ;
case "NetGroup.Connect.Success" :
ExternalInterface.call ( "onConnected" ) ;
break ;
case "NetGroup.Posting.Notify" :
receiveMessage( event.info .message ) ;
break ;
}
}
function sendMessage( msg:String ) :void
{
messageIncrement++;
var message :Object = new Object ( ) ;
message .sender = netGroup.convertPeerIDToGroupAddress ( nc.nearID ) ;
message .user = user;
message .mi = messageIncrement;
message .text = msg;
message .action = "postChat" ;
netGroup.post ( message ) ;
receiveMessage( message ) ;
}
function receiveMessage( message :Object ) :void
{
var removeBreakRegExp:RegExp = new RegExp( "\n " ,"gi" ) ;
var ms:String = message .text ;
ms = ms.replace ( removeBreakRegExp,"" ) ;
if ( ms != "" )
{
ExternalInterface.call ( "sendToJavaScript" , message .user , message .text ) ;
}
}
if ( ExternalInterface.available )
{
try
{
ExternalInterface.addCallback ( "sendToFlash" , receivedFromJavaScript) ;
}
catch ( error :Error )
{
ExternalInterface.call ( "sendToJavaScript" , error .message ) ;
}
}
function receivedFromJavaScript( value:String ) :void
{
sendMessage( value) ;
}
conBt.addEventListener ( MouseEvent.CLICK , onConnectClick) ;
function onConnectClick( event:MouseEvent)
{
connect ( ) ;
}
usr.addEventListener ( KeyboardEvent.KEY_DOWN , onEnterKey) ;
function onEnterKey( event:KeyboardEvent)
{
if ( event.keyCode == 13 )
{
connect ( ) ;
}
}
user = "user" + Math .round ( Math .random ( ) * 10000 ) ;
usr.text = user;
conMc.visible = false ;
usr.addEventListener ( MouseEvent.ROLL_OVER , focusOnUserName) ;
function focusOnUserName( event:MouseEvent)
{
stage .focus = usr;
usr.setSelection ( 0 , usr.length ) ;
}
stage .focus = usr;
usr.setSelection ( 0 , usr.length ) ;
Tags: Flash , HTML , JavaScript , Shoutbox Posted in Flash apps | No Comments »
June 21st, 2010
To view the app you will need flash player 10.1 .
Broadcast an image
Simple drawing
Text annotation
Simple group chat
Image, drawing and text annotations X, Y screen position sharing
Video:
How it works:
The whiteboard uses the new p2p flash player 10.1 NetGroup Class to connect app users and netGroup.post(message) to broadcast a message to the group.
Here is some of the code it uses:
Actionscript:
const StratusAddress:String = "rtmfp://stratus.rtmfp.net/your-stratus-key/" ;
var nc:NetConnection ;
var netGroup:NetGroup;
var user:String ;
var messageIncrement:int ;
var myGroupName:String = "your.app.group.name" ;
function connect ( ) :void
{
nc = new NetConnection ( ) ;
nc.addEventListener ( NetStatusEvent.NET_STATUS ,netStatus) ;
nc.connect ( StratusAddress) ;
}
function setupGroup( ) :void
{
var groupspec:GroupSpecifier = new GroupSpecifier( myGroupName) ;
groupspec.serverChannelEnabled = true ;
groupspec.postingEnabled = true ;
netGroup = new NetGroup( nc,groupspec.groupspecWithAuthorizations ( ) ) ;
netGroup.addEventListener ( NetStatusEvent.NET_STATUS ,netStatus) ;
user = "user" + Math .round ( Math .random ( ) * 10000 ) ; // we need unique usernames
userNameText.text = user;
createDrawLayer( user) ; // creates the drawing layer based on the username
}
function netStatus( event:NetStatusEvent) :void
{
//trace(event.info.code);
switch ( event.info .code )
{
case "NetConnection.Connect.Success" :
setupGroup( ) ;
break ;
case "NetGroup.Connect.Success" :
txtChatMessages.text = "connected to group" ;
break ;
case "NetGroup.Posting.Notify" : // fires each time a message is posted in the group
receiveMessage( event.info .message ) ;
break ;
case "NetGroup.Neighbor.Connect" :
break ;
case "NetGroup.Neighbor.Disconnect" :
break ;
}
}
function sendMessage( ) :void
{
messageIncrement++;
var message :Object = new Object ( ) ;
message .sender = netGroup.convertPeerIDToGroupAddress ( nc.nearID ) ;
message .user = user;
message .rnd = messageIncrement;
message .text = txtMessage.text ;
message .action = "postChat" ;
netGroup.post ( message ) ;
incomingMessage( message ) ;
txtMessage.text = "" ;
}
function receiveMessage( message :Object ) :void
{
if ( message .user != user)
{
if ( message .action != null )
{
switch ( message .action )
{
case "postChat" :
incomingMessage( message ) ;
break ;
case "clear" : // delete your own drawing across all users connected
clearMc( message .user ) ;
break ;
case "postImage" :
showGroupImage( message .image ) ;
break ;
case "postImagePozition" : // changes the position of the broadcasted image
showGroupImagePoz( message .imageX , message .imageY ) ;
break ;
case "postTextField" : // creates the text annotation for all users in the group
recreateTextField( message .txtObj ) ;
break ;
case "postTextFieldPozition" : // changes the position of a text annotation
pozitionTextField( message .txtMc , message .px , message .py ) ;
break ;
case "editTextField" : // function that edits the changes made to a text annotation
editedTextField( message .txtName , message .txtContent ) ;
break ;
}
}
}
}
connect ( ) ; // start the application
Tags: actionscript , flash p2p , stratus Posted in Flash apps | 3 Comments »