Reference Shared Object AS3 - actionscript-3

I am trying to reference a shared object (one that saves data), but whenever I try to, I get a crash.
This code works fine:
var var1:Object = { value:1 };
var varRef:Object = var1;
if(var1.value == 1) {
varRef.value = 50;
}
trace(varRef.value); // outputs 50;
trace(var1.value); // outputs 50;
But when I try to use shared objects, it doesn't work.
import flash.net.SharedObject;
var iapso:SharedObject = SharedObject.getLocal("purchases");
var varRef:Object = iapso.data.testing;
varRef = 90
trace ("The shared value is " + iapso.data.testing);
trace ("This should mirror it" + varRef);
If you're able to figure out the issue, please post a fixed version.
Thanks.

You must come from a programming background where pointers can be dereferenced.
In this case, varRef is not varRef = &iapso. Setting its value does not change the value of iapso.data.testing;
Initially, you set varRef as a pointer to iapso.data.testing:
var varRef:Object = iapso.data.testing;
Then, you immediately change it to a constant value object literal 90:
varRef = 90;
This does not set the value of testing to 90 - this changes the value of varRef.
You could set varRef to iapso.data, then set testing as in:
var varRef:Object = iapso.data;
varRef.testing = 90;
Then, the following would produced expected results:
trace(iapso.data.testing); // 90
trace(varRef.testing); // 90

setting varRef will not update the value in iapso.data - numbers are copied, not referenced.
var bar:Object = { data:1 };
var foo:Object = bar.data;
trace(foo); //"1"
bar.data = 2;
trace(foo); //"1"
If you really want to use a reference, use data instead, eg:
import flash.net.SharedObject;
var iapso:SharedObject = SharedObject.getLocal("purchases");
var varRef:Object = iapso.data;
varRef.testing = 90
trace ("The shared value is " + iapso.data.testing);
trace ("This should mirror it" + varRef.testing);

Related

AS3 - Using a For Loop to Update Multiple Points and Their Values in an Array

I'm a bit new with AS3 (but not really with coding) so please forgive my ignorance. I'm creating a small function that will be called by a Main Function to update the position of 52 Pointers that have the x and y position of multiple point objects (empty movie clips). It will also then update two global arrays with those values (one array for the x and one for the y).
The problem is, as there are 52 of them, and they will probably grow in quantity, I'd like to be able to use a FOR function to do it, but I can't seem to be able to figure it out.
I get this error: Access of undefined property _point.
Here is a piece of the code that dream about:
function happyFunc():void
{
var avpointers:int = 52;
var vpointx:Array = new Array();
var vpointy:Array = new Array();
for (aa=0; aa<vpointers; aa++)
{
vpointx[aa] = _point[aa].x;
vpointy[aa] = _point[aa].y;
}
}
And this is the code that I'm stuck with...
function reallySadFunc():void
{
_point1 = localToGlobal(new Point(point1.x,point1.y));
//...
_point52 = localToGlobal(new Point(point52.x,point1.y));
vpointx[0] = _point1.x;
vpointx[1] = _point2.x;
//...
//oh god there are 104 lines of this why do I have to suffer
}
Thank you!
If I read your question correctly, I think this is what you need:
public static const CLIP_COUNT:int = 52;
// ...
private function happyFunc(parentClip:DisplayObjectContainer):void
{
var vpointx:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var vpointy:Vector.<Number> = new Vector.<Number>(CLIP_COUNT, true);
var clipPoint:Point = new Point ();
var globalPoint:Point;
for (var i:int = 0; i < CLIP_COUNT; i++)
{
var childClip:DisplayObject = parentClip.getChildByName("point" +
(i + 1).toString());
clipPoint.x = childClip.x;
clipPoint.y = childClip.y;
globalPoint = parentClip.localToGlobal(clipPoint);
vpointx[i] = globalPoint.x;
vpointy[i] = globalPoint.y;
}
// do something with vpointx and vpointy - they're local variables
// and will go out of scope unless you declare them as class members
// or somehow return them from this function.
}
This function works by taking the parent display object (the one that contains the 52 movie clips - this could be the Stage) and iterates through them by getting each movie clip by name. The code assumes that your movie clips are called point1, point2, ..., point52.
To speed up the local-to-global coordinate conversion, two Point objects are created and then reused during the for loop to avoid creating many temporary Point instances.
Instead of using Array, use Vector.<Number> - this class has better performance than Array does.

How to get a time as a variable in Flash CS6

I am trying to get a time that is in a text document to become a variable in a Flash CS6 AS3 project. I can't seem to find where the problem is and the error messages aren't really helping. The highlighted parts are the changed lines.
Here is the newest code:
this.onEnterFrame = function()
{
var StartTime:URLLoader = new URLLoader();
StartTime.dataFormat=URLLoaderDataFormat.VARIABLES;
StartTime.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
}
StartTime.load(new URLRequest("ResponseTime.txt"));
var today:Date = new Date();
var currentTime = today.getTime();
var targetDate:Date = new Date();
var timeLeft = e.data - currentTime;
var sec = Math.floor(timeLeft/1000);
var min = Math.floor(sec/60);
sec = String(sec % 60);
if(sec.length < 2){
sec = "0" + sec;
}
min = String(min % 60);
if(min.length < 2){
min = "0" + min;
}
if(timeLeft > 0 ){
var counter:String = min + ":" + sec;
time_txt.text = counter;
}else{
var newTime:String = "00:00";
time_txt.text = newTime;
delete (this.onEnterFrame);
}
}
Newest Error:
1120: Access of undefined property e. (Line 17).
First of all, this does nothing :
var StartTime();
It's not correct AS3 code.
Then, AS3 loaders being asynchronous, you must way for the loader to finish load so you can get your variable. I mean that all your code after StartTime.load(...) must be inside the function onLoaded.
This way, when the loader finish loading, you'll have you variable.
That say, URLVariable is NOT a loader. It is an object you can use to put your variable into, and feed them to a loader.
If you want to download some file, use URLLoader (with URLRequest). On this page, there is a good example on how you can do that (skip the part about the dataFormat, though). The date you're requesting will be available in the data property of the event, eg :
var timeLeft = e.data - currentTime;
I'm not asking where currentTime is from, since it's out of the scope of that question.
Good luck.

display lines in AS3

I am baffled by this function, which is called prior to this with parameters 22 and 58 for xVal ad yVal respectively. It doesn't display anything when the swf is compiled and tested, and it's error free. The code is in the document class:
private function mLine(xVal : int, yVal : int) {
var rCol = 0x0000FF;
var incr = Math.round((Math.random() * 20) + 8);
lns.push(new Shape());
var i = lns.length - 1;
this.addChild(lns[i]);
lns[i].graphics.moveTo(xVal, yVal);
lns[i].graphics.lineStyle(10, rCol);
lns[i].graphics.lineTo(xVal, yVal + 20);
lns[i].name = incr;
trace("lns[" + i + "] x is " + lns[i].x); // outputs 'lns[0] x is 0'
trace("xVal is " + xVal); // outputs 'xVal is 22'
trace("yVal is " + yVal); //outputs 'yVal is 58'
trace(stage.contains(lns[i])); // outputs 'true'
}
Assuming you have declared private var lns = []; somewhere, it draws a blue line (20px straight down from the given position).
It doesn't display anything
That means you probably don't have an object of that class on the stage. In your document class, you should use addChild to display an instance of the class containing mLine. mLine needs to be called somehow obviously. You could do this in the class' constructor, but you'd need to remove the last trace statement to avoid a null pointer error, because stage would be null then.
Edit: Missed that you said it is in the Document class. So, try and see if drawing anything else works. The problem doesn't seem to be with this function.
Your code seems like it should work. I have rewrote it to conform better to ActionScript 3 best practices
private function drawLine(xVal:int, yVal:int):void
{
var lineColor:uint = 0x0000FF;
var lineShape:Shape = new Shape();
//lineShape.name = String(Math.round((Math.random() * 20) + 8));
lineShape.graphics.lineStyle(10, lineColor);
lineShape.graphics.moveTo(xVal, yVal);
lineShape.graphics.lineTo(xVal, yVal + 20);
addChild(lineShape);
lines.push(lineShape);
}
The x and y properties of your shape will both be zero because you never set them. you are just drawing lines inside the shape at the xVal and yVal. You could do the same thing like this:
private function mLine(xVal:int, yVal:int)
{
var lineColor:uint = 0x0000FF;
var lineShape:Shape = new Shape();
//lineShape.name = String(Math.round((Math.random() * 20) + 8));
lineShape.graphics.lineStyle(10, lineColor);
lineShape.graphics.moveTo(0, 0);
lineShape.graphics.lineTo(0, 20);
lineShape.x = xVal;
lineShape.y = yVal;
addChild(lineShape);
lines.push(lineShape);
}
Not sure why its not showing up at all for you though.

Error 1009 cannot access a property----again

Hello I'm stuck on this one which is trying to show a game level on the game and getting an output error 1009. I'm doing something wrong but can't figure. Here is the code:
if ( levelNumber ==1) {
var level:Number = 1;
showLevel.text=level.toString();
showLevel.text = String ("Level: " +level);
if ( levelNumber ==2) {
var level:Number = 2;
showLevel.text=level.toString();
showLevel.text = String("Level: " +level);
var numBombs:Number = 4;
}else if( levelNumber ==3 ) {
var level:Number = 3;
showLevel.text=level.toString();
showLevel.text = String ("Level: " +level);
The debugger says it's the line with showLevel.text=level.toString(); which I have set as a Number ie private var level:Number =0. I hope this is sufficient code to let you know what's going on here. It's also coming up with a duplicate variable definition - compiler error on var level:Number =2 and the next one that =3.Thanking you in advance for any assistance. Cheers.
Error #1009 is indeed a null reference error. I see your level is declared and has a right value.
Maybe the point is that your showLevel object (I guess it's a label) is not declared yet.
The problem can be that you use:
private var showLevel:mx.controls.Label;
instead of:
private var showLevel:mx.controls.Label = new mx.controls.Label();
otherwise if you make your showLevel in a viewStack you must be sure that your content is created yet. Therefor you can use:
<mx:ViewStack id="yourView" creationPolicy="all">

Unloading a Loader with actionscript 3

Hello and thank you very much for looking at this. I've spent too many hours struggling.
The code below loads a slideshow of four images, along with thumbnails for those images. It works fine.
I've added a button called "invis_button", that when pressed is supposed to remove the 3 loaders that make up the slideshow, using the removeChild command for each loader.
But this is the problem, there are 3 loaders involved in the slide-show. The removeChild command successfully removes one of the loaders (named "loader3"), but not the other two ("container3", and "thumbLoader3"). It returns an error stating "access of undefined property thumbLoader3" or "Container3".
Can someone tell me why this is ? Or better still, how to make that button (invis_button) unload the entire slide-show.
var images3:Array = ["ad_bona1.jpg", "ad_bona2.jpg", "ad_darkhawk1.jpg", "ad_darkhawk2.jpg"];
var thumbX3:Number = -375;
var thumbY3:Number = 220;
var loader3:Loader = new Loader();
loader3.load(new URLRequest("assets/ad_bona1.jpg"));
addChild(loader3);
loader3.alpha = 0;
loadThumbs3();
function loadThumbs3():void
{
var thumbLoader3:Loader;
var container3:Sprite = new Sprite();
addChild(container3);
container3.buttonMode = true;
for(var i3:uint = 0; i3 < images3.length; i3++)
{
thumbLoader3 = new Loader();
thumbLoader3.load(new URLRequest("assets/thumbs/" + images3[i3]));
thumbLoader3.x = thumbX3;
thumbLoader3.y = thumbY3;
thumbX3 += 85;
container3.addChild(thumbLoader3);
thumbLoader3.addEventListener(MouseEvent.CLICK, thumbClicked3);
}
}
function thumbClicked3(event:MouseEvent):void
{
var path3:String = event.currentTarget.contentLoaderInfo.url;
path3 = path3.substr(path3.lastIndexOf("/") + 1);
loader3.load(new URLRequest("assets/" + path3));
}
///PROBLEM BELOW, button removes only "loader3" and not the other two for some reason
invis_button.addEventListener(MouseEvent.CLICK, unload_loaders);
function unload_loaders(event:MouseEvent):void{
removeChild(loader3);
removeChild(thumbLoader3);
removeChild(container3);
}
Not sure if this is the entire reason behind what you're observing... but for starters, "thumbloader3" and "container3" are scoped locally to the loadThumbs3() method, which means once you finish executing the function, Flash's handles to those objects are lost (not to mention being in an entirely different scope)... try creating class-level properties for those two. Once that's done you should be able to successfully remove them from the stage later on.
I hope that you're also properly destroying your objects, and for the sake of brevity you just chose to omit that code above.
I've edited the code you had above & put the properties into the proper scope. (the multiple copies of thumbLoader3 are now collected inside of a vector (specialized array) so that they can be properly addressed when it comes time to destroy them)
I also wrote you a proper destroy method. ;)
I haven't tried it on my own machine, but give it a spin & see how it goes.
var images3:Array = ["ad_bona1.jpg", "ad_bona2.jpg", "ad_darkhawk1.jpg", "ad_darkhawk2.jpg"];
var thumbX3:Number = -375;
var thumbY3:Number = 220;
// begin new instance properties..
// created a new property, allowing you to group (and hold on to) the multiple thumbLoaders
var thumbLoader3Vector:Vector.<Loader> = new Vector.<Loader>();
var container3:Sprite;
// end new instance properties
var loader3:Loader = new Loader();
loader3.load(new URLRequest("assets/ad_bona1.jpg"));
addChild(loader3);
loader3.alpha = 0;
loadThumbs3();
function loadThumbs3():void
{
// this is where container3 used to be declared
container3 = new Sprite();
addChild(container3);
container3.buttonMode = true;
for(var i3:uint = 0; i3 < images3.length; i3++)
{
var tPtr:int = thumbLoader3Vector.length;
thumbLoader3Vector.push(new Loader());
// this is where thumbLoader3 used to be declared & instantiated
thumbLoader3Vector[tPtr].load(new URLRequest("assets/thumbs/" + images3[i3]));
thumbLoader3Vector[tPtr].x = thumbX3;
thumbLoader3Vector[tPtr].y = thumbY3;
thumbX3 += 85;
container3.addChild(thumbLoader3Vector[tPtr]);
thumbLoader3Vector[tPtr].addEventListener(MouseEvent.CLICK, thumbClicked3);
}
}
function thumbClicked3(event:MouseEvent):void
{
var path3:String = event.currentTarget.contentLoaderInfo.url;
path3 = path3.substr(path3.lastIndexOf("/") + 1);
loader3.load(new URLRequest("assets/" + path3));
}
///PROBLEM BELOW, button removes only "loader3" and not the other two for some reason
invis_button.addEventListener(MouseEvent.CLICK, unload_loaders);
function unload_loaders(event:MouseEvent):void{
// since the thumbLoader3 Loaders are children of container3 in the display list, we need to remove them first
for(var $i:uint = 0;$i<thumbLoader3Vector.length;$i++)
{
removeChild(thumbLoader3Vector[$i]);
// also make sure you remove the listener, so that the object will be picked up by garbage collection
thumbLoader3Vector[$i].removeEventListener(MouseEvent.CLICK, thumbClicked3);
}
// and then just set the entire vector to null
thumbLoader3Vector = null;
// remove the loader3 object & set it to null
removeChild(loader3);
loader3 = null;
// remove the container3 object & set it to null
removeChild(container3);
container3 = null;
}