Action Script 3. How to add multiple children of 1 instance? - actionscript-3

I'm creating flash game. I need to make player lives - heart images. If player have 5 lives should be added 5 hearts <3 <3 <3 <3 <3. I have image with instance name heart. How to add them correctly?
I've tried this:
var lives:Number = 4;
var currentHP = lives;
var heart:Heart = new Heart();
var hpArr:Array = new Array();
function hp() {
for (var i=0; i<lives; i++) {
heart = new Heart();
hpArr[i] = heart;
hpArr.push(heart);
heart.x += heart.width+20;
addChild(heart);
}
trace("Array length" + hpArr.length);
}
This correctly return 5 trace("Array length" + hpArr.length);, so that means hearts successfully added to array. Problem is that only 1 heart is added. What can be problem?

Change your for loop like this:
for (var i=0; i<lives; i++) {
heart = new Heart();
hpArr.push(heart);
heart.x = ( heart.width + 20 ) * i; // here is the trick!
addChild(heart);
}

Related

duplicateMovieClip in Action Script 3

My question is how to do this:
https://www.dropbox.com/s/zi63y771h38a2vo/Example.fla
In Action Script 3.0.
This is working timeline source code, with ready indexing values + sorting news via array.
Simple as that, how to create same thing in ActionScript 3.0?
I was searching on the websites/forums and I couldn't find any answer that was satisfying me, so I decided to create an account in here and ask for help.
If someone could remake this example on ActionScript 3.0, this could help us all, because I saw a lot of questions about duplicateMovieClip() function, but there were no strict answer + example on it, so maybe let's create this?
This is my suggestion, code is in file or here:
stop();
var IDMovieClip = 0;
var IDarray = 0;
var Duplicate:MovieClip;
MC._visible = false;
var ARRAY:Array = new Array();
ENTER.onRelease = function() {
Duplicate = MC.duplicateMovieClip(IDMovieClip, _root.getNextHighestDepth());
var ref = eval(Duplicate);
ref.ID = IDMovieClip;
ref.sortedID = IDarray;
_root[ref.ID].windowID.text = "ID: " + ref.ID;
Duplicate.Close.onRollOver = function() {
trace(_root[ref.ID]._target);
};
Duplicate.Close.onRelease = function() {
_root.ARRAY.splice(_root[ref.ID].sortedID,1);
removeMovieClip(_root[ref.ID]);
IDarray -= 1;
_root.doSort();
};
ARRAY.push([IDarray, IDMovieClip]);
doSort();
IDMovieClip += 1;
IDarray += 1;
};
doSort = function () {
for (var i = 0; i < ARRAY.length; i++) {
_root[ARRAY[i][1]]._y = 10 + ((_root[ARRAY[i][1]]._height + 10) * i);
_root[ARRAY[i][1]].sortID.text = i;
_root[ARRAY[i][1]].sortedID = i;
trace(ARRAY[i]);
}
};
FLA PROJECT DESIGN IN JPG (MovieClips/Placement etc)
(what You need to run it, if You dont want to download it from my DropBox)
If anyone could help, that would be great.
There is no duplicateMovieClip in AS3, in ActionScript 3, you instantiate movie clips. I didn't find place for all used variables, I think it's part of some project, so you should adapt code for your needs. You also should read a bit about Export for ActionScript.
//Container for your objects
var movieHolder: Sprite = new Sprite();
var id:uint = 0;
const padding: int = 10;
//Handler, that will add new objects to the scene
enter.addEventListener(MouseEvent.CLICK, onClickEnter);
addChild(movieHolder);
movieHolder.x = movieHolder.y = padding;
function onClickClose(e:MouseEvent):void {
movieHolder.removeChild(DisplayObject(e.currentTarget).parent);
sortMovies();
}
function onClickEnter(e:MouseEvent):void {
//Set up for MovieClip with form export for ActionScript
var movie:MyFormMovie = new MyFormMovie();
movie.windowID.text = "ID: " + id;
movie.Close.addEventListener(MouseEvent.CLICK, onClickClose, false, 0, true);
movieHolder.addChild(movie);
sortMovies();
id++;
}
function sortMovies():void {
var i: uint, len: uint = movieHolder.numChildren, movie: MyFormMovie;
var posY: uint;
for(i; i < len; ++i){
movie = movieHolder.getChildAt(i) as MyFormMovie;
movie.y = posY;
movie.sortID.text = i.toString();
posY += movie.height + padding;
}
}

Can you create new sprite out of two or more already existing by taking their overlapping part

I have two spites created by drawPath(). Sometimes they might overlap each other and when it happens i want to create new sprite, which contains only overlapping part. Maybe it is really simple but i couldn't find any solution exept draw a rectangle of zone where they overlaps. So if it could be done i really appreciate your help.
for (var j:int = 0; j < zonesAmount; j++) {
var sp:Sprite = new Sprite();
var zoneCoord:Vector.<Number> = new Vector.<Number>(0, false);
var zoneCommands:Vector.<int> = new Vector.<int>(0, false);
var o:XML;
for each (o in xml.ZONE[j].POINT)
{
var tmpCoord:int = o.#X;
zoneCoord.push(tmpCoord);
tmpCoord = o.#Y;
zoneCoord.push(tmpCoord);
}
zoneCommands.push(GraphicsPathCommand.MOVE_TO);
for (var i:int = 0; i < (zoneCoord.length - 2)/4; i++)
zoneCommands.push(GraphicsPathCommand.CURVE_TO);
sp.graphics.beginFill(xml.ZONE[j].#COLOR);
sp.graphics.drawPath(zoneCommands, zoneCoord);
sp.graphics.endFill();
sp.alpha = 0.1;
zones[xml.ZONE[j].#ID - 1] = sp;
var picsToolt:mapTooltip = new mapTooltip(15, 15, xml.ZONE[j].SOURCE.#NMB, xml.ZONE[j].SOURCE.#SRC);
picsToolt.Register(zones[xml.ZONE[j].#ID - 1], "");
addChild(zones[xml.ZONE[j].#ID - 1]);
}
Don't bother for addChild(zones[xml.ZONE[j].#ID - 1]) it doesn't matter
Here is examples of what i'm trying to do:
first and second
Second one describes exactly in what i'm intrested, red rect is what i can do and blue line is what i want

How to remove/reload movieclip/graphic in Flash CS5 with AS3

I have a setupBoard(); and a setupBlocks(); in my function:
function init(e)
{
setupBoard();
removeEventListener(Event.ENTER_FRAME , init);
setupCat();
setupBlocks();
}
function setupBoard()
{
var columns:Array = new Array();
var i,j:int;
var _place:place;
for (i = 0; i < 11; i++)
{
columns = [];
for (j = 0; j < 11; j++)
{
_place = new place();
_place.thisX=i;
_place.thisY=j;
_place.thisDistance=Math.min(i+1,j+1,11-i,11-j)*11;
_place.y = 56 * i + 3;
_place.x = 5 + 71 * j + 35*(i%2);
_place.buttonMode=true;
_place.addEventListener(MouseEvent.CLICK, setBlock);
columns[j] = _place;
// SÆTTER TAL PÅ BRIKKERNE
_place.thisText.text = _place.thisDistance + " - " + _place.thisX + " : " + _place.thisY;
addChild(_place);
}
rows[i] = columns;
}
}
The "place" is the MovieClip
this function loads when the game launches and when the game is finish/completed..
the setupBoard, setup the board ofc, and the setupBlocks setup some movieclips, which contain some graphic.
Here's my question, how do I remove/reload all the blocks when the game enters that function again?
At the moment they are just placed upon each other, which I don't like at all.
If I understood correctly, what you want to do is remove all the previous blocks (from the last time you ran the setup function) when you run setup a second time.
To do that, you should create a function which loops your rows and columns Arrays, and for each Place object it find, it does the following: removes it from the stage, removes all Event Listeners, and finally sets it to null. Your function could look something like this (and you would call it just before calling setup again):
for (i = 0; i < rows.length; i++)
{
var column:Array = rows[i];
for (j = 0; j < column.length; j++)
{
var place:Place = column[j];
if (contains(place))
{
removeChild(place);
}
place.removeEventListener(MouseEvent.CLICK, setBlock);
place = null;
}
column = [];
}
row = [];
I just wrote that straight into the box, so it's not tested. But basically it does the three things necessary to get those objects removed from the view, and clears up anything that would stop them from being freed from memory by the garbage collector.
Hope that helps.
Debu

alternative way for positioning objects

I'm looking for an alternative way to position a bunch of objects.
Here is my code:
private var orderContainer:Sprite;
private var currentOrder:uint = 1;
private var orderArray:Array;
private var scroller:uint;
private var xPos:uint;
private var yPos:uint;
.....
xPos = 55;
yPos = 30;
if (currentOrder == 7){ winkelwagenContent.TestBtn.addEventListener(MouseEvent.CLICK, clickHandler);
scroller++;
xPos = 700*scroller;
yPos = 60;
teller = 1;
currentOrder = 1;
}
orderContainer.x = xPos;
orderContainer.y = yPos;
xPos+=270;
if( teller % 2 == 0){
if(scroller >0){
xPos = (700+(teller*8))*scroller;
}else{
xPos = 55+(teller*8);
}
yPos+=100;
}
teller++;
currentOrder++;
}
private function clickHandler(e:MouseEvent):void{
for each(var order:Object in orderArray){
TweenLite.to(order, .5,{x:order.x-60});
}
}
Basicly what i want is that the objects(ordercontainer) are added to my movieclip in 2 collumns, so 1 left, 1 right, move the y-position down to below the 2 i just added and repeat.
till i get 3 2-collumns under eachother, when it reaches this, the yPosition should get reset to the top and the xPosition should move to the right so i can create a 2-column again next to it, again to 3 2-collumns, reset the yPositon again and repeat till all my objects are added, the amount of objects is variable so the calculation should be flexible.
Its working with the code i have but i have a feeling that i am making it way to complicated again.
You will see that the xPosition adds (teller*8) this is just because my allignment should be slightly diagonal on the yPosition.
There is also a tween attached to a button wich makes all the objects move to the left so the next collumn is visible(this isnt working very well thou, no idea why).
so to summ it up it should go like this:
**(1)** **(2)** **(7)** **(8)**
**(3)** **(4)** **(9)** **(10)**
**(5)** **(6)** **(11)** **(12)**
numbers are for the order the objects are added.
Here's one solution. Suppose you have an array of movieclips called objs.
const colNum:int = 2;
const rowNum:int = 3;
var offset:int = 0;
while (objs.length)
{
for (var j:int=0; j<rowNum; j++)
{
for (var i:int = 0; i<colNum; i++)
{
if (objs.length)
{
var nextObj:MovieClip = objs.shift();
nextObj.x = (offset+i) * nextObj.width;
nextObj.y = j * nextObj.height;
}
}
}
offset+=colNum;
}

How to modify position of children inside loop in AS3

I'm trying to make a dynamic image gallery from and xml. From my tutorials, right now i've got it so it will constantly add the next thumbnail below the other, which is fine, but I'm trying to figure out how to make it that once it reaches a certain y coordinate, it will move the x coordinate over and stack them again. So that rather one long list of thumbs, it will be a side by side stack. For some reason, I can't get it in my head how something like this would work. My goal is to have a side by side stack that I will end up putting in a movie clip that will be masked to show only 2 stacks at a time. Then when clicking a button will slide it over. I was planning to use the "movieclip.length" to calculate how far over to move it, but i haven't gotten that far yet. This is what I got:
var gallery_xml:XML;
var xmlReq:URLRequest = new URLRequest("xml/content.xml");
var xmlLoader:URLLoader = new URLLoader();
var imageLoader:Loader;
function xmlLoaded(event:Event):void
{
gallery_xml = new XML(xmlLoader.data);
info_txt.text = gallery_xml.screenshots.image[0].attribute("thumb");
for(var i:int = 0; i < gallery_xml.screenshots.image.length(); i++)
{
imageLoader = new Loader();
imageLoader.load(new URLRequest(gallery_xml.screenshots.image[i].attribute("thumb")));
imageLoader.x = 0;
imageLoader.y = i * 70 + 25;
imageLoader.name = gallery_xml.screenshots.image[i].attribute("src");
addChild(imageLoader);
imageLoader.addEventListener(MouseEvent.CLICK, showPicture);
}
}
xmlLoader.load(xmlReq);
xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
function showPicture(event:MouseEvent):void
{
imageLoader = new Loader();
imageLoader.load(new URLRequest(event.target.name));
imageLoader.x = 200;
imageLoader.y = 25;
addChild(imageLoader);
}
I can't seem to wrap my head around what I can do to move things over dynamically without having to write a custom if for each set of positions.. I get the feeling I've totally forgotten how to do algebra.
I'd suggest one of the following two solutions (untested):
var next_x:Number = 0.0;
var next_y:Number = 25.0;
for (var i:int = 0; i < gallery_xml.screenshots.image.length(); ++i)
{
// ...
imageLoader.y = next_y;
imageLoader.x = next_x;
next_y += 70;
if (next_y > THRESHOLD)
{
next_x += X_OFFSET;
next_y = 25.0;
}
}
That is, just keep track of where your next image will be placed and adjust that coordinate accordingly when you exceed thresholds. If you want to use your i variable, you'll have to calculate what row and column the image will be placed at:
for (var i:int = 0; i < gallery_xml.screenshots.image.length(); ++i)
{
// ...
var row:int = i % MAX_ITEMS_PER_COLUMN;
var column:int = i / MAX_ITEMS_PER_COLUMN;
imageLoader.y = 25 + row * 70;
imageLoader.x = column * COLUMN_WIDTH;
}