How to push textbox value into Array and recall it - actionscript-3

This is the first time I ask in this website, if there's any mistake and inappropriate thing apologize in advance
I was trying to make my own basketball score board using Action Script 3 but I am stuck on the way of calling a player fouls score and show it individually.
In the picture, the second box is where to type a player number who made a foul and the third box is where the number shows how many times this player has fouled.
I need to know how to code an array store that receives a value from the 'Player' textbox as the player number and stores the fouls count with the specific player's number too (if I type another player number it will count a foul separately and next time I type the exist number it will call out how many times he fouls)

You could use an array, or a dictionary, or even dynamic properties.
Let's assume your text fields are called txtTeam1fouls, txtPlayer, txtFouls, txtTeam2fouls. Let's also say you have a var called curTeam that stores an integer identifier for the team whose player number you enter (for this example, either 1, or 2).
Here is an example of storing a basic object in an Array:
var fouls:Array = []; //create a new empty array
//add a listener for when you type something into the player text input
txtPlayer.addEventListener(KeyboardEvent.KEY_UP, updatePlayer);
//this function retries a foul record from the array for a specific player
function getFouls(player:int, teamId:int):Object {
//loop through the array until you find a match
for(var i:int=0;i<fouls.length;i++){
if(fouls[i].player === player && fouls[i].team === teamId){
return fouls[i];
}
}
//if no record in the array, return 0
return null;
}
//this function updates the foul text field when you change the what's in the player text field
function updatePlayer(e:Event):void {
var foulRecord = getFouls(int(txtPlayer.text), curTeam);
//if a foul record exists, use it's foul count, if not use 0
txtFouls.text = foulRecord ? foulRecord.fouls.toString() : 0;
}
//call this function whenever you add a new foul record.
function addFoul(player:int, teamId:int):void {
//first, see if there is an existing foul record in the array
var foulObj:Object = getFouls(player, teamId);
if(!foulObj){
//if there was no record, create one, then push (add) it to the array
foulObj = {team: teamId, player: player, fouls: 1};
fouls.push(foulObj);
}else{
//if there is an existing record, increment it.
foulObj.fouls++;
}
//now update the totals for each team
var team1Ctr:int = 0;
var team2Ctr:int = 0;
for(var i:int=0;i<fouls.length;i++){
switch(fouls[i].team){
case 1:
team1Ctr++;
break;
case 2:
team2Ctr++;
break;
}
}
txtTeam1Fouls.text = team1Ctr.toString();
txtTeam2Fouls.text = team2Ctr.toString();
}

Related

AS3 event.target and var

I have an editable text field (c) in a movieClip, well 3 movielips like this actually named a1, a2 and a3. Movieclips are already on stage. The path to text field in each MC is mc.a1.c, mc.a2.c and mc.a3.c
The initial value for each textfield is set by XML which is also stored in variables with the same names and the movieclip(a1,a2,a3). If the user updates a textfield a CHANGE event listener triggers checkValue function. If the value is greater than my maxValue I want my function to return the text field to its original value and give the user an error message. So if textfield c in mc.a1.c is updated, I'm currently taking the name of its parent (a1) and then trying to reference the variable with the same name so that textfield c will be returned to the initial value held in var a1 (I'll only know which var to reference once a textfield update has been attempted.. hope that makes sense)
I've tried several things but always end up with the variable name, and not its value in the textfield. So, for now I've reverted to populating the field with 0 until I can find an answer.
example code:
aH.t1 is the predefined max value
function chngTh(event:Event):void{
var thR:String = String(event.target.parent.name.substring(0,1));
if (thR =="a"&&thN>int(aH.t1.text)){
event.target.text = 0; //I want the reference var a(x)and have its value in the text field
aH.errorMsg.text = "The number cannot be greater than 10 so the original value has been restored";
}
}
As you can probably tell my my code, I'm not a developer and I've already looked here in search of but can't seem to get grasp it...Is it me?
reference variable AS3
AS3: Using string as variable
Is what I'm trying to do achiveable in AS3?
Thanks to guidance from dene the solution looks like this:
function chngTh(event:Event):void{
var thR:String = String(event.target.parent.name.substring(0,1));
var thN:int = (event.target.text);
var thov:int = root[event.target.parent.name];
if (thR =="a"&&thN>int(aH.thrsh.t1.text)){
event.target.text = thov;
aH.errorMsg.text = hclbl[12];
}
}
Use event.target in the listener function to reference the text field that changed:
var maxValue = 5;
myTextField.addEventListener(Event.CHANGE, textListener);
function textListener(event:Event)
{
var tf = event.target as TextField;
var currentValue = parseFloat(tf.text);
if (currentValue > maxValue) {
tf.text = getOriginalValue(tf);
}
}
function getOriginalValue(tf:TextField) : Number
{
// Assuming the textfield's parent is named "a" + number (eg. a1, a2 etc.)
// Get the number of the parent by ignoring the character at index 0
var parentName = tf.parent.name;
var parentNumber = parentName.substring(1);
// Now you can use parentNumber to access the associated variable (a1, a2, etc)
// Assuming these variables are defined on the root (main timeline).
var originalValue = root["a" + parentNumber]
// If the variables are stored as Strings, this line is needed to convert it to a Number type
originalValue = parseFloat(originalValue)
return originalValue;
}

Save Number with Shared Object and Add to that Saved Number.

Hey everyone so basically what I am trying to accomplish is saving a number with the Shared Object which the the coins that the player collects in the game and if they player quits out of the game and comes back to play again the amount of coins he had when he quit will still show and he will be able to add to that amount if the player picks up more coins. I had this working for a bit but then the textfield started displaying "NAN".
Here is how I have it set up.
The Variable private var nCoins:Number;
In the constructor function I have:
sharedObjectCoins = SharedObject.getLocal("CoinsData");
nCoins = 0 + sharedObjectCoins.data.tCoins;
if (sharedObjectCoins.data.tCoins == null)
{
sharedObjectCoins.data.tCoins = nCoins;
}else
{
trace("Save data found."); // if we did find data...
loadDataTimeAttack(); // ...load the data
}
and in the games Enter.Frame Loop I have the function saveDataCoins which is setup like so:
private function saveDataCoins():void
{
if (nCoins > sharedObjectCoins.data.tCoins )
{
sharedObjectCoins.data.tCoins = nCoins;
}
coinsGraphic.coinsText.text = " " + sharedObjectCoins.data.tCoins;
sharedObjectCoins.flush();
}
not sure if you need the function to where the hitTest takes place between the coins and player but here it is:
private function checkPlayerHitCoins():void
{
for (var i:int = 0; i < aCoinsArray.length; i++)
{
//get current point in i loop
var currentCoins:mcCoin = aCoinsArray[i];
//test if player is hitting current point
if(player.hitTestObject(currentCoins))
{
nCoins += 1;
updatecoinsTextScore();
updateCoinsPauseScreen();
//Add points sound effects
var coinsSEffect:Sound = new coinsSound();
coinsSEffect.play();
//remove point on stage
currentCoins.destroyCoins();
//remove points from array
aCoinsArray.splice(i, 1);
trace("Hit: " + aCoinsArray.length);
}
}
}
Please if anyone could help me with this maybe point something out that I am doing wrong. This code worked perfect one time and when I closed the screen and came back to re test it the textfield displayed NAN and thats it when I hitTest the coins sometimes the NAN switches to a number for like a second but then goes back to NAN.
The first time (or rather every time it creates a new shared object) you will be trying to add undefined to 0, which will result in either a runtime error or NaN.
You need to check if the value exists before attempting to do addition with it.
if(sharedObjectCoints.data && sharedObjectCoins.data.tCoins && !isNaN(sharedObjectCoins.data.tCoins)){
nCoins = Number(sharedObjectCoins.data.tCoins); //there's not point in adding 0
trace("Save data found."); // if we did find data...
loadDataTimeAttack(); // ...load the data
}else{
sharedObjectCoins.data.tCoins = nCoins;
}
Also, if you don't manually set a value to a number var, it will start off life as NaN. eg var nCoins:Number will be NaN until you set it to something.
That said, working with the sharedObject directly like this is a very sloppy way to code your program. Really you should just use shared object to load and save the value, and everything in between use a strongly typed variable.
var nCoins:int = 0;
var tCoins:int = 0;
sharedObjectCoins = SharedObject.getLocal("CoinsData");
if(sharedObjectCoins.data && sharedObjectCoins.data.tCoins && !isNaN(sharedObjectCoins.data.tCoins){
tCoins = int(sharedObjectCoins.data.tCoins);
}else{
//no shared object, use default value for tCoins
tCoins = 0; //or whatever it should start off as.
}
Then write a save function
private function saveSharedObject():void {
sharedObjectCoins.data.tCoins = tCoins;
sharedObjectCoins.flush();
}
Then replace all other instances of sharedObjectCoins.data.tCoins with the var tCoins
It's probably best not to flush the shared object every frame for performance purposes.
Also, shared objects may or may not actually save, depending on user preferences, storage space available, etc. They should not be relied upon for critical data retention.
You can listen for problems with the shared object with AsyncErrorEvent.ASYNC_ERROR I believe (It's been a while since I've worked with AS3 Shared Objects)

getting a random element from an array of movieclips(or labels in a timeline) in Flash CC . Actionscript 3

I am making a pretty neat quiz-game in flashCC right now and I definitely need your help.
My skills are more on the design then the programming side. So to many of you this might seem a baby question (and asked many times before) but from all the answers I saw so far, I couldn't get any results for my project.
So here is the thing :
I need the EXACT script for creating an array (with movieclips inside? or instance names of mcs? How does this even work?)
and a method, to pick a random element of this array without repeats until the "game is over".
Paul
The easiest way to pick a random element from an array without repeating is to first sort the array with a "random" function, then pop or shift items out of it until the array is empty.
Let's say you have an array of items which can be filled with either instances or instance names, you've chosen instance names: :
var FirstArray:Array = ["blau", "orange", "green"];
Now, you'll need a random sort function:
// you do not need to modify this function in any way.
// the Array.sort method accepts a function that takes in 2 objects and returns an int
// this function has been written to comply with that
function randomSort(a:Object, b:Object):int
{
return Math.random() > .5 ? -1 : 1;
}
The way a sort function normally works is it compares two objects and returns -1 if the first item precedes the second item, 1 if the opposite is true, and 0 if they are the same.
So what we're doing in the function above is returning -1 or 1 randomly. This should get the array all jumbled up when you call:
FirstArray.sort(randomSort);
Now that the array is randomly sorted, you can begin pulling items from it like so:
if(FirstArray.length) // make sure there's at least one item in there
{
// since you are using instance names, you'll need to use that to grab a reference to the actual instance:
var currentQuizItem:MovieClip = this[FirstArray.pop()];
// if you had filled your array with the actual instances instead, you would just be assigning FirstArray.pop() to currentQuizItem
// every time you call pop on an array, you're removing the last item
// this will ensure that you won't repeat any items
// do what you need to do with your MovieClip here
}
else
{
// if there aren't any items left, the game is over
}
When strung together, the above code should be enough to get you up and running.
You could try something like:
var array:Array = [1, 2, 3, 4, 5];
var shuffledArray:Array = [];
while (array.length > 0)
{
shuffledArray.push(array.splice(Math.round(Math.random() * (array.length - 1)), 1)[0]);
}
trace('shuffledArray: ', shuffledArray, '\nrandom item: ', shuffledArray[0]);

Save items(MovieClips) and dynamically create them

I made an invetory in AS3 which allows me to put items on slots in a closet, or in slots in the inventory. It completely works, but there is one problem.
In the game you are supposed to be able to buy new items and add them to the closet. I want this to be saved so that it is available the next time you play.
To do this, I want to save an Array to a SharedObject, then create the items dynamically from the array.
Right now I'm using the old fashioned hard coding for each object;
Itemwrench = new WrenchItem();
Itemwrench.x = par.toolCloset.kast_1.slotTC1.x + 400;
Itemwrench.y = par.toolCloset.kast_1.slotTC1.y + 245;
Itemwrench.gotoAndStop(2);
Itemwrench.name = "slotTC1";
Itemwrench.TC = 1;
NotinventoryParentTC.addChild(Itemwrench);
However, to add them dynamically I'd have to use getChildByName before it is added to the stage, which is not possible.
If possible could you show me how to do this correctly?
The information you need:
-The items are all stored in a closet with slots(Instances in the closet movieclip).
-The items need to get the name slotTC + the integer in a for loop.
-The name of the items change according to the slot number they are assigned when you take them out of the closet or put them back into the closet.
for(var i:int = 0; i < itemsInTC.length - itemsInTC.indexOf(e.currentTarget.name) - 1; i++)
{
nextSlotTC = "slotTC" + (itemsInTC.indexOf(e.currentTarget.name) +2 +i);
trace("Next Slot: " + nextSlotTC);
TempStrTC = "slotTC" + (itemsInTC.indexOf(e.currentTarget.name) +1 +i).toString();
trace("temp string: " + TempStrTC);
NotinventoryParentTC.getChildByName(nextSlotTC).x =
par.toolCloset.kast_1.getChildByName(TempStrTC).x + 400;
NotinventoryParentTC.getChildByName(nextSlotTC).y =
par.toolCloset.kast_1.getChildByName(TempStrTC).y + 245;
if(Boolean(NotinventoryParentTC.getChildByName(nextSlotTC)))
{
NotinventoryParentTC.getChildByName(nextSlotTC).name = TempStrTC;
}
}
This way I assign a new name and place them in the slot with the new name they received.
So now my question:
How do make it so that you can save the items to a shared object so that they are in the closet the next time you play the game.
Sorry for the long question.
Thanks in advance,
Milan.
You cannot directly store a DisplayObject in a SharedObject, as it contains memory links which will not be valid if you load such an object. A comon way to work around this is to store a significant data portion of that object. For example, you devise a following structure:
class SlotStructure {
public var slotID:int;
public var itemID:int;
public var itemName:String;
public var itemParameters:Array; // stuff simple types here
}
Then, for each of your items in inventory, you generate a SlotStructure object describing a particular inventory object. For your wrench it could look like this:
var ss:SlotStructure=new SlotStructure();
ss.slotID=1;
ss.itemID=getID(item); // assuming a function that returns a type of an item
ss.itemName=item.name;
ss.itemParameters=new Array();
for (var param:String in item) ss.itemParameters.push({name:param,value:item[param]});
Then you store an array of these into your SharedObject. To retrieve an inventory from a SharedObject you do:
public static const
registerClassAlias("SlotStructure",SlotStructure); // to be able to typecast from SO
for (var i:int=0;i<slots.length;i++) {
var ss:SlotStructure=slots[i];
var item:Item=new getClassFromID(ss.itemID)(); // a function that returns class
// say 1 - wrench, 2 - short sword, 3 - long sword, etc, one type=one ID
for each (var o:Object in ss.itemParameters)
item[o.name]=o.value;
placeIntoSlot(item,ss.slotID); // this does manipulation with x&y and display
}
A function getClassByID() might look like this:
private static const CLASSES:Array=
[StoneItem,WrenchItem,ShortswordItem,LongswordItem,...];
// manually stuff all your items in this!
public function getClassByID(id:int):Class {
return CLASSES[id];
}
The entire solution can be tailored to particular task, for example, in my game I have gems, that differ by location, type, size and score, so I store just these values and then I create new gems, set location, type, size and score with one function that sets all the other relevant parameters of that gem to align with stored info, and call it after making a gem with new Gem(). Your items might too be only worthy of a class name and ID in the class table, so store these with slot numbers and create objects that will have all their properties already set.

Creating a user generated list in flash

I'm trying to create a flash application that will keep track of user generated values. The app should basically allow the user to input the name of the item and it's cost. The total costs should then be added up to show a total value to the user. I can probably figure out how to add the values together, but I'm not really sure how to allow the user to create a list and then allow the user to save it. Can anyone point me towards a tutorial or point me in the right direction?
I am using variables to add user inputed numbers to come up with a total. The first problem is that actionscript 3.0 does not allow variables for texts. I just converted it to 2.0 to fix this. The second problem, is when I test the app and put in my values and click submit, I get NaN in the total values field. Is there a reason why it wouldn't add the values?
Here is the code I used for the submit button:
on (release) {
total = Number(rent) + Number(food) + Number(travel) + Number(entertainment) + Number(bills);
}
Am I missing anything?
Can I give the input text instance names and then give them variables? How are some ways to go about this?
Thanks for the help!
Have an object array, say for example
var stack:Array = new Array();
Then push the item name and it's cost to that array when user inputs, like
stack.push({item:AAA, cost:xx});
So that you can generate the list whenever you want with that array.
You have to see how this works in code. A list in actionscript could be stored inside an array, vector, dictionary or even an Object.
Var myList:Array = [];
myList.push({name: "item 1", cost: 5 });
myList.push({name: "item 2", cost: 7.5 });
If you want to grab the 'product' of "item 1" from the list, you have to create a function for that, lets call it getProductByName
function getProductByName(name:String):Object
{
for each(var product:Object in myList)
{
if (product.name === name) return product;
}
return null; // no match found
}
You can call that function like this:
var product = getProductByName("item 1");
trace(product.cost); // 5
And you can alter the product, so lets make it more expensive
product.cost += 1;
trace(product.cost); // 6
Have fun! If you are using classes, you would create one for the product, with public name and cost, and in that case you'de better use a vector, to ensure working with the right type.
This is what fixed the issue for me in action script 3.0:
myButton.addEventListener(MouseEvent.CLICK, addThem);
function addThem(e:MouseEvent)
{
totalField.text = String ( Number(field1.text) + Number(field2.text) + ....);
}
I also had to name the instances appropriately.