Introduction
Coppercube is a tool that can be used to create interactive 3D applications, either for Windows or for the web. While Coppercube includes a number of behaviors, customized or complex actions still require custom code. The SWF files produced by Coppercube can be scripted using ActionScript. This tutorial shows you how.
Background
The code presented here is used as the basis for a number of Coppercube tutorials that you can view here.
Using the Code
Coppercube applications can be scripted through the SimpleAPI
, which is a set of functions that expose the inner properties of the elements in the scene. We will make use of this to create a light that changes color.
First the Coppercube application needs to be compiled. The sample project is included in the downloads, or can create your own using the steps described on this web page (you will need to add an additional light called Light2
if following these instructions).
Coppercube supports two scripting languages: ActionScript (Flash or Flex) and Squirrel. ActionScript is used to script the Flash applications, while Squirrel is used to script the Windows applications. This means your target audience (web or Windows) will define what language you use. This will be a web application, so we will use ActionScript.
Scripting Flash Coppercube applications basically involves loading the SWF file created by Coppercube into a new SWF created by your ActionScript compiler. We will use the Flex compiler to create the final scripted application. The SWF you create then modifies the elements inside the Coppercube SWF file.
To keep things simple, you can embed the Coppercube SWF inside the final SWF file. The process is described here. We use this same formula for our class called CoppercubeSprite
.
CoppercubeSprite.as
package
{
import flash.display.*;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.utils.ByteArray;
import gs.TweenMax;
[SWF(width="600", height="400", frameRate="100", backgroundColor="000000")]
public class CoppercubeSprite extends Sprite
{
[Embed(source="../resources/scripting.swf", mimeType="application/octet-stream")]
public static var EmbeddedCopperCubeSWFDataFile:Class;
private var loader:Loader;
private var simpleAPI:Object;
private var loadingFinished:Boolean;
private var applicationStarted:Boolean = false;
private var light:CCLight = null;
public function CoppercubeSprite()
{
addEventListener(Event.ENTER_FRAME, onGraphicsFrame);
var copperCubeData:ByteArray = new EmbeddedCopperCubeSWFDataFile() as ByteArray;
loader = new Loader();
addChild(loader);
loader.loadBytes(copperCubeData);
loader.contentLoaderInfo.addEventListener(Event.INIT, onCoppercubeLoaded);
}
private function onCoppercubeLoaded(e:Event):void
{
loadingFinished = true;
simpleAPI = (loader.content as DisplayObject)['simpleAPI'];
}
public function onGraphicsFrame(event:Event):void
{
if (loadingFinished)
{
if (simpleAPI && simpleAPI.isLoaded() && !applicationStarted)
{
applicationStarted = true;
startCCApplication();
}
if (applicationStarted)
{
enterFrame(event);
}
}
}
public function startCCApplication():void
{
this.light = new CCLight
(this.simpleAPI, simpleAPI.getSceneNodeByName("Light2"));
this.light.Color = 0xFFFF00;
TweenMax.to(this.light, 1, {hexColors:{Color:0x00FFFF}, yoyo:0});
}
public function enterFrame(event:Event):void
{
}
}
}
First the Coppercube SWF file is embedded. You can use the Embed
keyword to add resources into a SWF file, giving you one file to distribute, and also negating the need to load resources from external sources (along with its inherent unreliability).
[Embed(source="../resources/scripting.swf", mimeType="application/octet-stream")]
We set up a function to be called every frame. It is in this function that we can modify the Coppercube scene.
addEventListener(Event.ENTER_FRAME, onGraphicsFrame);
The embedded SWF file is then loaded, with the onCoppercubeLoaded
function set to be called when the loading is finished.
var copperCubeData:ByteArray = new EmbeddedCopperCubeSWFDataFile() as ByteArray;
loader = new Loader();
addChild(loader);
loader.loadBytes(copperCubeData);
loader.contentLoaderInfo.addEventListener(Event.INIT, onCoppercubeLoaded);
Once the embedded SWF file is loaded, we set loadingFinished
to true
to indicate that the Coppercube scene is ready to be modified, and get a reference to the SimpleAPI
interface.
private function onCoppercubeLoaded(e:Event):void
{
loadingFinished = true;
simpleAPI = (loader.content as DisplayObject)['simpleAPI'];
}
The onGraphicsFrame
function won’t do anything until loadingFinished
has been set to true
. Once we know that the Coppercube SWF file has been loaded and a reference to the SimpleAPI
interface has been obtained, we then check to see if the SimpleAPI
has loaded. Once it has, the startCCApplication
function is called, and the applicationStarted
flag is set to true
so we don’t call this function again.
if (simpleAPI && simpleAPI.isLoaded() && !applicationStarted)
{
applicationStarted = true;
startCCApplication();
}
Once the application has been started, we then call the enterFrame
function.
if (applicationStarted)
{
enterFrame(event);
}
It is in the startCCApplication
function that we perform any initialization required. In this case, we create a new instance of the CCLight
class, and use the TweenMax class to modify the colour of the light.
this.light = new CCLight(this.simpleAPI, simpleAPI.getSceneNodeByName("Light2"));
this.light.Color = 0xFFFF00;
TweenMax.to(this.light, 1, {hexColors:{Color:0x00FFFF}, yoyo:0});
Tweening is the process of changing the properties of an object smoothly over time, and TweenMax
is just one of many tweening libraries available for ActionScript. I like TweenMax
because it can tween colours, and the yoyo property means that properties can by cycled back and forth.
The enterFrame
function is left empty; the TweenMax
class will modify the colour of the light every frame for us.
public function enterFrame(event:Event):void
{
}
CCLight.as
package
{
import mx.messaging.management.ObjectInstance;
public class CCLight
{
protected var ccObject:Object = null;
protected var simpleAPI:Object = null;
protected var color:int = 0x000000;
public function get Color():int
{
return this.color;
}
public function set Color(color:int):void
{
this.color = color;
simpleAPI.setLightColor(ccObject, color);
}
public function CCLight(simpleAPI:Object, ccObject:Object)
{
this.simpleAPI = simpleAPI;
this.ccObject = ccObject;
}
}
}
CCLight
is a very simple class designed to expose the colour property of a Coppercube
light as a pair of get
/set
functions. This is because TweenMax
expects to be able to modify a property rather than supply a parameter to a function, which is how the SimpleAPI
works. So the CCLight
class simply keeps a reference to the SimpleAPI
interface and the light that it is to modify, and class the SimpleAPI setLightColor
function from within a standard set function. This makes modifying a Coppercube
object from TweenMax
simple.
SpriteUIComponent.as
package
{
import flash.display.Sprite;
import mx.core.UIComponent;
public class SpriteUIComponent extends UIComponent
{
public function SpriteUIComponent(sprite:Sprite)
{
super ();
explicitHeight = sprite.height;
explicitWidth = sprite.width;
addChild (sprite);
}
}
}
Because we are using Flex to create the application, we need a way to add a Sprite to the application defined in the MXML file. Sprites can not be added directly to a Flex Application object, so as a very simple workaround we use the SpriteUIComponent
class as an intermediate step. SpriteUIComponent
extends the UIComponent
class, which means it can be added to a Flex Application object, and then simply adds the supplied Sprite as a child of itself.
LightScripting.mxml
="1.0"="utf-8"
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
xmlns:ns1="*"
width="600"
height="400"
creationComplete="creationComplete()">
<mx:Script>
<![CDATA[
</mx:Script>
</mx:Application>
The MXML file is the entry point of the application. Once the application is ready, the creationComplete
function is called, at which point a new CoppercubeSprite
object is added to the Flex Application object as a child of a new SpriteUIComponent
object.
When you run the application, you will see that the light that is sitting above the model will slowly fade between yellow and cyan. Almost any aspect of the Coppercube scene can be modified using the same methods, and we also have available to us the full power of ActionScript (such as tweening).
Check out the live demo here, and download the source code here.
History
- 1st September, 2009 - Initial post