Review and On The Move

Topics:
Review: Packages and Size in AS3
Review: AS3 in Flash
Going Mobile with SMS

Questions and Answers

Question: How do "packages" work in AS3?

Answer: If you want to use a package, you must first create a directory structure for that package. For instance, if I want to use the package "com.mobvcasting" package in AS3 for my code, I would first create a directory structure that looks like this:
		Desktop (or anywhere really)
			-> src
				-> com
					-> mobvcasting
						-> (actionscript source files)
		
Then in AS3 file, I would use the following package definition:
package com.mobvcasting

I would compile with my mxmlc command line compiler like so:
mxmlc -compiler.source-path=/path/to/src/ /path/to/src/com/mobvcasting/SOURCECODE.as
(of course, you have to change "/path/to/" to be the actual path and sourcecode.as to be the actual file you want to compile.)

Question: How do I set the size of an AS3 Sprite/MovieClip or whatever..?

Answer: This is a strange quirk of working with classes that extend "Sprite". Since they don't actually have a size until something is placed inside of them, setting the size early on doesn't work. You have to set the size after you have added something to them. Here is an example (note that the size setting is in the constructor after the textfield has been added with "addChild"):

// Always start with a "package"
package com.mobvcasting
{
	// Like Java you need to import the classes you are going to use
	import flash.display.Sprite;
	import flash.text.TextField;

	// The class name is the same as the file name, case sensitive
	// Extending Sprite or MovieClip gives you the ability to do most things you can do in Flash
    public class Simple extends Sprite
    {
		// Declare a String variable
		private var astring:String = "Hello World";
		
		// Declare a Text Field		
		private var displayText:TextField = new TextField();
		
    	public function Simple():void
    	{
    		// Set the text of the textfield to be our string
			displayText.text = "" + astring;
			
			// Display it
			addChild(displayText);  // Do this before setting the size
			
			// These are just in case the scale has been thrown off
			this.scaleX = 1;
			this.scaleY = 1;

			this.width = 100;  // Set the width and height after you do an "addChild"
			this.height = 100;
			
			// Set it's position on the stage if you like			
			this.x = 20;
			this.y = 40;

			// Set the Background Color so we can see how big it is.	
			this.opaqueBackground = 0xFF0000;
		}
	}
}
		
		

AS3 in Flash (easier than using MXMLC?)

Let's say you aren't comfortable on the command line with a plain text editor to do your AS3 programming. You want to use the various AS3 code that we have gone over but you just want to do it in Flash itself.

It is actually very straight-forward: Take any of our AS3 examples and remove the "package", "class" and "constructor" definitions along with any "import" statements and any references to "public" or "private" and the code will run on the timeline.

It is good practice to create a seperate layer for your Actions so be sure to do that. It is also a good idea to name it something like "code" or "actionscript" so you can find it later..

Here is the code of a full AS3 file:
// Always start with a "package"
package com.mobvcasting
{
	// Like Java you need to import the classes you are going to use
	import flash.display.Sprite;
	import flash.text.TextField;

	// The class name is the same as the file name, case sensitive
	// Extending Sprite or MovieClip gives you the ability to do most things you can do in Flash
    public class Simple extends Sprite
    {
		// Declare a String variable
		private var astring:String = "Hello World";
		
		// Declare a Text Field		
		private var displayText:TextField = new TextField();
		
    	public function Simple():void
    	{
    		// Set the text of the textfield to be our string
			displayText.text = "" + astring;
			
			// Display it
			addChild(displayText);  // Do this before setting the size
			
			// These are just in case the scale has been thrown off
			this.scaleX = 1;
			this.scaleY = 1;

			this.width = 100;  // Set the width and height after you do an "addChild"
			this.height = 100;
			
			// Set it's position on the stage if you like			
			this.x = 20;
			this.y = 40;

			// Set the Background Color so we can see how big it is.	
			this.opaqueBackground = 0xFF0000;
		}
	}
}		
		
If you would like to use this code in Flash without adding it to a MovieClip you would re-write it as follows:
		// Declare a String variable
		var astring:String = "Hello World";
		
		// Declare a Text Field		
		var displayText:TextField = new TextField();
		
		// Set the text of the textfield to be our string
		displayText.text = "" + astring;
			
		// Display it
		addChild(displayText);  // Do this before setting the size
			
		// These are just in case the scale has been thrown off
		this.scaleX = 1;
		this.scaleY = 1;

		this.width = 100;  // Set the width and height after you do an "addChild"
		this.height = 100;
			
		// Set it's position on the stage if you like			
		this.x = 20;
		this.y = 40;

		// Set the Background Color so we can see how big it is.	
		this.opaqueBackground = 0xFF0000;
		
		
As you can see, without all of the code blocks it all just runs.. You probably want to leave the "function" definitions in place (although remove the "private" keyword) if you are going to be calling them.

Going Mobile with SMS

One way that we can help with the audience problem is to utilize something like SMS (or perhaps email) to alert people of an event or even alert us when people are available and ready to participate in a live fashion.

TextMarks is a free online service that allows for the sending and recieving of text messages on the regular mobile network. TextMarks allows anyone to register a keyword of their choosing and to utilize the shortcode 41411.

(I registered the L1V3 for demonstration purposes)

One of the great things about TextMarks is that you can have the service hit a script running on a remote server through a web request (HTTP).

Using this functionality as well as the ability to send SMS back you can allow mobile users to participate in "Live Web" applications.

To have my keyword hit a script that I am running on a webserver, I have to choose "Respond to a keyword with text from a webpage" when setting up the keyword with TextMarks:



The URL I put in is as follows: http://itp.nyu.edu/~sve204/liveweb/textmarks.php?phone=\p&text=\0

TextMarks substitutes the user's phone number where the "\p" is and the message they send where the "\0" is. (More documentation can be found here: http://www.textmarks.com/dev/docs/recv/.

Now I can write the "textmarks.php" script..
<?
        // This PHP file: textmarks.php gets hit with phone and message when someone texts 41411 L1V3
        // http://itp.nyu.edu/~sve204/liveweb/textmarks.php?phone=\p&text=\0 

        // Phone Number:
        $phone = $_GET['phone'];

        // Message:
        $message = $_GET['text'];

        // Save the message to the text file which changes my pages
        $fp=fopen('/home/sve204/public_html/liveweb/textmarks.txt','w');
        fwrite($fp,$message);
        fclose($fp);

        echo "Yay!!!  Thanks";
?>
		
Now when ever someone texts 41411 with the keyword L1V3 this script is called and they get a text back that says: "Yay!! Thanks"

In addition this script writes out the contents of their message to a text file: "textmarks.txt" on the server (this file needs to exist in the first place).

SMS + AJAX

Now we can do a lot of different things with their message using AJAX or Flash. This example AJAX based page, takes the contents of their message and changes the background color of the page:

<html>
	<head>
		<!-- Always load up the ajax.js file so you don't have to do all of the hard work -->
		<script type="text/javascript" src="ajax.js"></script>
		
		<!-- Do your own JavaScript below -->
		<script type="text/javascript">

			// A variable to hold the interval id
			var interval = null;	
	
			// A function to call our server side file or script
			// This get's triggered by the interval (in function setup_ajax()
			function call_ajax()
			{
				makeHttpRequest('http://itp.nyu.edu/~sve204/liveweb/textmarks.txt',ajax_return);
			}

			// A function that gets called when the server responds
			// This is where you would do what you want with the response
			// In this case, I am changing the color of the page
			function ajax_return(response)
			{
				document.bgColor="#" + response;
			}
	
			// Setup AJAX function, creates a timeout so that we run something periodically
			function setup_ajax()
			{
				// Set interval of 2000 milliseconds
				// Keeps going over and over again
				interval = setInterval("call_ajax()",2000);
			}			
		
			// Register setup_ajax with the onload event of the window (when it is done loading)..	
			// This makes setup_ajax run after the browser renders the page
			function addOnLoad()
			{
				if (window.addEventListener)
				{
					window.addEventListener('load', setup_ajax, false);
				}
				else if (window.attachEvent)
				{
					window.attachEvent('onload', setup_ajax);
				}
			}
			// Tell the browser to run the addOnLoad function above
			addOnLoad();
		</script>
	</head>
	<body>
		<h1>Nothing Really On This Page</h1>
	</body>
</html>
		
As you can see, the AJAX is periodically checking the text file that the textmarks script is writing to and changing the color of the page. You can try it: http://itp.nyu.edu/~sve204/liveweb/textmarks_example.php

Of course, you can do so much more.. Have people participate in a chat through text and online or have people be able to alter a page that is displayed on a large screen or anything along those lines..

AJAX Gotchas

One thing that you need to be concerned with when doing any type of AJAX is that the request through AJAX needs to come from the same server that page initially loaded from. In our case, itp.nyu.edu.. You can't load data from elsewhere without getting it from itp.nyu.edu in the end. Of course, you could have a PHP script make the request for data from elsewhere and return that data to the AJAX script.

SMS + Flash

We can also use this technique to do very similar things in Flash.

This AS3 file (called Flajax.as) loads data from the textfile as does the AJAX script below. Instead of changing the background color of the entire page, it just changes the background color of itself and write the data to a textfield.

package com.mobvcasting
{
	import flash.display.Sprite;
	import flash.text.TextField;
	
	// Network library
	import flash.net.*;
	
	// Events library
	import flash.events.*;
	
	// Timer library
	import flash.utils.Timer;
	
	
	public class Flajax extends Sprite
	{
		// Declare a String variable
		private var astring:String = "Hello World";
		
		// Declare a Text Field		
		private var displayText:TextField = new TextField();
		
		// Declare the URL Loader
		private var loader:URLLoader;
		
		// Declare the request
		private var request:URLRequest;
		
		public function Flajax():void
		{
			// Set the text of the textfield to be our string
			displayText.text = "" + astring;
			
			// Display it
			addChild(displayText);
			this.scaleX = 1;
			this.scaleY = 1;
	
			this.width = 100;
			this.height = 100;
			
			this.x = 20;
			this.y = 40;
	
			this.opaqueBackground = 0xFF0000;
			
			// Create the URL Loader - Load any Web document, like you would with AJAX
			loader = new URLLoader();
	
			// Register the function that will receive the content
			loader.addEventListener(Event.COMPLETE, pageLoaded);
	
			// Create the request
			request = new URLRequest("http://itp.nyu.edu/~sve204/liveweb/textmarks.txt");
	
			// Setup the Timer
			var myTimer:Timer = new Timer(2000, 0);
			myTimer.addEventListener("timer", loadPage);
			myTimer.start();			
			
			// Make the request
			//loadPage();
			// Called by the timer
		
		}
		
		private function loadPage(event:TimerEvent):void
		{
			// Make the request
			try {
				loader.load(request);
			} catch (error:Error) {
				trace("Unable to load requested document.");
			}		
			trace("Should have loaded");
		}
		
		public function pageLoaded(event:Event):void
		{
			trace("loaded: " + loader.data);            
			displayText.text = loader.data;
			
			if (loader.data.valueOf() == "blue")
			{
				// have to use "valueOf" to do == comparison
				this.opaqueBackground = "0x0000FF";
				trace("should be blue");
				trace(this.opaqueBackground)
			}
			else if (loader.data.valueOf() == "red")
			{
				// have to use "valueOf" to do == comparison
				this.opaqueBackground = "0xFF0000";       
				trace("should be red");
				trace(this.opaqueBackground);
			}
			else 
			{
				this.opaqueBackground = "0x" + loader.data;       
				trace("should be: " + loader.data);
				trace(this.opaqueBackground);
			}
		}
	}
}
You can try it out: http://itp.nyu.edu/~sve204/liveweb/Flajax.swf

Download it: http://itp.nyu.edu/~sve204/liveweb/Flajax.as

The keys to making this work are the following chunks of code:

This allows us to connect to network.
// Network library
import flash.net.*;

This allows us to get notified when something happens.
    
// Events library
import flash.events.*;

This allows us to do something periodically.
// Timer library
import flash.utils.Timer;

The following code in the constructor sets up the objects that are going to do the work. We need a URLLoader, an event listener for the URLLoader and a timer to periodically call our "loadPage" function.
// Create the URL Loader - Load any Web document, like you would with AJAX
loader = new URLLoader();

// Register the function that will receive the content
loader.addEventListener(Event.COMPLETE, pageLoaded);

// Create the request
request = new URLRequest("http://itp.nyu.edu/~sve204/liveweb/textmarks.txt");

// Setup the Timer
var myTimer:Timer = new Timer(2000, 0);
myTimer.addEventListener("timer", loadPage);
myTimer.start();			

// Make the request
//loadPage();
// Called by the timer

The laodPage function below actually makes the request (just like an ajax request) to the server for the text file:
private function loadPage(event:TimerEvent):void
{
	// Make the request
	try {
		loader.load(request);
	} catch (error:Error) {
		trace("Unable to load requested document.");
	}		
	trace("Should have loaded");
}

The "pageLoaded" function is what gets called when the page is loaded. It is the response from the text file or script that is called above. In this case, it takes the contents and changes the background color.
public function pageLoaded(event:Event):void
{
	trace("loaded: " + loader.data);            
	displayText.text = loader.data;
	
	if (loader.data.valueOf() == "blue")
	{
		// have to use "valueOf" to do == comparison
		this.opaqueBackground = "0x0000FF";
		trace("should be blue");
		trace(this.opaqueBackground)
	}
	else if (loader.data.valueOf() == "red")
	{
		// have to use "valueOf" to do == comparison
		this.opaqueBackground = "0xFF0000";       
		trace("should be red");
		trace(this.opaqueBackground);
	}
	else 
	{
		this.opaqueBackground = "0x" + loader.data;       
		trace("should be: " + loader.data);
		trace(this.opaqueBackground);
	}
}

(You could also use Flash Remoting: http://www.adobe.com/products/flashremoting/ or open source clones: http://osflash.org/open_source_flash_projects#servers_and_remoting (AMFPHP, openAMF, AMF::Perl and so on)

Flash Gotchas

As with AJAX their are some gotcha's with this script as well. It needs to either be on the same server as the SWF or a "crossdomain.xml" file has to be put on the server you are requesting data from. It also can't be run locally, it needs to come from the server.

Send SMS

Another great thing that can be done with TextMarks is to send an SMS to an individual. (First the individual needs to subscribe to your keyword).

You could use this to alert people when you are "live" or you could use it to alert you to the fact that someone is visiting your "live" page.

In order to do this, you need to register for an API key from TextMarks (it takes some time so do it early): http://www.textmarks.com/dev/api/reg/?ref=devsb

TextMarks, being the nice folks that they are have written a PHP library that uses their API, making things like sending messages very easy.

Documentation is here: http://www.textmarks.com/dev/docs/apiclient/php/

Their PHP library is here: http://www.textmarks.com/dev/docs/apiclient/php/TextMarksAPIClient.class.php Here is an example PHP script which uses their library and API: (PHP Page: sendmesomething.php)
<?php
// Require/Import the TextMarksAPIClient.class.php file
// Download from: http://www.textmarks.com/dev/docs/apiclient/php/TextMarksAPIClient.class.php
require "TextMarksAPIClient.class.php";

ini_set('display_errors', true);
ini_set('display_startup_errors', true);
error_reporting(E_ALL);

// This page get's called by AJAX when someone is on a page for a while (2 minutes)...
// Now I know I have audience and I can go online and interact with them..
// I should probably check the user agent to make sure it is a real person and not Google or Yahoo but they shouldn't run JavaScript anyway..
sendTextToMe();

// Send a text message to a single TextMark subscriber:
function sendTextToMe()
{
	
	// TextMarks API Key: Request from: http://www.textmarks.com/dev/api/reg/?ref=devapi
	$sMyApiKey='MYAPIKEY';
	
	// TextMarks Username or Phone Number
	$sMyTextMarksUser = 'MYPHONENUMBER'; //(or my TextMarks phone)
	$sMyTextMarksPass = 'MYPASSWORD';
	
	// TextMarks Keyword
	$sKeyword = 'MYKEYWORD';
	
	// Who are you going to send the text to?
	$sTo = 'MYPHONENUMBER';
	
	// The message to send
	$sMessage = "Someone is on your site";
	
	// Create the TextMarks Object with the above parameters
	$tmapi = new TextMarksAPIClient_Messaging($sMyApiKey, $sMyTextMarksUser, $sMyTextMarksPass);
	
	// Send the message!
	$tmapi->sendText($sKeyword, $sTo, $sMessage);
	
	// For debugging, dump out the results
	var_dump($tmapi);
	
	echo "Notified";
}
?>
If you visit this page in a browser, it will trigger a message. This could easily be placed in a normal web page to alert you that someone is viewing your page. Unfortunately, you would be getting text messages every time someone or something (google bot, msn bot and the like) loads your page.

Going one step further would be to trigger it via AJAX after a certain amount of time so you know that someone is sticking around and they can run javascript/ajax (unlike a google crawler or yahoo crawler)

Here is Live Page which triggers the above through AJAX after 20 seconds. I then know that someone is there and I can go LIVE: (It is almost identical to the color changing example above but instead of reading from the text file it calls the above PHP script and instead of happening over and over again, it happens once (setTimeout instead of setInterval.) Of course it also has a Flash video player so that the user can see me should I decide to go live..)
<html>
	<head>
		<!-- Always load up the ajax.js file so you don't have to do all of the hard work -->
		<script type="text/javascript" src="ajax.js"></script>
		
		<!-- Do your own JavaScript below -->
		<script type="text/javascript">

			// A variable to hold the interval id
			var interval = null;	
	
			// A function to call our server side file or script
			// This get's triggered by the interval (in function setup_ajax()
			function call_ajax()
			{
				makeHttpRequest('http://itp.nyu.edu/~sve204/liveweb/sendmetext.php',ajax_return);
			}

			// A function that gets called when the server responds
			// This is where you would do what you want with the response
			// In this case, I am changing the color of the page
			function ajax_return(response)
			{
				alert(response);
			}
	
			// Setup AJAX function, creates a timeout so that we run something periodically
			function setup_ajax()
			{
				// Set interval of 20000 milliseconds = 20 seconds
				// Keeps going over and over again - Nope, using setTimeout so it only happens once
				interval = setTimeout("call_ajax()",20000);
			}			
		
			// Register setup_ajax with the onload event of the window (when it is done loading)..	
			// This makes setup_ajax run after the browser renders the page
			function addOnLoad()
			{
				if (window.addEventListener)
				{
					window.addEventListener('load', setup_ajax, false);
				}
				else if (window.attachEvent)
				{
					window.attachEvent('onload', setup_ajax);
				}
			}
			// Tell the browser to run the addOnLoad function above
			addOnLoad();
		</script>
	</head>
	<body>
		<h1>If you hang out here..  I will get notified and I might come online</h1>
		
    <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="550" height="400" id="player_stream" align="middle">
        <param name="allowScriptAccess" value="sameDomain" />
        <param name="movie" value="new_player_stream.swf" />        
		<param name="quality" value="high" />        
		<param name="bgcolor" value="#ffffff" />       
		<param name="flashvars" value="rtmp_url=rtmp://itp.nyu.edu/sve204/live&thestream=gottext" />   
	<embed src="new_player_stream.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="player_stream" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="rtmp_url=rtmp://itp.nyu.edu/sve204/live&thestream=gottext" />
     </object>		
		
	</body>
</html>
If you are really curious if I will respond, visit the page: My Live Home Page