How to adjust the z-axis, if there is, for graphics in AS3 - actionscript-3

I'm a beginner in FlashDevelop. I drew a simple circle. I also embedded a .jpg. Is there any way to place the circle I drew before the jpeg?
This is placed inside the init():
[Embed (source = "images/Untitled.png")]
var bg:Class;
var bmp1:Bitmap = new bg;
addChild(bmp1);
var k:int, l:int;
for (l = 0; l < 10; l++)
{
for (k = 0; k < 8; k++)
{
graphics.beginFill(0xff0000, 1);
graphics.drawCircle(k*50, l*50, 10);
graphics.endFill();
}
}

[Embed (source = "images/Untitled.png")]
var bg:Class;
var bmp1:Bitmap = new bg;
addChild(bmp1); // Add the bitmap first
var sprite1:Sprite = new Sprite();
this.addChild(sprite1); // Add the sprite afterwards; it appears on top of the bitmap
var k:int, l:int;
for (l = 0; l < 10; l++)
{
for (k = 0; k < 8; k++)
{
sprite1.graphics.beginFill(0xff0000, 1);
sprite1.graphics.drawCircle(k*50, l*50, 10);
sprite1.graphics.endFill();
}
}

What you're looking at here is a topic called The Display List. Put very simply and very shortly, objects that are added to the stage (or other containers) will be displayed in the order that they are added, with the latest object going on top of the previous one.
Pranav Negandhi's answer is correct in showing how to add your circle object infront/on-top/before your jpeg, but you should consider reading all or some of the following articles in order to fully understand the display list and what tools you have available to make objects appear just the way you want them on the screen.
AS3 101: The Display List
Adobe's Display list programming in ActionScript 3
Republic Of Code's AS3: The Display List
You could also have a look through the reference for displayobjectcontainer, which contains most of the methods you'll be working with, such as addChild() or addChildAt()
Display Object Container Reference
As always, feel free to ask questions here on stackoverflow if you need help!

Related

How to Access and Get Amplitude of MP3 Sound on the Timeline?

I'm wanting to get the amplitude of a mp3 that's playing in my SWF. The problem is, it's embedded directly on the timeline.
Is there any way I can get to the sound (via ActionScript) that's playing when it's on the timeline?
Update: For more clarity, when the sound is added to the stage (literally dragged from the Library to the stage) it appears to become a property of the frame?
Any imported item is accessible in the Library (ctrl+L or find under Window in top menu bar)..
In the Library just right-click the current name of your audio item (will be Type: Sound)
and choose Properties. In there you should see Linkage section so tick Export For ActionScript.
In the now available Class box you can now put your own preferred instance name (no_spaces) and leave Base Class as flash.media.Sound (should be that way)
//assuming you have.. my_Audio ..as Linkage Class name
var mySound:Sound = new my_Audio();
var myChannel:SoundChannel = new SoundChannel();
myChannel = mySound.play();
addEventListener(Event.ENTER_FRAME, show_Amplitude);
function show_Amplitude(evt:Event)
{
// where 200 is your own number for the maximum width or height of amplitude bars
mc_ampLeft.width = myChannel.leftPeak * 200;
mc_ampRight.width = myChannel.rightPeak * 200;
}
Alternative solution: Get amplitude via computeSpectrum
For whatever situations where the above solution is not applicable, then the alternative would be to just use ComputeSpectrum (which works globally on all audio since its tied to the SoundMixer not just specific sound Object). This is an example as starting point (tweak this or research a better formula)
var n_RMS :Number = 0;
var n_FFT :Number = 0;
var max_AMP :Number = 200; // max width or height of bar at full volume
var FFT_bytes:ByteArray = new ByteArray;
addEventListener(Event.ENTER_FRAME, compute_Amplitude);
function compute_Amplitude(evt:Event)
{
SoundMixer.computeSpectrum( FFT_bytes, false, 0 );
for (var i:int = 0; i < 256; i++) //GETS LEFT CHANNEL FFT
{
n_FFT = FFT_bytes.readFloat();
n_RMS = 0.8 * Math.sqrt( Math.abs(n_FFT) ) / 0.434294481904;
}
mc_ampLeft.width = (n_RMS /2) * max_AMP; //update LEFT bar
for (var j:int = 0; j < 256; j++) //GETS RIGHT CHANNEL FFT
{
n_FFT = FFT_bytes.readFloat();
n_RMS = 0.8 * Math.sqrt( Math.abs(n_FFT) ) / 0.434294481904;
}
mc_ampRight.width = (n_RMS /2) * max_AMP; //update RIGHT bar
}

How would I code a statement that will choose 5 random frames out of 12 in Flash ActionScript 3?

I'm sure this question has been asked a million times in a million ways, but I would appreciate the help anyway. I am working on a Flash Mastermind clone and have a movie clip with 12 colored "pegs" and a "hole" image. How would I code a statement that will pick five random frames and not just the first five frames? I have the barest idea, but I'm not entirely sure if it's right:
var totalColors:Number = 12;
var maxColors:Number = 5;
var chosenColors:Array:
for(var i:Number = 1; i<totalColors; i++)
{
chosenColors[i] = Math.floor(Math.random()*totalColors)+1
}
Thanks a lot in advance for your help!
Please note that the movieclip has been rearranged since I wrote this; I moved the first frame - the "hole" to another layer.
EDIT: Pan has helped a lot since I first asked this question. To test it I decided to expand on my Bejeweled clone code. I added five more shapes to the original 7. At first I thought the line "newPiece.type = Math.ceil(Math.random() * chosenColors.length);" inside the loop, so I commented the quoted line, which was outside of the j loop and part of the original code, and replaced it with this:
newPiece.type = chosenColors[j];
I am very sorry if this seems elementary to some; I am not the strongest programmer, especially when making games. I am far better at ASP.NET and UI design, but game development has always appealed to me for some weird, possibly insane reason. Anyway, here is part of the method for creating a new jewel. The two for loops are pan's code for choosing seven random frames out of twelve. Unfortunately, the movie still picks the first seven frames from the movie clip.
//i goes through all of the possible colors and adds them to the temp array
for (var i:uint = 1; i <= newPiece.totalFrames; i++)
{
temp.push(i);
}
//j chooses seven colors out of the array of all possibilities
for (var j:int = 0; j < numPieces; j++)
{
//index is the frame that has been chosen randomly
var index:int = int(Math.random() * temp.length);
chosenColors.push(j);
chosenColors[j] = temp[index];
//remove the index
temp.splice(index, 0);
}
newPiece.type = Math.ceil(Math.random() * chosenColors.length);
Again, if I've confused anyone with my bad code to English translation, here is an image of my running game and its Jewel movieclip so you will hopefully see what I mean.
var totalColors:Number = 12;
var maxColors:Number = 5;
var chosenColors:Array = [];
var temp:Array = [];
for(var i:Number = 1; i <= totalColors; i++)
{
temp.push(i);
}
for (var j:int = 0; j < maxColors; j++)
{
var index:int = int(Math.random()*temp.length);
chosenColors[j] = temp[index];
//remove the index
temp.splice(index, 1);
}

Order of instances in 3D Flash

I'm making cube of 9 cubes in Flash As3. However i cant rotate it properly due to order of indexes whole adding then to stage.
First im creating cube of 6 squares, then wall of 9 cubes, and at the end cube of 3 walls.
It is all fine, however when i rotate it to the left, order of cubes is inverted and it ruins whole composition. I know i coul dinamicly change index based on rotation but it would be a loooooooot of work.
Any ideas how could i do it better way?
Here is actual model:
http://test.mrowa.topdivision.pl/kostka/3DTest.html
If you are using the Flash's display list you would have to sort the sprites based on their z.
Here is some code that would sort the children of a DisplayObjectContainer based on their z position, call this whenever some object changes its position.
public function sortChildren(container:DisplayObjectContainer):void
{
var objects:Vector.<DisplayObject> = new Vector.<DisplayObject>;
for (var i:int = 0; i < container.numChildren; i++)
{
objects.push(container.getChildAt(i));
}
objects.sort(sortCompare);
var index:int = 0;
for (var j:int = 0; j < objects.length; j++)
{
index = container.getChildIndex(objects[j]);
if (index != j)
container.setChildIndex(objects[j], j);
}
}
private function sortCompare(a:DisplayObject, b:DisplayObject):int
{
return (a.z - b.z);
}
You can move the objects member to be a class member and add/remove items to it whenever you add/remove items to/from the stage so that you don't have to fill the whole array every time this function is called.

AS3 reference movieclip by .name property

Yay, another simple noobie as3 question.
How can I reference a movieclip by its ".name" ?
I tried searching for a solution, but I couldn't find anything. Basically I have a set of movieclips added to the stage using a loop, so the way I found to diferentiate them was by giving them a .name of "something" + the Loop's "i". So now they are named something like "something1", "something2", "something3", and so on.
Now, I need to send some to a specific frame. Usually I would do something like:
something1.gotoAndStop(2);
But "something1" isnt the instance name, just the ".name". I cant find a way to reference it.
you want to use getChildByName("name") more info
import flash.display.MovieClip;
// create boxes
for(var i:int = 0 ; i < 4; i++){
var box:MovieClip = new myBox(); // myBox is a symbol in the library (export for actionscript is checked and class name is myBox
box.name = "box_" + i;
box.x = i * 100;
this.addChild(box);
}
// call one of the boxes
var targetBox:MovieClip = this.getChildByName("box_2") as MovieClip;
targetBox.gotoAndStop(2);
Accessing things by name is very prone to errors. It's not a good habit to get into if you're a newbie. I think a safer way to do this would be to store references to the things you're creating in the loop, for example in an array, and reference them by their indexes.
Example:
var boxes:Array = [];
const NUM_BOXES:int = 4;
const SPACING:int = 100;
// create boxes
for(var i:int = 0 ; i < NUM_BOXES:; i++){
var box:MovieClip = new MovieClip();
// You can still do this, but only as a label, don't rely on it for finding the box later!
box.name = "box_" + i;
box.x = i * SPACING;
addChild(box);
// store the box for lookup later.
boxes.push(box); // or boxes[i] = box;
}
// talk to the third box
const RESET_FRAME:int = 2;
var targetBox:MovieClip = boxes[2] as MovieClip;
targetBox.gotoAndStop(RESET_FRAME);
Note, I've also replaced many of the loose numbers with constants and vars which will also help your compiler notice errors.
You can use the parent to get the child by name. If the parent is the stage:
var something1:MovieClip = stage.getChildByName("something1");
something1.gotoAndStop(2);

actionscript for loop iterator to change movie clip name

I have a bunch of movie clips I created in flash CS5 and are all placed within the stage. I control each one of them dynamically with code using ActionScript 3. However I want to control all of them at the same time using a for loop and just change the width of each element but its not working.
Here is my code:
for(var i:Number = 0; i < 100; i++)
{
leftBar+i.width = ( Math.round(channel.rightPeak * 1.1) ) + 60;
}
So I have 100 bars each called leftBar and their number. So the firstBar is leftBar1, then leftBar2 and so on. I cant get it to work however. I have tried "leftBar"+i and also leftBari but none of them seem to work.
The correct way to select each of those MovieClips in your loop is:
this["leftBar" + i]
New code:
// Note: We've changed the initial value of i to 1 because you mentioned that
// your first MovieClip was called 'leftBar1' rather than 'leftBar0'.
for(var i:int = 1; i <= 100; i++)
{
var current:MovieClip = this["leftBar" + i];
current.width = Math.round(channel.rightPeak * 1.1) + 60;
}
Basically you want to select the property leftBar0, leftBar1, etc from this using square brackets. It is the same as doing this:
this.leftBar0
And can also be used for any properties or methods of any other class:
// Example of Square Bracket notation.
var sprite:Sprite = new Sprite();
sprite["x"] = 10;
trace(sprite.x);
this["addChild"](sprite);