How is this class connecting to the sound? - actionscript-3

im trying to use (well succeeding) to use this sound class
http://www.mcfunkypants.com/2011/as3-pitch-shift-mp3/
the example code looks like this. . .
public class Pitch_Shift_Example extends Sprite
{
[Embed(source='Pitch_Shift_Example.mp3')]
private var engine_mp3 : Class;
public var engine_loop:Pitch_Shift_MP3;
public function Pitch_Shift_Example()
{
engine_loop = new Pitch_Shift_MP3(engine_mp3);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
var someText:TextField = new TextField();
someText.x = 200;
someText.y = 0;
someText.textColor = 0xFFFFFF;
someText.selectable = false;
someText.autoSize = TextFieldAutoSize.LEFT;
someText.text = "Pitch Shift MP3 Demo by Breakdance McFunkypants\nMove your mouse to change the sample rate. Enjoy!";
addChild(someText);
}
private function onMouseMove(event:MouseEvent):void
{
engine_loop.rate = (mouseX / stage.width) * 2;
}
}
Now what is confusing me is how the engine_mp3 class uses the sound.
line one embeds the sound.
line two creates an empty class called engine_mp3.
line 3 creates a new pitch shift class which in line 7 we pass the (empty) engine_mp3 class.
Basically how is engine_mp3 getting the mp3 data??
Any help is appreciated.
Andy

It works like something like this:
You embed the mp3 file with these two lines:
Embed(source='Pitch_Shift_Example.mp3')]
private var engine_mp3 : Class;
Those two lines work together. The first line is embed metadata that describes the line below it. What it's doing is embedding the mp3 file and making it accessible as a class. You therefore have a reference to this embedded sound class with the variable name engine_mp3.
Later on in your code, you instantiate a new instance of the Pitch_Shift_MP3 class, and you pass in the reference to your embedded sound class engine_mp3:
engine_loop = new Pitch_Shift_MP3(engine_mp3);
The constructor for the pitch shift class is expecting a class (that represents a sound) as its single argument. What it must be doing in its own code is instantiating the class that engine_mp3 represents by doing this:
var instantiatedSound:Sound = new engine_mp3() as Sound;
Hope that makes sense!

Related

Best way to read a property from a MovieClip?

I got a .fla file, where inside I have some movieclip instances placed in the scene. I need to iterate through them and gather some data, like position, name, and custom properties.
These custom properties, I don't know how to pass them, I know one way that works so far is to use the accessibility properties panel (Flash Pro CC), and then in the code I can just read them. However there should be a better way I assume.
If I have understood correctly your question and what you have said in your comments about the answer of #Aaron, you have an swf file, which you load dynamically, and you want to get/set some of its MovieClips properties, if it's the case, take this example :
MyMC.as :
public class MyMC extends MovieClip
{
private var timer:Timer;
private var rotation_speed:int = 1;
public function MyMC() {
}
public function set_Rotation_Speed(_rotation_speed:int): void {
this.rotation_speed = _rotation_speed;
}
public function get_Rotation_Speed(): int {
return this.rotation_speed;
}
public function start_Rotation(): void {
this.timer = new Timer(500, 10);
this.timer.addEventListener(TimerEvent.TIMER, on_Timer);
this.timer.start();
}
private function on_Timer(e:TimerEvent): void {
this.rotation += this.rotation_speed;
}
}
Then, in my swf.swf I have an instance of that MovieClip.
I loaded the swf.swf using this code :
var loader:Loader = new Loader()
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_SWFLoad);
loader.load(new URLRequest('swf.swf'));
And to set/get some of my MovieClip properties, I did :
function on_SWFLoad(e:Event): void
{
var swf:DisplayObjectContainer = DisplayObjectContainer(loader.content);
var num_children:int = swf.numChildren;
for(var i:int = 0; i < num_children; i++)
{
var child:MovieClip = MovieClip(swf.getChildAt(i));
// get the name
trace('name : ' + child.name);
// set the position
child.x = child.y = 100;
// get the class name, in my case it's MyMC
var class_name:String = getQualifiedClassName(child);
// get all the details of the child
trace(describeType(child));
child.set_Rotation_Speed(45);
child.start_Rotation();
trace(child.get_Rotation_Speed()); // gives : 45
}
addChild(loader);
}
You can use the describeType() function To get all the properties of your instance.
Hope that can help.
First of all, you can set properties on timeline instances from code. There's nothing special about this. For example:
Place an instance of a library symbol on a keyframe
Give it an instance name in the Properties panel, for example "myInstance"
On the same keyframe put some code that refers to it, such as myInstance.color = "red"
You can also create and assign custom properties by making the symbol a component:
Right-click on the symbol in the library and choose "Component Definition"
Add custom properties in the Parameters table. It's now a component symbol.
On the timeline, place an instance of the symbol and use the Properties panel to set its parameters.
You can do a lot more with components if you want, such as live preview and compiled components. More info can be found here here: http://www.adobe.com/devnet/flash/learning_guide/components/part03.html

Referring to a variable in the target file from a class AS3

I've researched this all day and I'm stuck! I want to know how to use a variable from a target path to move something. Here is the code:
// Target file
var speed:int = Number(1);
var container:MovieClip = new MovieClip;
var objects:Objects = new Objects();
container.addChild(objects);
and
// Class for Objects
package {
import flash.display.MovieClip;
public class Objects extends MovieClip {
public function Objects() {
this.x += speed;
trace(this.x);
}
}
}
When I run it, I get an error like this:
Objects.as, Line 6 1120: Access of undefined property speed.
Thanks!
The most simple way to do it is to pass the speed variable to that class. See, classes are like stand alone objects in the space, and they (mostly) don't know about each other, or at least they don't know about the variables that you define in them.
So if you create a class inside another one (new Objects()), the most easy way is this:
var objects:Objects = new Objects(speed);
Then, inside Objects class, you will have:
public class Objects extends MovieClip {
var _speed:Number;
public function Objects(speed:Number) {
_speed = speed; // save it to a local member variable
this.x += _speed;
// start working with the local one,
// which will be accessible in the whole class
}
It's like passing some defined values, so that class can use them. And the class saves them inside itself so it can be used through the whole file (scope).

embedding image inside as3 using Flash

I'm using Flash Pro, CS6 on the Mac.
I've got this class
package classes
{
public class AssetEmbeds_1x
{
//kid
[Embed(source = '../graphics/Player_Graphics.swf')]
public static const playerG:Class;
}
}
Which is a swf which contains an exported (on 1st frame) movieclip called kidCharacter. I'm trying to access that kidCharacter movieclip from another class, and I'm not able to do that.
I've tried this...
var textureClass:Class = AssetEmbeds_1x;
var newClass = textureClass['playerG'];
myGraphic = newClass['kidCharacter'];
But it's not working, myGraphic (which is a movieclip) is always null. I'm not sure if it's even embedding anything.
Try this:
var player:MovieClip = new AssetsEmbeds_1x.playerG();
var kid:MovieClip = player.root.kidCharacter;

Embed bitmap in ActionScript3

How can I embed a bitmap in Actionscript 3 and get the BitmapData?
public class MyGame extends Sprite {
[EMBED(source="Assets/helicopter1.png")] private static var BMClass:Class;
public function MyGame() {
var BM:Bitmap = new BMClass();
var BMData:BitmapData = new BitmapData(BM.width, BM.height);
BMData.draw(BM)
}
}
I've tried everything. If I ever try to instantiate the embedded class (new BMClass();) I get this error:
TypeError: Error #1007: Instantiation attempted on a non-constructor..
If I use
[EMBED(source="Assets/helicopter1.png")] private static var BMClass:BitmapData;
or something similar the BitmapData is null.
Edit:
So I figured out that the embedded data is null, but I can't figure out why. What did I do wrong in the embedding?
Looks like you are embedding correctly if you don't get an error transcoding. You should be able to get the bitmapData directly from the bitmap:
[Embed(source="picture.jpg")]
private var Picture:Class;
// create a bitmap of the embedded
var pic:Bitmap = new Picture();
// add to display list
addChild(pic);
// if you need to get the bitmapData for something else
var bitmapData:BitmapData = pic.bitmapData;
You don't need to instantiate as BitmapData and draw - you can simply:
[Embed(source="Assets/helicopter1.png")]
private var AssetClass:Class;
var bitmap:Bitmap = new AssetClass();
In some editors (at least my version of Intellij) the Embed tag is case sensitive. I got the exact same error you have when using [EMBED] but it worked great when I switched to [Embed]

how do I access the main class's stage? + Can I pass functions as arguments like this?

There are two files in my actionscript project named "TestAPP", TestAPP.as and Draggable.as
TestAPP.as:
package {
import flash.display.Sprite;
import flash.display.Stage;
public class TestAPP extends Sprite
{
var _mainStage:Stage;
public function TestAPP()//This is where we test the UI components.
{
var sp:Sprite = new Sprite();
_mainStage = stage;
_mainStage.addChild(sp);
sp.graphics.beginFill(0x00FF00);
sp.graphics.drawCircle(0,0,10);
sp.graphics.endFill();
sp.x = 50;
sp.y = 50;
var draggable1:Draggable = new draggable(sp,_mainStage,limitingfunc);
}
public function limitingfunc(x:Number,y:Number):int{
return 0;
}
}
}
And for the draggable.as:
package
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.MouseEvent;
public class Draggable
{
private var _limitingFunc:Function;
private var _which:Sprite;
private var _MouseSavedX:Number;
private var _MouseSavedY:Number;
private var _stage:Stage;
public function Draggable(which:Sprite,stage:Stage,limitingfunc:Function)
{
_limitingFunc = limitingfunc;
_which = which;
_stage = stage;
_which.addEventListener(MouseEvent.MOUSE_DOWN,begin_drag);
}
//limiting func: returns 0 when the object is free to move that place.
//returns -1 when the user wants to block X coordinate changes (but maintain Y free)
//returns -2 when the user wants to block Y ...
//returns -3 or less when the user wants to block both X and Y from changing.
//returns
private function Return_0(x:Number = 0,y:Number = 0):int{
return 0;
}
private function begin_drag(ev:MouseEvent):void{
var xTo:Number = _stage.mouseX - _MouseSavedX + _which.x;
var yTo:Number = _stage.mouseY - _MouseSavedY + _which.y;
var limitingFuncReturnValue:int = _limitingFunc(xTo,yTo);
if(limitingFuncReturnValue == 0){//free to move.
_which.x = xTo;
_which.y = yTo;
}
else if(limitingFuncReturnValue == -1){//free to move Y
_which.y = yTo;
}
else if(limitingFuncReturnValue == -2){
_which.y = yTo;
}
//else:do nothing.
}
}
}
In "my actionscript theory", I'm supposed to see a circle that follows the mouse when I click it. (The draggable is not fully implemented) But the circle doesn't even budge :(
...I've been trying to figure out how to access the main class's stage property. I've googled for it, but still no progress.
Please help this helpless newb!!! I'll really appreciate your help:)
Thank you!
You're implementing your 2nd class as "draggable", when you named it (and it has to be named) "Draggable" with an upper case. Change it and see if that works. You seem to be passing in the parent classes stage correctly though.
If TestAPP is your document class. You can access to the stage thru the stage property (like your are doing in your example).
If TestAPP is not the document class, you should listen first to the ADDED_TO_STAGE event and then access to the stage property.
There is no need to add _mainStage property because you already have the stage property.
In order to move objects around, you need to use the ENTER_FRAME event.
You can access the main class' stage property the same way you do it for any DisplayObject on the stage: Use this.stage.
So just this should be enough:
var sp:Sprite = new Sprite();
stage.addChild(sp);
You could then pass the sprite and the main class' stage as a parameter, the way you did - but I would recommend creating a subclass Draggable extends Sprite and instantiate the whole thing using new Draggable() instead.
The new object will automatically have its own reference to stage as soon as it is added to the display list, and limitingFunc could be a member of Draggable, as well.
Also, you can use the startDrag() and stopDrag() methods, no need to implement your own: You can specify a Rectangle as a parameter to startDrag() to limit the permitted movement.
if you need it so much you may:
private static var _instance: TestAPP;
//...
public function TestAPP(){
_instance = this;
//...
}
public static function get instance():TestAPP{
return _instance;
}
public static function set instance(newVal: TestAPP):void{
_instance = newVal;
}
and you'll be able to reference its stage from any class where your TestAPP will be imported just with TestAPP.instance.stage.
but _instance is a property of the class TestAPP itself, not its instances