Can anyone help me how to access a data from an fla file to another fla file? - actionscript-3

Can anyone help me how to access a data from an fla file to another fla file?
I have a starting fla file called "savescore.fla" which is connected to the class called "score.as".I have a "btnAdd" button that if clicked, it will add by one to the variable "scoring" in the class "score.as". I have also a movieclip "btnSave" that would save the score. Lastly, I have a "next_btn" button that would go directly to my another fla file
which is "finalscore.fla". I wanted the "finalscore.fla" to show the current "scoring" variable from the "score.as" class but the problem is that it will only show 0/zero as the score. I think that as "savescore.fla" saves and edits the variable in the "score.as", it will only make changes to itself and not to the "score.as" that's why I still got 0 as the final score because it comes from the "score.as" and not from "savescore.fla". So I was thinking if I could just access the score from the "savescore.fla", it would solve the problem. But I have no idea what codes to put...or can you give me another way?
Here are the codes: (Btw, I am using actionscript 3.0)
savescore.fla:
var lol:score = new score();
var saveDataObject:SharedObject;
//var currentScore:int;
init(); // this line goes directly beneath the variables
function init():void{ // call once to set everything up
saveDataObject = SharedObject.getLocal("test"); // give the save data a location
btnAdd.addEventListener(MouseEvent.CLICK, addScore); // clicking on +1
btnSave.addEventListener(MouseEvent.CLICK, saveData); // clicking on Save
next_btn.addEventListener(MouseEvent.CLICK, sunod); // clicking on +1
if(saveDataObject.data.savedScore == null){ // checks if there is save data
trace("No saved data yet."); // if there isn't any data on the computer...
saveDataObject.data.savedScore = lol.scoring; // ...set the savedScore to 0
} else {
trace("Save data found."); // if we did find data...
loadData(); // ...load the data
}
}
function addScore(e:MouseEvent):void{
lol.scoring+=1; // add 1 to the score
}
function saveData(e:MouseEvent):void{
saveDataObject.data.savedScore = lol.scoring; // set the saved score to the current score
trace("Data Saved!");
saveDataObject.flush(); // immediately save to the local drive
trace(saveDataObject.size); // this will show the size of the save file, in bytes
trace(lol.GetFullScore());
}
function loadData():void{
lol.scoring = saveDataObject.data.savedScore; // set the current score to the saved score
trace("Data Loaded!");
}
function sunod(event:MouseEvent):void{
var ldr:Loader=new Loader();
ldr.load(new URLRequest("finalscore.swf"));
addChild(ldr);
}
score.as:
package{
public class score{
public var scoring:int;
function score()
{
}
public function SetScore(val:int):void
{
scoring = val;
}
public function GetFullScore():int
{
return scoring;
trace(scoring);
}
}
}
finalscore.fla:
var lol1:score = new score();
txtScore.text = ("Score: " + lol1.GetFullScore()); // set the text property of the txtScore
trace(lol1.GetFullScore());

Once you have loaded an external swf you can grab a reference to it in an onLoadedHandler. So in savescore:
var myReference:Object;
function loadComplete(event:Event):void {
myReference= event.target.content;
myReference.lol1.GetFullScore();
... or...
var myScore = event.target.lol1.GetFullScore();
etc...
}
you'll want to make sure the reference exists before you use it
EDIT
in your Child SWF create a variable and method to store the parent:
var parentSWF:MovieClip;
function setParent(myParent:MovieClip):void{
parentSWF = myParent;
}
then in the parent send the child a reference :
function loadComplete(event:Event):void {
myReference= event.target.content;
// use the reference to child to call
// any variables or functions in it
myReference.lol1.GetFullScore();
// set the reference in child with the following
// so that the child can call the parent
myReference.setParent(this);
}
then in child you can use lol :
parentSWF.lol;
If you had to go this way you would ideally create measures to check the objects/methods etc exist before they are used
FINAL EDIT
For a start, move
var ldr:Loader=new Loader();
out of the sunod function and put it at the top with the other declaration so that loadcomplete can use it. You need to set up a listener for the loadComplete handler. Put this after your other listeners
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
in your loadcomplete handler in savescore add
myReference.doThisWhenLoaded();
in finalscore put
function doThisWhenLoaded():void{
txtScore.text = ("Score: " + parentSWF.lol);
}
This just seems complete overkill and I'm sure I've overcomplicated your over complications(!). My advice would be to do away with the second swf and just create a finalscore.as object in savescore. This would be so much easier. At the moment I can't see why you want to have another swf floating around. I've never been a fan of multiple swfs though so someone else may well jump in and correct this.

Here's the changes of my code:
savescore.fla:
var lol:score = new score();
var saveDataObject:SharedObject;
init(); // this line goes directly beneath the variables
function init():void{ // call once to set everything up
saveDataObject = SharedObject.getLocal("test"); // give the save data a location
btnAdd.addEventListener(MouseEvent.CLICK, addScore); // clicking on +1
btnSave.addEventListener(MouseEvent.CLICK, saveData); // clicking on Save
next_btn.addEventListener(MouseEvent.CLICK, sunod); // clicking on +1
if(saveDataObject.data.savedScore == null){ // checks if there is save data
trace("No saved data yet."); // if there isn't any data on the computer...
saveDataObject.data.savedScore = lol.scoring; // ...set the savedScore to 0
} else {
trace("Save data found."); // if we did find data...
loadData(); // ...load the data
}
}
function addScore(e:MouseEvent):void{
lol.scoring+=1; // add 1 to the score
}
function saveData(e:MouseEvent):void{
saveDataObject.data.savedScore = lol.scoring; // set the saved score to the current score
trace("Data Saved!");
saveDataObject.flush(); // immediately save to the local drive
trace(saveDataObject.size); // this will show the size of the save file, in bytes
trace(lol.GetFullScore());
}
function loadData():void{
lol.scoring = saveDataObject.data.savedScore; // set the current score to the saved score
trace("Data Loaded!");
}
function sunod(event:MouseEvent):void{
var ldr:Loader=new Loader();
ldr.load(new URLRequest("finalscore.swf"));
addChild(ldr);
}
var myReference:Object;
function loadComplete(event:Event):void {
myReference= event.target.content;
myReference.lol1.GetFullScore();
myReference.setParent(this);
}
finalscore.fla:
var lol1:score = new score();
var parentSWF:MovieClip;
txtScore.text = ("Score: " + parentSWF.lol); // this line has the error because of parentSWF.lol
trace(lol1.GetFullScore());
function setParent(myParent:MovieClip):void{
parentSWF = myParent;
}
score.as:
package{
public class score{
public var scoring:int;
function score()
{
}
public function SetScore(val:int):void
{
scoring = val;
}
public function GetFullScore():int
{
return scoring;
trace(scoring);
}
}
}

Related

dispatch change value and start tween

I try to make simple scorebug. It’s feed from external XML file.
I want to start an animation when score changing, but i doesn’t found event listener or dispatcher to get change of value.
var myTimer:Timer = new Timer(100);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
myTimer.start();
function timerListener (e:TimerEvent):void
{
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("Xml.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
function processXML (e:Event):void
{
var myXML:XML = new XML(e.target.data);
ShotClock.text = myXML.timestamp;
GameClock.text = myXML.Clock;
HS.HomeScore.text = myXML.HomeScore;
AS.AwayScore.text = myXML.AwayScore;
Period.text = myXML.Period;
AwayTeam.text = myXML.AwayName;
HomeTeam.text = myXML.HomeName;
}
if ( (myXML.HomeScore).CHANGE )
{ var myTween:Tween = new Tween(HS.HomeScore, "alpha", Strong.easeIn, 0, 1, 1, true); }
}
You need to change the logic of loading. Instead of starting timed loadings, which won't be accurate 100 ms anyway, could lag, could fail, could arrive in order other than you issued them, etc., you need a single-thread asynchronous loop that does, simply, the following:
Start data loading.
(async pause)
Handle the loaded data.
Get XML data from loaded text.
Parse XML attributes.
Check if the score variable changed and trigger the things you want to.
Wait 100 ms.
(async pause)
Go to step №1.
Something like that:
var theLoader:URLLoader;
var theScore:Number = 0;
var theTimer:Timer;
// Start the tracking routine.
trackNext();
function trackNext():void
{
theLoader = new URLLoader;
theLoader.addEventListener(Event.COMPLETE, onXML);
// Error tracking is a must or the logic flow
// might just stop when you least expect it to.
theLoader.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 0, true);
theLoader.load(new URLRequest("xml.xml"));
}
function onXML(e:Event):void
{
// Sanity check. There should be only one valid URLLoader instance.
if (e.target != theLoader)
{
return;
}
var X:XML;
try
{
X = new XML(theLoader.data);
}
catch (fail:Error)
{
// Processing the case where data is loaded successfully,
// but it is not a valid XML String.
onError(e);
return;
}
// Here's the place for your code
// that extracts data from XML.
// ...
// Get the new score value.
var aScore:Number = X.HomeScore;
// Compare it to previous value.
if (aScore != theScore)
{
// ATTENTION!!! THIS IS THE PLACE YOU ARE LOOKING FOR!!!
// Trigger things if the new score is any different.
// ...
// Keep the new score value.
theScore = aScore;
}
finishLoading();
}
// This method just ignores an error, think of it
// as of blank to process the exceptional cases.
function onError(e:Event):void
{
// Sanity check. There should be only one valid URLLoader instance.
if (e.target != theLoader)
{
return;
}
finishLoading();
}
// Call it finishLoading(true) to stop the tracking routine.
function finishLoading(thenstop:Boolean = false):void
{
// Dispose of the URLLoader instance if any.
if (theLoader)
{
var aLoader:URLLoader = theLoader;
theLoader = null;
aLoader.removeEventListener(Event.COMPLETE, onXML);
try
{
aLoader.close();
}
catch (fail:Error)
{
// Do nothing about it.
}
}
finishTimer();
if (thenstop)
{
return;
}
// Wait 100 ms to give Flash Player a breather
// before starting to load the file once more.
theTimer = new Timer(100, 1);
theTimer.addEventListener(TimerEvent.TIMER, onTime);
theTimer.start();
}
function finishTimer():void
{
// Dispose of the Timer instance if any.
if (theTimer)
{
theTimer.removeEventListener(TimerEvent.TIMER, onTime);
theTimer.stop();
theTimer = null;
}
}
function onTime(e:TimerEvent):void
{
// Now go for the next iteration.
finishTimer();
trackNext();
}

Score not adding properly ActionScript3

I have this score counter for my project but instead of adding +1 or subtracting -1, it'll subtract 2 and add 7. This is the code I'm using.
I have it so one page has two buttons (startBTN and endBTN) and when you click on startBTN, it will load another swf on top of this swf and add one point. However, when it does this, it adds 7 points. The other button is meant to subtract one point and pull up that respective swf and instead subtracts 2.
I have tried this on a separate page and it will subtract 4 instead of 2 even if they aren't linked together.
var saveDataObject:SharedObject;
var currentScore:int;
init(); // this line goes directly beneath the variables
function init():void{ // call once to set everything up
saveDataObject = SharedObject.getLocal("test"); // give the save data a location
currentScore = 0; //start with 0 score
startBTN.addEventListener(MouseEvent.CLICK, addScore); // clicking on +1
endBTN.addEventListener(MouseEvent.CLICK, subtractScore); // clicking on Save
function addScore(e:MouseEvent):void{
currentScore += 1; // add 1 to the score
updateScoreText(); // update the textfield
}
function subtractScore(e:MouseEvent):void{
currentScore -= 1; // add 1 to the score
updateScoreText(); // update the textfield
}
function saveData(e:MouseEvent):void{
saveDataObject.data.savedScore = currentScore; // set the saved score to the current score
trace("Data Saved!");
saveDataObject.flush(); // immediately save to the local drive
trace(saveDataObject.size); // this will show the size of the save file, in bytes
}
function loadData():void{
currentScore = saveDataObject.data.savedScore; // set the current
score to the saved score
trace("Data Loaded!");
//return currentScore;
}
function updateScoreText():void
{
txtScore.text = "Score: " + String(currentScore); // set the text property of the txtScore
trace(currentScore);
}
if(saveDataObject.data.savedScore == null){ // checks if there is save data
trace("No saved data yet."); // if there isn't any data on the computer...
saveDataObject.data.savedScore = currentScore; // ...set the savedScore to 0
} else {
trace("Save data found."); // if we did find data...
loadData(); // ...load the data
}
//updateScoreText(); // finally, update the text field
}

Implicit Coercion of a value of a type of text.flash:TextField to an unrelated Int

Okay, so I'm trying to create a mobile flash game (I'm mostly an animator, a storyteller) and I'm having trouble with the input text for the player name. I've often read helpful tips on this site so I signed up to get some help. The code I use to load and save data is saveDataObject, But as far as I know input text has to be used with package code. I tried to convert it to function var, but then these errors occur. I am unsure how to use the Package class code, and everything I've read on it has been confusing. I am pretty much self taught for everything I know about code though tutorials and forums, so if it isn't explained in a way I can understand I wont be able to do it...
Here's the section of code if I wasn't clear(error lines separate):
var playerName:int;
init(); // this line goes directly beneath the variables
function f_1(init):void
{ // call once to set everything up
saveDataObject = SharedObject.getLocal("DataBattle/character/name"); // give the save data a location
-
playerName = txtPlayer;
-
function addName(e:TouchEvent):void
{
var myTextBox1:TextField = new TextField();
var txtPlayer:TextField = new TextField();
var myText:String = "Cyan";
function CaptureUserInput()
{
captureText();
}
function captureText():void
{
myTextBox1.type = TextFieldType.INPUT;
myTextBox1.background = true;
addChild(myTextBox1);
myTextBox1.text = myText;
myTextBox1.addEventListener(TextEvent.TEXT_INPUT, textInputCapture);
}
function textInputCapture(event:TextEvent):void
{
var str:String = myTextBox1.text;
createOutputBox(str);
}
function createOutputBox(str:String):void
{
txtPlayer.background = false;
txtPlayer.x = 200;
addChild(txtPlayer);
txtPlayer.text = str;
}
-
if(saveDataObject.data.characterName = playerName == null)
-
{ // checks if there is save data
trace("No Player data yet."); // if there isn't any data on the computer...
saveDataObject.data.characterName = playerName; // ...set the savedScore to 0
}
else
{
trace("Player data found."); // if we did find data...
loadData1(); // ...load the data
}
function loadData1():void
{
playerName = saveDataObject.data.characterName; // set the current score to the saved score
trace("Data Loaded!");
}
}
}
function saveData(e:TouchEvent):void
{
saveDataObject.data.characterName = playerName; // set the saved score to the current score
trace("Data Saved!");
saveDataObject.flush(); // immediately save to the local drive
trace(saveDataObject.size); // this will show the size of the save file, in bytes
}
Would be nice to have some more details about this error. Like which line is actually throwing this error.
However even without it there are few things that looks weird right away.
var playerName:int;
// And few lines below
playerName = txtPlayer;
// Few more lines below
var txtPlayer:TextField = new TextField();
Looks like you're declaring playerName as int so you want to store numeric values, but then txtPlayer is a TextField. So by playerName = txtPlayer; you're trying to store TextField as Int value, which is not gonna work.
I can also see
if(saveDataObject.data.characterName = playerName == null)
and it's like :O
I'm not even sure how this part is being compiled. You want to do playerName == null check (which would return true/false) and then assign it to saveDataObject.data.characterName ?

How to use remote SharedObject in AS3 and Red5

I wish to use remote SharedObject so I created a simple script to test out the techniques. When I ran the following code as two instances of SWF, both instances output 1, which was incorrect because the second instance was supposed to output 2.
import flash.net.SharedObject;
import flash.events.SyncEvent;
var nc:NetConnection;
var so:SharedObject;
nc = new NetConnection();
nc.client = { onBWDone: function():void{} };
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.connect("rtmp://localhost:1935/live");
var t = new TextField();
addChild(t);
function onNetStatus(event:NetStatusEvent):void{
if(event.info.code == "NetConnection.Connect.Success"){
so = SharedObject.getRemote("shObj",nc.uri);
so.connect(nc);
if (!(so.data.total > 0 && so.data.total<1000)) {// undefined
so.data.total=1;
} else so.data.total=2;
t.text=so.data.total;
}
}
Did I miss out something? Do I need to make some special settings to Flash or Red5? Do I need to create a special directory? Must I use a special event listener? Could anyone correct the code for me?
(09 Apr 2014)
When I used an event listener like the following, I got a blank screen for both instances, which was strange because I expected at least the second screen to show '2'. Can someone explain the behavior?
import flash.net.SharedObject;
import flash.events.SyncEvent;
var nc:NetConnection;
var so:SharedObject;
nc = new NetConnection();
nc.client = { onBWDone: function():void{} };
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.connect("rtmp://localhost:1935/live");
var t = new TextField();
addChild(t);
function onNetStatus(event:NetStatusEvent):void{
if(event.info.code == "NetConnection.Connect.Success"){
so = SharedObject.getRemote("shObj",nc.uri);
so.addEventListener(SyncEvent.SYNC,syncHandler);
so.connect(nc);
so.setProperty("total",2);
}
}
function syncHandler(event:SyncEvent):void{
if (so.data.total) {
t.text = so.data.total;
}
}
Basically for the use of Shared Objects, I would recommend splitting the job into three seperate parts.
Attach Event Listener and connect to the Shared Object
function onNetStatus(event:NetStatusEvent):void
{
if(event.info.code == "NetConnection.Connect.Success")
{
so = SharedObject.getRemote("shObj",nc.uri);
so.addEventListener(SyncEvent.SYNC,syncHandler); //add event listener for Shared Object
so.connect(nc);
}
}
Complete the Event Handler method to reflect changes in the value of Shared Object
/* This function is called whenever there is change in Shared Object data */
function syncHandler(event:SyncEvent):void
{
if(so.data.total) //if total field exists in the Shared Object
trace(so.data.total);
}
Change the data in Shared Object:
Use the setProperty method of Shared Object here. Invoke this method when you need to change the value (maybe at button click or on occurrence of certain Event)
/* This function writes values to the Shared Object */
function changeValue(newValue:String)
{
so.setProperty("total",newValue);
}

accordion menu error 1010

I'm trying to create an accordion menu off of an online tutorial. I followed every step (i think) on Original Tutorial but changed things according to my size, as well as make the instance names end with _mc or _txt accordingly. But for some reason it doesn't seem to be working.
I'm getting the #1010 error and it doesn't really clarify anything:
TypeError: Error #1010: A term is
undefined and has no properties.
at
tutorial_fla::MainTimeline/placeItemsOnStage()
at
tutorial_fla::MainTimeline/onComplete()
at
flash.events::EventDispatcher/dispatchEventFunction()
at
flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
I have my first xml file that has all the images to insert and that one hasn't been changed at all should work fine.
I know this is long, but I'm hoping someone can check it out anyhow. I'm extremely new to this and would pretty much have to abandon the whole project. Thanks so much!
my code:
//import tweenlite classes
import gs.TweenLite;
import gs.easing.*;
var MENU_ARRAY:Array; //used to save the items data
var OPENED_MENU:int; //to inform the menu that should be open at startup
var MOVE_ON_MOUSE_OVER:Boolean=false; //tha name says everything
var xmlLoader:URLLoader; //the xml loader
loadXML("menu2.xml"); //load the xml
function loadXML(Uri:String):void {
xmlLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, onComplete);
xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
xmlLoader.load(new URLRequest(Uri));
}
function onError(evt:ErrorEvent):void {
trace("cannot load xml file");
}
function onComplete(evt:Event):void {
//read and load xml into array, by parsing it using prepareMenu
MENU_ARRAY=prepareMenu(xmlLoader.data.toString());
placeItemsOnStage(); //place all required items on stage.
}
function placeItemsOnStage():void {
var pos:Number=0;
//define the container properties
menuContainer_mc.x=0;
menuContainer_mc.y=0;
for(var c:int=0; c<MENU_ARRAY.length; c++) {
var it:menuItem = new menuItem; //load out menuItem, because its exported to AS, we can use it here
it.x=c*51; //its the gray border width
it.y=0; //place on top
it.id="Item-"+c; //id the menuItem
it.name="Item-"+c; //name de menuItem
it.posX=pos; //actual pos, useful to open and know is position
it.itemLabel_txt.text=String(MENU_ARRAY[c].Ititle).toUpperCase(); //load the label in uppercase
it.addEventListener(MouseEvent.CLICK, onMouseClick); //add mouse click listener
if(MOVE_ON_MOUSE_OVER==true) it.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); //if configured, load the mouse over event
it.useHandCursor=true; //use hand cursor
it.buttonMode=true; //buttonMode
it.itemText_txt.visible=false; //hide the textField
menuContainer_mc.addChild(it); //add the menu item as child
if(String(MENU_ARRAY[c].IcontentType)=="image/swf") { //check the content and load things accordint to it
var ldr:Loader = new Loader();
ldr.x=51;
ldr.y=0;
it.addChild(ldr);
ldr.load(new URLRequest(MENU_ARRAY[c].IcontentData.toString()));
}
else if(String(MENU_ARRAY[c].IcontentType)=="text") {
it.itemText_txt.visible=true;
it.itemText_txt.text=MENU_ARRAY[c].IcontentData.toString();
}
pos+=51; //the next menuItem x position
}
//put mask in place
masker_mc.width=(MENU_ARRAY.length*51+700)
masker_mc.height=menuContainer_mc.height;
masker_mc.x=0;
masker_mc.y=0;
moveItem(OPENED_MENU-1); //open menu confirured in XML
}
function onMouseOver(evt:MouseEvent):void {
if(evt.target.name.toString()=="buttonBack") prepareMove(evt)
}
function prepareMove(evt:MouseEvent):void {
var targetName:String = evt.currentTarget.name.toString(); //get the menuItem
var temp:Array = targetName.split("-"); //split his name: Item-x
var itemNumber:int=(temp[1]); //got item number
moveItem(itemNumber); //move it
}
function onMouseClick(evt:MouseEvent):void {
if(evt.target.name.toString()=="buttonBack") prepareMove(evt); //mouse action was done in buttonBack
else trace("Item "+evt.currentTarget.name+" clicked!"); //mouse action was made on accordion area
}
function moveItem(num:int):void {
var itemToMove:menuItem=menuContainer_mc.getChildByName("Item-"+String(num)) as menuItem;
//get the menuItem child
for(var m=0;m<MENU_ARRAY.length;m++) //move one-by-one to the new position
{
var tempMc = menuContainer_mc.getChildByName("Item-"+m);
if(tempMc.x > itemToMove.x) TweenLite.to(tempMc, 1, {x:((tempMc.posX) + itemToMove.width-51), ease:Quart.easeOut}); //see tweenLite for info about this.
else if(tempMc.x <= itemToMove.x) TweenLite.to(tempMc, 1, {x:(tempMc.posX), ease:Quart.easeOut});
}
}
function prepareMenu (XMLData:String):Array
{
//make sure it cames in XML
var menuXML:XML = new XML(XMLData);
//just in case
menuXML.ignoreWhitespace = true;
//get XML item's entrys
var XMLItems = menuXML.descendants("item");
//load all items into an array
var itemsArray:Array = new Array();
var itemObj:Object;
for(var i in XMLItems)
{
itemObj=new Object();
itemObj.Ititle=XMLItems[i].#Ititle;
itemObj.IcontentType=XMLItems[i].#IcontentType;
itemObj.IcontentData=XMLItems[i].#IcontentData;
itemObj.itemID="menu"+i;
itemsArray.push(itemObj);
}
OPENED_MENU=menuXML.#menuOpen; //get menu for open.
MOVE_ON_MOUSE_OVER=(menuXML.#moveOnMouseOver.toString()=="true" ? true : false); //get the option for load or not mouseOver open
return itemsArray;
}
//finish.
stop();
"term" refers to an identifier, "Error #1010: A term is undefined and has no properties" means you are using an expression which cannot be evaluated. This usually happens when you try to access and use an undefined object property via its string name as in myobject["property"].method(). Can you provide the exact line on which the exception is raised?