Send all instances of a container BEHIND everything else? - actionscript-3

Found this topic: AS3 setChildIndex to front I'm trying to accomplish the exact opposite.
"addChildAt" doesn't work for me when I'm setting the container behind everything else or something along the lines. And as for stars themselves, I can't send them back anymore than layer 0 for some odd reason (it'll give me error 2006, stating "The supplied index is out of bounds"). Here's the code:
starsSpawn function:
var starContainer:MovieClip = new MovieClip();
addChildAt(starContainer, 20);
starContainer code:
function starsSpawn()
{
for(var i:int= 0; i < 30; i++)
{
var newStar = new starCode();
var scaleXY = Math.random()*(2)+0.1;
newStar.width = scaleXY;
newStar.height = scaleXY;
var positionX:Number = Math.random()*(stage.stageWidth + (1* newStar.width));
var randomY:Number = Math.random()*(stage.stageHeight - newStar.height);
newStar.x = positionX;
newStar.y = randomY;
starContainer.addChild(newStar);
}
}
Essentially how it works is that a container is set up and the for loop creates 30 stars, each with the outlined code.

When you addChildAt(myChildMC, 0); it gets added at index 0 and everything else gets bumped up. Z order indexes in AS3 are contiguous, meaning every space from zero to the highest z order must be filled. If I remove whatever is on layer 4, layer 5 will slide down to fill, and so on
And I don't think you can add something to index 20 unless all the other indexes have children in them. That may be what is causing your particular error. To add something to the top level just do addChild(myChild).
edit
Since it sounds like you have the concept of how z-order works in reverse in your mind, you probably are wanting to have the stars "in front" of everything else i.e. Always on top i.e. Always visible. To do that just do addChild(starsContainer) after all the other containers are added or Sprites or MovieClips. If you add something to the stage at runtime, just add the stars container again (this won't create a second container, it literally just changes the z-order if there is already a container by that name... this is an often misunderstood point).

Related

Setting an movieclips image/background

I have a button and a small area which is a movieclip.
What i need is, on button press it inserts an image into the movieClip, it would have to be docked into the whole movieclip area essentially.
I have looked through multiple posts yet they have an overwhelming amount of information that I cannot figure out, this is so far what i have done :
B_Background1.addEventListener(MouseEvent.CLICK, setBackground1);
function setBackground1(event:MouseEvent):void{
var firstPic:MovieClip = new C_1BackgroundPIC();
addChildAt(firstPic, C_MainStage);
}
As I understand it, it adds an event to the button, then in the function it creates a new movieClip instance which has the Picture inside of it, and then adds it to the "MainStage" although using C_MainStage is invalid thus doesn't work, it does add a picture if i just use 0 as the position but it then adds it to the position 0, which i dont want...
It's a good start. When you use addChildAt, it expects a number as the second parameter. Presumably, C_MainStage is your MovieClip (which isn't a number). Presumably you want the current display index of C_MainStage (not C_MainStage itself). This can be had by using getChildIndex
Look at the following:
function setBackground1(event:MouseEvent):void{
var firstPic:MovieClip = new C_1BackgroundPIC();
addChildAt(firstPic, getChildIndex(C_MainStage));
//now, you may need to also resize your picture so it fits in the bounds of C_MainStage, if so, you can do something like this:
if(firstPic.width >= firstPic.height){
//if firstPic is wider than it is tall
//set it's width to the same as C_MainStage
firstPic.width = C_MainStage.width;
//now, to keep the aspect ratio (in case they don't match), make the scaleY the same value as the new scaleX
firstPic.scaleY = firstPic.scaleX
}else{
//do the opposite as above since the height is larger than the width
firstPic.height = C_MainStage.height;
firstPic.scaleX = firstPic.scaleY;
}
//now, you may want to center firstPic in the C_MainStage bounds
firstPic.x = C_MainStage.x + ((C_MainStage.width - firstPic.width) * .5);
firstPic.y = C_MainStage.y + ((C_MainStage.height - firstPic.height) * .5)
}

How can I randomize a picture under a cover in actionscript 3.0?

I'm making a flash game for practice and I have my stage set up so there are 9 boxes. When the game is started, one of the boxes is randomized as the one with the start underneath, if you pick the box with the star underneath, you win.
The randomizing code is
var star = 1 + Math.Round(Math.Random()*8.0)//generate a number between 1 and 9
What i dont know is how to attach this code so that it assigns the star to one of my 9 boxes made as buttons. How can I hide the star underneath the box as a cover.
Thanks for your time
I'm picturing one of those games where you but a ball under one of three cups and swap the cups, then guess which one has the ball.
The simplest way to hide one object under another is to just add it to the stage before the object covering it. So add your star to the stage, then add all your boxes. BUT since you don't have to have an unseen object actually be on the stage, I recommend not adding the star to the stage until it is revealed, and remove it when it gets hidden again.
You can create layers to make sure objects are always above/below what they need to be above/below. Create sprite objects, and call them layers. Add them in order from bottom to top. Add other sprites to these layer sprites to control their display order.
var layer1:Sprite = new Sprite(); // Bottom / background
var layer2:Sprite = new Sprite(); // Top / foreground
stage.addChild(layer1);
stage.addChild(layer2);
layer2.addChild(someObject1);
layer1.addChild(someObject2); // someObject2 will be below someObject1
That deals with covering the star with the boxes.
You can put your boxes in an array. You'll want a number between 0 and 8, then just use that as the index in the array to get the box you want.
var whichBox:int = (int)(Math.random() * 9);
var boxesArray:Array = new Array();
for (var i:int = 0; i < 9; i++) {
boxesArray.push(new Box()); // Or whatever your boxes are
}
var boxWithStar:Box = boxesArray[whichBox];
You can then move the star to the same location as its box...
star.x = boxWithStar.x;
star.y = boxWithStar.y;
This is a pretty handy function you can use:
function randRange(start:Number, end:Number) : Number
{
return Math.floor(start +(Math.random() * (end - start)));
}
example (any number between 0 - 9) :
var random:int = randRange(0,9);
remember to make it an int or you may end up with a float.

Setting multiple depth layers in AS3

I get how to set depth in as3 - but with as2 i could begin multiple 'depth points' using numbers - where in as3 all i can seem to do is set this object to a higher/lower depth than that object. The problem is (when dealing with a stack of isometric boxes, which can be placed by the user on a grid in any order) i don't want to deal with the added complexity of having every element know where every other element is, then adjust appropriately.
What I'm trying to do is set up 6 total depth numbers/positions, one for each column in a 6 x 6 grid. So anything in column 1 will begin it's depth placement at say 500, anything in column 2 will begin its depth at 1000, column 3 would be 1500 and so on.
That way, the second i place an object on a particular column, it would tuck itself under, or place itself above all surrounding items in other columns, this to me is much much easier than somehow figuring out where 15 different sized boxes are, how they relate to one another, then figure out what depth order they need to go in.
Any ideas? as3 seems to have removed the ability to set a depth to a specific number :p
The approach can be simplified. You basically want to create 3 'container' clips and add them in order. The last one added is the top-most.
Bonus: if you want to rearrange, you can call addChild() on any clip (even already added ones) and that one will go to the top.
//// IMPORTANT STUFF ////
import flash.display.Sprite;
var top:Sprite = new Sprite;
var mid:Sprite = new Sprite;
var bot:Sprite = new Sprite;
addChild(bot);
addChild(mid);
addChild(top);
//// END IMPORTANT STUFF ////
// Move Stuff so we can visualize how this works.
// Then add some boxes so we can see what's going on.
mid.x = 20;
mid.y = 20;
bot.x = 40;
bot.y = 40;
// Add Top box
var t:Sprite = new Sprite;
t.graphics.beginFill(0xFF0000);
t.graphics.drawRect(0,0,100,100);
top.addChild(t);
// Add Middle box
var m:Sprite = new Sprite;
m.graphics.beginFill(0x00FF00);
m.graphics.drawRect(0,0,100,100);
mid.addChild(m);
// Add Bottom box
var b:Sprite = new Sprite;
b.graphics.beginFill(0x0000FF);
b.graphics.drawRect(0,0,100,100);
bot.addChild(b);

AS3: How can I construct this Linkage problem?

I want to do something like this with AS3, but I'm new to AS3 and I'm not sure how to go about the coding.
What I need to do is I have 1 x blank MC called all_mc, inside that I need to have 200 x empty_mc all lined up one after another on the x axis.
Each empty_mc is 100px wide and load from a Linkage in the library called panelClass (which is a MovieClip).
The empty_mc itself is called emptyClass in the library.
I need the all_mc to display on the stage from start. It should look like this image. The I need 200 of these red squares.
I know instead of adding all 200 MCs manually, I should be making a loop? But I can not get my head around it for the life of me. Can someone please kindly help me out?
Just make a loop and dynamically create your MovieClips:
var mcWidth:Number = 100; // Using hardcoded value because MovieClip.width is not always reliable (if the MovieClip contains shapes with strokes, etc.)
for (var i:int = 0; i < 200; i++) {
var mc:panelClass = new panelClass();
all_mc.addChild(mc);
mc.name = "empty_mc" + i; // set a name so that it can be accessed later on
mc.x = mcWidth * i;
}

Actionscript 3.0 problem - Why is it giving an error even when I've re-checked the code?

I'm using Adobe Flash CS4 professional for this Actionscript 3.0 project
(http://tutorials.flashmymind.com/2009/02/rotating-menu-via-actionscript-3/)
I even tried following the suggestions in the comments as well but this error always shows up:
TypeError: Error #1010: A term is undefined and has no properties.
at rotating_menu_fla::MainTimeline/frame1()
(for complete details, kindly click the link - http://i429.photobucket.com/albums/qq19/tsujzpie/screenshot_03.jpg)
I've been following every step of the tutorial but I'm stumped over the coding...
Here's the code by the way...
//Save the center coordinates of the stage
var centerX:Number=stage.stageWidth/2;
var centerY:Number=stage.stageHeight/2;
//The number of items we will have (feel free to change!)
var NUMBER_OF_ITEMS:uint=5;
//Radius of the menu circle (horizontal and vertical)
var radiusX:Number=200;
var radiusY:Number=100;
//Angle difference between the items (in radians)
var angleDifference:Number = Math.PI * (360 / NUMBER_OF_ITEMS) / 180;
//How fast a single circle moves (we calculate the speed
//according to the mouse position later on...)
var angleSpeed:Number=0;
//Scaling speed of a single circle
var scaleSpeed:Number=0.0002;
//This vector holds all the items
//(this could also be an array...)
var itemVector:Array = new Array ('1', '2', '3', '4','5');
//This loop creates the items and positions them
//on the stage
for (var i:uint = 0; i < NUMBER_OF_ITEMS; i++) {
//Create a new menu item
var item:Item = new Item();
//Get the angle for the item (we space the items evenly)
var startingAngle:Number=angleDifference*i;
//Set the x and y coordinates
item.x=centerX+radiusX*Math.cos(startingAngle);
item.y=centerY+radiusY*Math.sin(startingAngle);
//Save the starting angle of the item.
//(We have declared the Item class to be dynamic. Therefore,
//we can create new properties dynamically.)
item.angle=startingAngle;
//Add an item number to the item's text field
item.itemText.text=i.toString();
//Allow no mouse children
item.mouseChildren=false;
//Add the item to the vector
itemVector.push(item);
//Add the item to the stage
addChild(item);
}
//We use ENTER_FRAME to animate the items
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
//This function is called in each frame
function enterFrameHandler(e:Event):void {
//Calculate the angle speed according to mouse position
angleSpeed = -(mouseX - centerX) / 5000;
//Loop through the vector
for (var i:uint = 0; i < NUMBER_OF_ITEMS; i++) {
//Save the item to a local variable
var item:Item=itemVector[i];
//Update the angle
item.angle+=angleSpeed;
//Set the new coordinates
item.x=centerX+radiusX*Math.cos(item.angle);
item.y=centerY+radiusY*Math.sin(item.angle);
//Calculate the vertical distance from centerY to the item
var dy:Number=centerY-item.y;
//Scale the item according to vertical distance
item.scaleY = (dy / radiusY)+2;
//Set the x scale to be the same as y scale
item.scaleX=item.scaleY;
//Adjust the alpha according to y scale
item.alpha=item.scaleY+1.1;
}
}
I find it odd - it may be that the code is right but I don't know if these steps has messed up the project...
3 - Convert the circle into a movie clip...
4 - In the “Item” movie clip, create a dynamic text field in the center of the circle (in a new layer).
5 - Set the text to align center. Type some number in the text field. Give the text field an instance name of “itemText”. Embed numerals...
6 - Remove the Item movie clip from the stage. We will create all the items dynamically via ActionScript 3.
I could've given more screenshots but since I'm a new user, I'm only allowed a max of two - and contrary to this tag, I'm not doing an Android app.
(I'll give you added info once any of you would reply to this question...)
I have to admit that the steps 3 to 6 is confusing and didn't made sense to me - especially with step six, when you have to remove the movie clip from the stage. For me, if I were to do that, what would the script work on then?
Any idea what I did wrong?
EDIT:
Thanks, I realized my mistake - thanks for the tip :-)
But now, I tried to modify the code of this tutorial a bit to have words appear inside the circles (like "Home", "About", etc....) like what I've typed in the line in the screenschot - http://i429.photobucket.com/albums/qq19/tsujzpie/modifiedlineincode_00.jpg
But inspite of what I believe are the appropriate changes I've done, an error showed up still - (kindly see here - http://i429.photobucket.com/albums/qq19/tsujzpie/newerrorincode_00.jpg)
Why is that happening? Before I forget, in what section of the code must I insert a line that will make a clicked button display the info corresponding to it? (that is, if I click on the "Contact" or any of the buttons a window will appear beneath the menu on the stage...)
That errors means ActionScript has no clue what an Item is. Make sure you've ticked Export for ActionScript on your Item MovieClip in library and that the class is named Item also.
Update:
The tutorial you're following mentions itemVector is a Vector of Item instances, not an array of Strings like you're code suggests. This why you're getting the error displayed in your screenshot. It means ActionScript can not convert an Item to a String.
An easy fix is to create another array for the menu item labels:
var itemVector:Array = [];// = new Array ('1', '2', '3', '4','5');
var itemLabels:Array = ["Home","About","Contact","Gallery"];
NUMBER_OF_ITEMS = itemLabels.length;
and in the for loop swap this item.itemText.text=i.toString(); for this tem.itemText.text=itemLabels[i];
It seems that you don't fully grasp the difference between variable types. I would suggest getting familiar with the basics of as3 before moving forward. Also paying more attention to your code and fully understanding code you use written by others will keep you out of trouble. However you will still encounter errors. You might find explanations for those errors on the Flash Error Database.
Regarding the Carosel tutorial, also have a look at this video. It might help explain things better.
The compiler can not find the Item class.
Go into your library and open up the properties for the "Item" MovieClip.
Verify that is is set for export to actionscript.