if i insert multiple instances of movie clip with addChild method and "for" loop, how can i determine exact x, y position of instances in the scene? Either specific x y for each instance or placing the instances next to each other with specified space between them. Let's say 40px width squares with 20px space between them.
many thanks for any advices
This example show the squares in a row with 20px space between them:
var xSquare:Number = 10;
var ySquare:Number = 10;
var space:Number = 20;
for (var i:int = 0; i < 5; i++) {
var testSquare:Square = new Square();
addChild(testSquare);
testSquare.x = xSquare + testSquare.width * i + space * i ;
testSquare.y = ySquare;
}
Hope this is what you mean
While inserting your objects to stage, give all of them a name (obj0, obj1, obj2, etc). Next, you can simply use getChildByName('objX'). Is this what you need?
Related
I've done this a million time, but here it didn't work.
I have a game_mc inside a animate.fla. inside this clip I generate a view targetareas to place stones on it. ok, the TargetArea is a simple Movieclip inside my lib.
I can see everything, I can click on the area an get the propper name, I can get the names of the clips inside game_mc.
but I can't access it by using game_mc[clipname]
for (var i:int = 1; i<= 20; i++){
var targetArea:TargetArea = new TargetArea();
targetArea.txt.text = String(i);
var modu = ((i-1) %5);
targetArea.x = 100 + modu * 340;
var abs = int((i-1) / 5);
targetArea.name = "targetarea_" + String(i)+ "_mc";
targetArea.mouseChildren = false;
targetArea.y = 100 + (abs * 200) ;
game_mc.addChild(targetArea);
}
for(var x:int=0;x < game_mc.numChildren;x++) {
trace (game_mc.getChildAt(x).name);
}
for (var i:int = 1; i< 20; i++){
var targetName:String = "targetarea_" + i + "_mc"
trace( game_mc[targetName].x);
}
I think the name you assign your TargetArea instances isn't automatically converted
into a property of the DisplayObject you attach it to. As far as I remember though this
nonchalant way of accessing MovieClips using array access used to work prior to AS3.
The more elegant solution is to retrieve the child using getChildByName().
trace(game_mc.getChildByName(targetName).x);
Additionally, in case game_mc is an instance of MovieClip or a dynamic class you can make the TargetArea instances a property of it using:
game_mc[targetArea.name] = targetArea;
This way you can access them using game_mc[name].property afterwards.
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!
I am adding moiveClips and putting their position accordingly. I am placing all the dynamically added clips in one new movie clip and then centering that on stage. As a test, I see I can control the alpha in the main container but I can not access the children. How can I assess each flagButton separately? There would be several in this loop example below.
var flagButton:MovieClip;
var flagArray:Array = new Array;
var flagDisplayButtons:MovieClip = new MovieClip();
function displayFlagButtons()
{
for( var i = 0; flagArray.length > i; i++)
{
var flagButton:MovieClip = new roundButton();
flagButton.x = (flagButton.width + 10) * i;
flagButton.y = stage.stageHeight - flagButton.height;
addChild(flagButton);
flagDisplayButtons.addChild(flagButton);
}
addChild(flagDisplayButtons);
// Works
flagDisplayButtons.x = stage.stageWidth/2 - flagDisplayButtons.width/2;
// Does not see flagButton
flagDisplayButtons.flagButton.alpha = .5;
}
GETS ERROR:
TypeError: Error #1010: A term is undefined and has no properties.
In your example code, you have created a bunch of button instances, and one by one you have added them to the display list of flagDisplayButtons. They are on that display list in the order that you placed them.
first instance is at index 0
second instance is at index 1
third instance is at index 2
and so on.
So if you want to access the third button you added, you could do this :
var flagButton:RoundButton = flagDisplayButtons.getChildAt(2) as RoundButton;
Now that you have created variable to reference that button, you can do any of these :
flagButton.alpha = .5;
flagButton.x = 100;
flagButton.y = 200;
You need to use getChildAt or getChildByName to get the children of a DisplayObjectContainer
IE:
flagDisplayButtons.getChildAt(0).alpha = 0.5;
I made this plugin wich positions all child objects of a container in a grid formation. Now I added a clickhandler to the childs in the container, and when I click one of them, it is removed. When I remove a full row (from top to bottom) on the right hand side, all goes well, but when I remove a full row on the left hand side, the position of all the items in the container stay on their place but the container itself will be moved to x = 0 and y = 0. What I want is that all childs in the container are moved to x:0, y:0 as one group.
some pictures on what I get and what I want:
1) What I get:
2) What I get when I remove a full row on the left:
3) What I want:
The code I use:
private function clickHandler(event:MouseEvent):void {
var name:String = event.currentTarget.name;
if(container.getChildByName(name) != null)
container.removeChild(container.getChildByName(name));
trace(name, "container.width: ", container.width);
trace(name, "container.width: ", container.height);
trace(name, "container.x: ", container.x);
container.graphics.clear();
container.graphics.beginFill(0x2C2C2C);
container.graphics.drawRect(container.x ,container.y, container.width, container.height);
container.graphics.endFill();
}
Anyone got an idea on how to fix this? :)
EDIT: Code for creating the grid:
private function generateGrid(rows:int, cols:int, spacing:int):void
{
for (var py:int = 0; py <rows; py++)
{
for (var px:int = 0; px <cols; px++)
{
if(childs.length > 0)
{
var child:* = childs.shift();
child.x = (child.width + spacing) * px;
child.y = (child.height + spacing) * py;
} else {
break;
}
}
}
}
There's not really anything to 'fix', you just haven't written any code to move those objects, so they're not moving. You're redrawing the background of the container based on the new width, but you haven't actually moved any of the objects inside that container.
There are a lot of ways you could do this. The simplest solution that comes to mind would be something like this:
- loop through all the children of the container and find the lowest x position.
- loop through again and subtract that lowest x value from the x position of each child.
(You probably want to do this for the y position too, so they'll move up when you remove the top row.)
You would run that entire process each time a child is removed. If the lowest position is 0, meaning there is an object in the leftmost position, then nothing moves, if there is a blank row, the lowest x will be greater than 0, and everything will move over by that amount.
Disclaimer:
It would probably be 'better' to not muddle the graphical views with the data structure so much, but that's the best suggestion I can offer without seeing the rest of your code.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
public class Grid extends Sprite{
private var _squ:Square;
private var _cont:Sprite;
public function Grid() {
// constructor code
_cont = new Sprite();
addChild(_cont);
for( var i:uint = 0;i< 20; i++){
_squ = new Square(50,50,2,Math.random() * 0xFFFFFF);
_cont.addChild(_squ);
_squ.name = "square_"+i;
_squ.x = 100 + 52 * Math.round(i%5);
_squ.y = 50 + 52 * Math.floor(i/5);
_squ.buttonMode = true;
}
this.addEventListener(MouseEvent.CLICK, onClickAction);
}
public function gridAlign(cont:Sprite):void{
for( var i:uint = 0;i< cont.numChildren; i++){
_cont.getChildAt(i).x = 100 + 52 * Math.round(i%5);
_cont.getChildAt(i).y = 50 + 52 * Math.floor(i/5);
}
}
private function onClickAction(e:MouseEvent):void{
_cont.removeChild(_cont.getChildByName(e.target.name));
this.gridAlign(_cont);
}
}
}
try this.
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);