Retrieving datas within an Array - arrays

This is probably easy but I just cannot get the answer. Here is a simple Array:
I want the information to be distributed from an Input textBox to different dynamic textBox after a click. I am OK with buttons.
var ERLQ1:Array = ["ERLQ1", "N09°02.61 / E100°49.11", "ErawanLq"];
InputText = "ERLQ1";
//I want to display:
Txt1 = "ERLQ1" //Being first part of the array as main reference.
Txt2 = "N09°02.61 / E100°49.11" // Should be: String(ERLQ1[1])
Txt3 = "ErawanLq" // Should be: String(ERLQ1[2])
First time I write in a forum like this. Please forgive if not perfect. Thanks in advance.
Andre

If I understand correctly, an array of objects would work well. Since you have a set number of textfields I assume that you also have a set number of details that you want to display in them. If that is the case, this solution should work fine.
arr:Array = [{_name:"ERLQ1",ans1:"N09°02.61 / E100°49.11",ans2:"ErawanLq"},
{_name:"ERLQ2",ans1:"question 2 answer 1",ans2:"ques2ans1"}];
So, I don't really "get" your application, but if it were some sort of a quiz, you'd have a new array element for each question, and that element has a name, and two answers. Easy to modify it to grab answers from an answer pool. Now to find the element in the array that has ._name == "ERLQ1" you will need to loop through all the elements and return the one that has the ._name property that matches your search. Here is an example function:
private function matchName(arr:Array, term:String):int{
for (var i:int = 0; i < arr.length; i++){
if (arr[i]._name == term){
return i;
}
}
return -1;
}
This function will return the array index number of the matching term. If no match exists, it returns -1. So you could use it like this (pseudocode):
// on submit search{
// find the index number in the array of the element that matches the search term
var ind:int = matchName(arr, searchTerm);
// assign the textfield texts to the corresponding associated values
textBox1:text = arr[ind]._name;
textBox2:text = arr[ind].ans1;
textBox3:text = arr[ind].ans2;
}

I perhaps misunderstood (because of my English), but :
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
var ERLQ1:Array = ["ERLQ1", "N09°02.61 / E100°49.11", "ErawanLq"];
var Txt1 : TextField = new TextField();
Txt1.autoSize=TextFieldAutoSize.CENTER;
Txt1.type = TextFieldType.INPUT;
Txt1.border = true;
var Txt2 : TextField = new TextField();
Txt2.autoSize=TextFieldAutoSize.CENTER;
Txt2.type = TextFieldType.INPUT;
Txt2.border = true;
var Txt3 : TextField = new TextField();
Txt3.autoSize=TextFieldAutoSize.CENTER;
Txt3.type = TextFieldType.INPUT;
Txt3.border = true;
addChild(Txt1);
addChild(Txt2);
addChild(Txt3);
Txt1.x = 20, y =40;
Txt2.x = 180, y =40;
Txt1.x = 300, y =40;
Txt1.text = ERLQ1[0]; // is now : first part of the array as main reference (String(ERLQ1[0]).
Txt2.text = ERLQ1[1]; // is now : String(ERLQ1[1]);
Txt3.text = ERLQ1[2]; // is now : String(ERLQ1[2]);
This will display 3 TextFiels as input text like this :
If I misunderstood your question, please tell me more about what You expect!
Best regards.
Nicolas

Related

How do I randomize quiz questions in actionscript3?

I have a quiz game in flash; basically you need to type the answer to answer 4 questions. In the end, it will show you the score and your answers vs. The correct answers.
I need help on how to randomize the questions (without repeating the question)
In the end the correct answer needs to match the order in which the player answered the question.
I attached the pictures below.
The code: Frame 1
stop();
var nQNumber:Number = 0;
var aQuestions:Array = new Array();
var aCorrectAnswers:Array = new Array("Jupiter", "Mars", "war", "Titan");
var aUserAnswers:Array = new Array();
aQuestions[0] = "What is the biggest planet in our solar system?";
aQuestions[1] = "Which planet in our solar system is the 4th planet from the
sun?";
aQuestions[2] = "Mars is named after the Roman god of ___.";
aQuestions[3] = "What is the name of Saturn's largest moon?";
questions_txt.text = aQuestions[nQNumber];
submit_btn.addEventListener(MouseEvent.CLICK, quiz);
function quiz(e:MouseEvent):void{
aUserAnswers.push(answers_txt.text);
answers_txt.text = "";
nQNumber++;
if(nQNumber < aQuestions.length){
questions_txt.text = aQuestions[nQNumber]}
else{
nextFrame()}
}
Frame 2
var nScore:Number = 0;
for(var i:Number = 0; i < aQuestions.length; i++){
this["userAnswer" + i + "_txt"].text = aUserAnswers[i];
this["correctAnswer" + i + "_txt"].text = aCorrectAnswers[i];
if(aUserAnswers[i].toUpperCase() == aCorrectAnswers[i].toUpperCase()){
nScore++}
if(i == aQuestions.length - 1){
score_txt.text = nScore.toString()}}
A common way to handle this, would be to create an array to hold your questions that need to be asked, randomize the array, then remove the corresponding question from the array at the time it is asked. Then when that array is empty, move on to your recap screen.
Here is one of many ways you could accomplish this:
First, let's simplify this by using objects instead of a whole bunch of arrays. Your object will have properties for all the relevant information
//create an array that will hold all your questions
var questions:Array = [];
//add a new question object to the array, repeat for all questions
questions.push({
question: "What is the biggest planet in our solar system?",
correctAnswer: "Jupiter"
userAnswer: null,
correct: false
});
Next, let's randomize that array:
//sort the array with the sort function below
questions.sort(randomizeArray);
//this sorts in a random way
function randomizeArray(a,b):int {
return(Math.random() > 0.5) ? 1: -1;
}
Now, let's copy the array to keep track of which questions need to be asked still
var askQuestions:Array = questions.concat(); //concat with no parameters returns a new shallow copy of the array
var curQuestion; //create a var to hold the current question
Now, create a function to ask the next question:
function askNextQuestion():void {
//check if there are any more questions to ask
if(askQuestions.length > 0){
//get the next question object
curQuestion = askQuestions.shift(); //shift removes the first item of an array, and returns that item
questions_txt.text = curQuestion.question;
answers_txt.text = "";
}else{
//all questions have been asked, show your recap screen
finish();
}
}
You'll need a function to run when you click the answer button:
function submitAnswer(e:Event = null):void {
//if there is a current question
if(curQuestion){
curQuestion.userAnswer = answers_txt.text;
curQuestion.correct = curQuestion.correctAnswer.toUpperCase() == answers_txt.text.toUpperCase();
}
//ask the next question
askNextQuestion();
}
And a function that runs when all questions have been asked:
function finish():void {
var score:int = 0;
//go through the array and count how many are correct and recap
for(var i:int=0; i<questions.length;i++){
if(questions[i].correct) score++;
trace("Question " + (i+1) + ":",questions[i].question); //arrays are 0 based, so we add 1 to the index (i) so that it says "Question 1:" for the first question instead of "Question 0:"
trace("You answered:",questions[i].userAnswer);
trace("Correct Answer:", questions[i].correctAnswer);
trace(questions[i].correct ? "You were correct" : "You were wrong","\n"); //this is shorthand if statement, \n is a line break
}
score_txt.text = score + " out of " + questions.length;
}
And of course, to get things started you just do: askNextQuestion()
Are you looking for the nifty feature called Math.random()? Multiply the result of Math.random() by your desired random generation range, round it, and select a random question in your array using the number.

Flash multidimensional array of movieclips

Programming an educational program with fractions, you can touch a part of a fraction on a digiboard (or pc screen) that becomes colored/active. Touch or click it a second time and it becomes white/unactive again. And so on...
To reset a fraction with all of its colored parts to white I want to press a single button once that's calling the function resetFraction. Please take a look at the code below, it seems to go wrong at the two-dimensional array with movieclips - no change from colored to a white part. All arrays containing names of movieclips:
//array with fractions containing the (real) movieclips of parts
//mc_frac1 has one part, mc_frac2 has two parts, and so on
var fractionAr : Array = new Array(mc_frac1, mc_frac2, mc_frac3, mc_frac4, mc_frac5);
//array with max-index for partAr, see below
var maxPart : Array = new Array(1,2,3,4,5);
//array with parts, 2 dimensional with a variable index per fraction
var partAr : Array = new Array(
new Array(mc_part1_1),
new Array(mc_part2_1, mc_part2_2),
new Array(mc_part3_1, mc_part3_2, mc_part3_3),
new Array(mc_part4_1, mc_part4_2, mc_part4_3, mc_part4_4),
new Array(mc_part5_1, mc_part5_2, mc_part5_3, mc_part5_4, mc_part5_5));
//put all parts back to 'untouched' (color white)
function resetFraction(var FracNum : Number) {
var p : Number = FracNum;
for (var i = 0; i < maxPart[p]; i++) {
fractionAr[p-1].partAr[p-1][i].gotoAndStop(1);
}
}
This code below is split up in portions to see where it goes wrong:
p = 4;
mc_frac4.mc_part4_2.gotoAndStop(1); //works
fracAr[p-1].mc_part4_2.gotoAndStop(1); //works
//but
fracAr[p-1].partAr[3][1].gotoAndStop(1); //does nothing
The two-dimensional array seems to be the problem.
Anyone can help me? It saves a lot of code to realise this with one function.
Thanks a lot.
I'm out!
Instead of the dot (.) I use the array acces operators ([ ]) and quotes (" ") in the partAr array:
var partAr : Array =
new Array(
new Array("mc_part1_1"),
new Array("mc_part2_1", "mc_part2_2"), and so on...
while the fourth line in the function becomes this:
function resetFraction(var FracNum : Number) {
var p : Number = FracNum;
for (var i = 0; i < maxPart[p]; i++) {
fractionAr[p-1][partAr[p-1][i]].gotoAndStop(1);
}
}
Simple, isn't it?

Actionscript 3 and sorting incoming bytes from an arduino

im new to using action script so i apologies if this wont make sense, the issue iam having is that the incoming bytes from my arduino are not being stored properly in an array. The bytes come in one at a time from my arduino and will be stored in an array in as3.
i have two values SF-F8-001, SF-F8-002 and SF-F8-003 etc... when i trace the incoming bytes i get this:
S
F
-
F
8
-
0
0
1
so when i look at that i realized i needed an array to store the byte as they come in however i have tried many different things but it hasnt worked
however this code below seems to get me close to my desired result
import flash.events.*;
import flash.net.Socket;
import flash.utils.ByteArray;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequestMethod;
var ary:Array = new Array();
var bar_grab:Array = new Array();
var array:Array = new Array();
trace("__AS3 Example__");
var socket:Socket = new Socket("localhost",5331);
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
function socketDataHandler(event:ProgressEvent):void
{
var str:String = String(socket.readUTFBytes(socket.bytesAvailable));
var b:String;
bar_grab.push(str);
b = bar_grab.join("");
boxtwo.text = b;
}
this code gets me this
SF-F8-001SF-F8-002SF-F8-003 etc...
however the result iam looking for is this
SF-F8-001,SF-F8-002,SF-F8-003 etc....
so if anyone could help me sort this out i will be grateful
thank you
If you know a priori how many characters each item will consist of you could read everything to string and get each individual item like that:
//Main string containing all items
var allString:String = "123456789";
//Number of chars in of item
var charsInItem = 3;
var item:String;
var index:int;
var resultArray:Array = new Array();
for(var i:int = 0; i < allString.length/charsInItem; i++)
{
index= i*charsInItem;
//traces name of one item
item = allString.slice(index, index+charsInItem);
resultArray.push(item);
trace(item);
}
//Output:
//123
//456
//789
If you don't know a number of chars in one item or it varies, I would suggest tweaking Arduino code and putting some sort of a marker in between every item. Like say a comma (,). Then your string would look something like this: "item1,item2,longerItem3". And you could split that string into array like that:
var array:Array = new Array();
var allString:String = "item1,item2,longerItem3";
//This splts string into array items using comma (,) as a seperator
array = allString.split(",");
for(var i:int = 0; i < array.length; i++)
{
//trace every array element
trace(array[i]);
}
//Output:
//item1
//item2
//longerItem3
I should add that even if you know a number of chars in one item I would still suggest using method nr.2.

hitTestObject not hitTesting with all MovieClips

Hey guys having a little trouble this might be easier than i am making it out to be.
But the problem that i am having is when i hittest my mcPoints with my mcPlayer it is only interacting with 4 out of 5 of the movie clips that are added to the stage by a for loop.
I have been struggling with this for the past two days and cant seem to pin point the problem, everything seems set up perfectly but maybe you can help.
These are my Variables:
public var mcPoints:smallGainPoints;
private var nPoints:Number = 5;
private var aPointsArray:Array;
Here is how i set up the 5 mcPoints Movie Clips to be added to stage:
private function addPointsToStage():void
{
var startPoint:Point = new Point((stage.stageWidth / 2) - 100, stage.stageHeight / 2);
var spacing:Number = 50;
for (var i = 0; i < nPoints; i++)
{
trace(aPointsArray.length);
mcPoints = new smallGainPoints();
aPointsArray.push(mcPoints);
stage.addChild(mcPoints);
mcPoints.x = startPoint.x + (spacing * i);
mcPoints.y = startPoint.y;
}
}
So that adds the 5 points movie Clips to the stage which are aligned horizontally.
And finally here is the loop that listens for the HitTestObject to Initiate:
private function checkPlayerHitPoints():void
{
for (var i:int = 0; i < aPointsArray.length; i++)
{
//get current point in i loop
var currentPoints:smallGainPoints = aPointsArray[i];
//test if player is hitting current point
if(player.hitTestObject(currentPoints))
{
//Add points sound effects
var pointsSound:Sound = new pointsPickUpSound();
pointsSound.play();
//remove point on stage
currentPoints.destroyPoints()
//remove points from array
aPointsArray.splice(i, 1);
trace(aPointsArray.length);
//Add plus 5 text to current points position
mcPlus5 = new plusFiveText();
stage.addChild(mcPlus5);
mcPlus5.x = (currentPoints.x);
mcPlus5.y = (currentPoints.y);
//Update high score text
nScore += 5;
updateHighScore();
}
}
}
So i added traces both for when the movie clips are added and when they are hit here are the values i get:
0
1
2
3
4
Hit: 4
Hit: 3
Hit: 2
Hit: 1
Also i call the addPointsToStage(); in my constructor for more information.
So from the values im getting it seems that the last value "0" isn't being interacted with, any ideas why? Please anything would be of use. Thanks so much!
i'm not exactly sure what your code is suppose to be doing. But when you remove element from array in loop you are lose one item.
You array is
[1][2][3][4][5]
When i=1 you remove element and get
[1][3][4][5]
next interation i=2 which means you never test agains value 3.
You should decrement i whenever you remove element from an array.

Finding the biggest width of multiple text fields in AS3

I have an array that makes multiple textfields based off a user variable. The code below is connected to a function that fires when text is added. From there it's supposed to find the widest text field, and then apply the width to rest of the textfields so they all are the same size.
Here is the code that is giving me problems. I could use a second look to see perhaps if my syntax is improper or if there's a better way at going at this.
for (var ied: int=1; ied>=electoff.electinput.textArray.length; ied++)
{
trace("one");
widest=(electoff.electinput.textArray["b"+ied].width>widest)?electoff.electinput.textArray["b"+ied].width:widest;
}
for (i =ied; i<electoff.electinput.textArray.length; ied++)
{
electoff.electinput.textArray["b"+ied].width = widest;
trace("two");
}
Here's the error I'm getting:
TypeError: Error #1010: A term is undefined and has no properties. at
NewPlv2_fla::MainTimeline/ajWidth()[NewPlv2_fla.MainTimeline::frame1:650] at NewPlv2_fla::MainTimeline/_keys()[NewPlv2_fla.MainTimeline::frame1:774]
AS3.0 Array is indices are zero-based, which means that the first element in the array is [0], the second element is [1], and so on.
so FYI you trying to access textArray["b"+ided]. but this syntax is a Associative arrays
I tested following code. check please.
import flash.text.TextField;
var arr:Array = [];
for(var i:int = 0; i<10; i++)
{
var tf:TextField = new TextField();
tf.width = 200 * Math.random();;
tf.name = "tf" + i;
tf.height = 100;
arr.push(tf);
trace(tf.name + ": " + tf.width);
}
var widest:Number = 0;
for (i=0;i<arr.length;i++)
{
if(arr[i].width>widest) widest = arr[i].width;
}
trace("widest: " + widest);

Resources