How do I remove the last item of an array? - actionscript-3

I have an array of questions for an interactive quiz game. When you answer a question, functionally I want that question to be removed from the array (cat4Questions) so that it won't come back for the player so I tried to splice it.
I wasn't sure if it was working so I traced the array. While I was expecting "question1, question2, question3, question4" to be traced, "question1, question2, question3, question4, question5" was the result of my trace.
This is the line of code where I try to splice the array:
cat4Questions.splice(cat4Questions.length,1);
trace(cat4Questions);

You should take a look at shift() and pop() array methods.
shift()
Removes the first element from an array and returns that element. The remaining array elements are moved from their original position, i, to i-1.
pop()
Removes the last element from an array and returns the value of that element.
In your case, you probably need the pop() function to remove the last element of the array.

Arrays are zero-indexed, so you should use Array.length-1; to get the index position of the array.
cat4Questions.splice(cat4Questions.length-1,1);
trace(cat4Questions);
trace now.

You are probably going to remove items other than the last item in the array. If for example the user answers another question.
You can use this code to remove any question:
cat4Questions.splice(cat4Questions.indexOf(question), 1);
Edit
As I said in the comments below, you don't really have to look at the performance of this. But here is how to use pop instead of splice.
cat4Questions[cat4Questions.indexOf(question)] = cat4Questions.pop();
You can also remove the calls to pop and indexOf because they are not efficient either
lastQuestion = cat4Questions[--numQuestions];
cat4Questions[question.index] = lastQuestion;
lastQuestion.index = question.index;
Where question is the question to be removed, index is the index of the question (you have to keep track of that) and numQuestions is the total number of questions. This way, you never use length, indexOf, pop, splice, ...

Related

How to make my scoring system update the right variable?

Please take a look at my code at http://pastebin.com/nHB81pVW
As you may notice, there are a few classes which are colored bubbles.
inside those classes there's a function called addScore which calls one of the increaseColor functions at the bottom of the code in the pastebin.
When the bubbles burst, it seems like a random score is updated instead of the corresponding color... how can I make it update the right color?
Please let me know if I need to explain myself better
I think this is your error:
bubbleList.splice(i,1);
bubbleList[i].addScore();
That's wrong. Let's say you have an array: [1, 2, 3], and i is 1. When you do a splice(i, 1);, you actually perform splice(1, 1); and the result would be [1, 3], right?
But then you do bubbleList[i], which is actually array(1), and in our case of [1, 3], the item with index 1 would be 3.
Shortly said, you are removing an element and then you do addScore on the next element from the array.
Instead, do this:
bubbleList.splice(1, 1)[0].addScore();
splice would return you an array of elements that were removed (in your case single one), and so you get the element as position 0 and perform addScore on it.
Cheers!
Edit: or if you want it to be more clear - first addScore, then splice ;)
thanks for the answers and tips.
I placed addScore before removeChild and splice and that fixed the problem.
Thanks :)

AS3 Nullify Object through Reference

I have seem people asking this question, and getting an answer saying that this is impossible in AS3.
So I have a function called destroymc:
function destroymc(mcname:MovieClip):void{
mcname = null
}
This doesnot destroy the movieclip I want to destroy. Because it is passed by reference.
Is there really no way to make this work?
thanks.
Hm, as far as I know, to 'destroy' a MovieClip in AS3.0, you need to get rid of all references to it, and you need to remove it from the parent. Then the GC can collect it.
If you have an array of MovieClips, then something like this could work.
var mcs:Array;
// populate array
// to destroy the first one
mcs[0].parent.removeChild(mcs[0]); // remove the first element from its parent
mcs.shift(); // remove the first element in the array
And so if you want in in a function, you could pass the array to it
function destroymc(mcs:Array){
mcs[0].parent.removeChild(mcs[0]);
mcs.shift();
}
I'm using an array here because you need to use functions like this with dynamically generated MovieClips and entity managers and stuff. I hope this helps.

Removing commas from multidimensional arrays

I'm having a bit of trouble removing commas from an array when I go to write it to a cell in google spreadsheets. array.join(''); doesn't seem to do the trick. I would appreciate any help. Also, anchor[i][j].join('') returns an error.
Here is a bit of code:
anchor[i][j].join('') returns an error
anchor[i].join('') doesn't seem to have an effect.
for (var i=0; i(less than) rangeKW.length-2;i++){
anchor[i] = [];
for (var j=0; j<rangeURL.length;j++){
anchor[i][j] = ahref + rangeKW[i] + ahref1 + rangeURL[j] + "</a>|";
}
}
cell.setValue("{" + anchor);
}
Suppose you have
var x = [[1,2,3],[4,5,6]]
Then either of these lines will give you "123456":
Array.prototype.concat.apply([], x).join('')
x.map(function(a){ return a.join(''); }).join('');
The first one constructs the array [1,2,3,4,5,6] and then joins it. The second one joins each inner array first, constructing ["123", "456"] and then joins that. I think the first one is likely to be a tiny bit more efficient, although we are talking peanuts here, but the second one gives you a bit more control if you want to put something different between rows and columns.
In both cases, this doesn't change the original value in x. You can assign the new value to x if that's what you want.
array.join() works with "normal" arrays, by normal I mean 1 dimension and applies to the array itself, not on an single element (error on [i][j]), beside that I don't really understand what you want to do and how your code is related to your question ...
concerning anchor[i].join('');// doesn't seem to have an effect. I don't know how many elements are in there and how they look like but the syntax is correct. You can also use toString() if you want to make it a CSV string.
EDIT : (thanks for the information in comments.)
I think the easiest way (or at least the most clear) would be to create a couple of new variables that you could log separately to see exactly what happens.
for example
var anchorString = anchor[i].join(); // or toString() they both return strings from 1D arrays
Logger.log(anchorString)
if every index i of anchor have to be in the same cell then write it like this in the i-loop :
var anchorString += anchor[i].join();
Logger.log(anchorString)

How to represent an empty Array in Action Script 3.0

i'm trying to make a question game with 30 question divided into 3 dificulties, so i'm using arrays to have my questions randomized but not repetitive.
I made the code use the first parameter of the array (array[0]) then remove it from the array.
So, my array will have no more elements after a time. But, when my array have only 1 element, i cant play this element, and i need to use the representation of the empty array to get it to play.
I'm new on AS3, so this may seem very confusing. Here is the code I used.
btn_1.addEventListener(MouseEvent.CLICK,retor);
function retor(e:MouseEvent):void{
trace(vaitemp);
gotoAndStop(1,vaitemp[0]);
vaitemp.splice(0,1);
if(vaitemp.length==0){
trace ("acabou")
gotoAndStop(1,vai2temp[0]);
vai2temp.splice(0,1);
trace(vai2temp)
}
}
I need to represent the "vaitemp" Array as an empty array at the "if"function, so it will play the last element and THEN go to the next array (the "medium dificulty group").
Well, the question is preety messy, i hope any of you can understand what I want.
The literal for an empty array is just []. As in var emptyArray:Array = [];

retrieving a variable value from lower level

well i created some variables in the main stage level, with something like this:
for(i=0,i<10,i++){
var var_name="var_num_"+i;
this[var_name]="some value";
}//<-----------------------------------------------------works
so i get 10 variables named "var_num0", "var_num1", "var_num2" each one with some value.
and i can acces them any where calling this
var second_var=MovieClip(root).var_num0;//<--------------works
my problem comes when i want to call all the variables from a lower level or in another frame or somewhere else using another loop:
var third_var;
for(j=0,j<3,j++){
third_var=this["MovieClip(root).var_num_"+j];//<---------DOSNT WORK
trace(this["MovieClip(root).var_num_"+j]);//<------------returns "undefined"
}
how can i make this work? i tried a lot of things and nothing...
thanks you all
In your case both "root" and "this" are the scope you want to access the vars from. so try this:
var third_var:MovieClip;
for(j = 0; j < 3; j++)
{
third_var = MovieClip(root)[var_num_ + j];
trace(third_var);
}
Also you should have semi-colons in your for loop rather than comers.
I'd like to preface my answer with a suggestion you use a 'Document Class' with AS3 to make things like namespaces and inheritance much clearer. You know exactly where things are accessible when using document based, object oriented programming versus the timeline programming available through the Flash IDE (its only there because of AS1/2). Tut: http://www.kirupa.com/forum/showthread.php?223798-ActionScript-3-Tip-of-the-Day/page14
On to the answer: You are trying to move two levels of inheritance in one set of [] Another way of writing your first "Doesn't work" line is:
this.myMovieClip["var_num"+j"];
You could also use: this["MovieClip"]["var_num"+j];
Basically, you need to take the "MovieClip(root)" out of the string you are using to call your variable because you are passing through two levels of inheritance: this->MovieClip->targetVar
You need to use two periods, a period and a set square bracket or two sets square brackets to move two levels of inheritance. A period . and a set of square brackets [] both accomplish the task of moving one level deeper, so putting the . inside the string used to call up your variable won't work.
Explanation:
The following three examples all return the same variable:
myMovieClip.my_variable
myMovieClip["my_variable"]
var str:String = "my_variable";
myMovieClip[str];