AS3 count the number of flashVars before entering if statement - actionscript-3

I am creating a simple image viewer using AS3 and getting image URLs from flashVars in the HTML. I want to use an if
argument to have it perform one function if there is only one flashVar and another if there are more.
I have it reading the flashVars fine and can write if statments all day long, the trouble I am having is counting the number
of flashVars being passed from the HTML. here is a real dumbed down version of what I am trying to do (which doesnt work
because I can not figure out the correct process to follow):
var numberOfVars:Number = 0; // to store the number of flashVars
var paramObj:Object = LoaderInfo(this.root.loaderInfo).parameters; //get the flashVars
for each (paramObj in LoaderInfo(this.root.loaderInfo).parameters){
numberOfVars + 1;
}
var tf:TextField = new TextField();
addChild(tf);
tf.text = numberOfVars.toString(); // this returns '0' when runningn this code
if (numberOfVars < 2){
//do this
}
else {
//do this
}
thanks for your help guys.
Chris

You would want to increment numberOfVars
Looks like you have this:
numberOfVars + 1;
When you should have this:
numberOfVars++;
which is just short way of writing this:
numberOfVars = numberOfVars + 1;
or this:
numberOfVars += 1;

Just use a for(key in object) loop to track the amount of vars stored on root.loaderInfo.parameters.
var fvars:Object = root.loaderInfo.parameters;
var n:int = 0;
for(var i:String in fvars) n ++;
// n holds the amount of flashvars
if(n <= 1)
{
// one or no variables found
}
else
{
// more than one found
}
Also, you've done one of your operators wrong:
for each(paramObj in LoaderInfo(this.root.loaderInfo).parameters)
{
numberOfVars + 1; // <<<<<< here
}
You're looking for one of the following:
numberOfVars ++;
numberOfVars += 1;
numberOfVars = numberOfVars + 1;

I will offer a slightly different take on the conditional logic here. Instead of reacting to variables based on how many there are (introducing plenty of opportunity for unpredictable results) - why not base your conditional statements on what the vars actually are. This is my standard flashVar process:
var _loadParams:Object
private function init():void
{
_loadParams = new Object();
_loadParams = LoaderInfo(stage.loaderInfo).parameters;
someVar = String( parseParam( "someVar", "default value") );
}
private function parseParam(name:String, defaultValue:String):String
{
if (_loadParams.hasOwnProperty(name) && _loadParams[name] != "" && _loadParams[name] != "undefined")
{
return _loadParams[name];
}
else
{
return defaultValue;
}
}
This, obviously, is just testing for the presence of a value, but it could be easily altered to call some functionality based on those results:
if (_loadParams.hasOwnProperty(name) && _loadParams[name] != "" && _loadParams[name] != "undefined")
{
switch (name){
case 'param1':
doSomthing(name);
break;
case 'param2':
doSomthingElse(name);
break;
}
}
I don't know what you are trying to achieve, and this may be way off. But I thought I'd chime in ;)
Cheers!

Related

HitTest Function with two parameters not initializing

Hey guys so Basically what I'm trying to do is when my player collides with all 5 of the points MovieClips in an array and the Goal Movie Clip i want a text to appear saying "Perfect. But i cant quite accomplish this. I set up the function and it seems like it would but i think what might be wrong is the hitTest with all the Movie clips in the array.
Here is how i set it up:
This is in my loop Function:
private function gameLoop(e:Event):void
{
perfectTextFunction();
}
This is the function:
private function perfectTextFunction():void
{
if (player.hitTestObject(mcGoal_1 && points))
{
trace("perfect Text");
mcPerfect = new perfectText();
mcPerfect.x = (stage.stageWidth / 2);
mcPerfect.y = (stage.stageHeight/ 2);
stage.addChild(mcPerfect);
}
}
The Trace doesn't pick anything up.
Here is how the points are added to the stage if needed:
public function addPointsToStage():void
{
for (var i = 0; i < nPoints; i++)
{
trace(aPointsArray.length);
points = new mcGainPoints();
stage.addChild(points);
points.x = startPoint.x + (xSpacing * i);
points.y = startPoint.y - (ySpacing * i);
aPointsArray.push(points);
}
}
Please any help would be appreciated! THank you!
VESPER here is how I made the NESTED LOOP:
//If all points are hit then Perfect Hit Text
if (player.hitTestObject(mcGoal_1 || mcGoal_2))
{
var weHitAll:Boolean = true;
for (var s in aPointsArray)
{
weHitAll = weHitAll && player.hitTestObject(aPointsArray[s]);
if (!weHitAll)
break;
}
if (weHitAll)
{
trace("perfect Hit");
mcPerfect = new perfectText();
mcPerfect.x = (stage.stageWidth / 2);
mcPerfect.y = (stage.stageHeight/ 2) - 80;
stage.addChild(mcPerfect);
nScore += 25;
updateHighScore();
}
}
var weHitAll:Boolean=true;
for (var s in aPointsArray) {
weHitAll = weHitAll&&player.hitTestObject(aPointsArray[s]);
if (!weHitAll) break; // missed one, drop cycle
}
if (weHitAll) {
trace('Perfect hit!');
... // etc
}
Function hitTestObject accepts only a single object as parameter, in order to check against an array you need to iterate through it, checking against one object at a time (here it's in aPointsArray[s]).

How can I check if an array contains another array?

At first sight it's very simple, but I'm having some problems to do this without using a lot of nested loops.
Example:
var father:Array = new Array(0,1,2,3,4,5);
var son:Array = new Array(3,4,5);
father.contains(son) // returns true or 4(the starting index if the contained array)
ActionScript 3 actually supports some slightly crazy stuff, due to the fact that, in the early days, Adobe/Macromedia were trying to make it compliant with Ecmascript.
So... you can do this:
var a1:Array = [1,2,3,4,5,6,7,8,9];
var a2:Array = [3,4,5];
// borrow String's indexOf function, and it magically works on Arrays
// but rename it because Array already has a different indexOf function
a1.indexOf2 = String.prototype.indexOf;
trace(a1.indexOf2(a2) > -1); // true
But you need to be a little bit careful because it will convert all the elements to Strings for the equality test. For primitives, it mostly won't matter but it will break badly with objects as they'll all be converted to "[object Object]" or to whatever their toString() returns.
Also, if you wanted to use the actual index for anything, rather than just checking it's not -1, you have to divide by two, as the number is double what you'd expect. I don't exactly know why this is :)
If you need something more general and reliable, you'd be better off writing a function to do an explicit search. This is a quick example, which I just wrote so could easily be bug-ridden:
public function find(haystack:Array, needle:Array):int
{
var index:int = -1;
while(index <= haystack.length - needle.length)
{
index++;
index = haystack.indexOf(needle[0], index);
for( var i:int = 1; i<needle.length; i++)
{
if(haystack[index+i] != needle[i])
{
continue;
}
}
if( i == needle.length)
{
return index;
}
}
return -1;
}
Try this for simplicity:
// Determines if an array contains en element (similar to the PHP function with the same name)
public function in_array(needle:*, haystack:Array):Boolean
{
for each (var element:* in haystack)
{
if (element == needle) {return true;}
}
return false;
}

Detect Game Win State in AS3

I'm trying to come up with a clean function that will perform a check on a 2D Array to verify if a win has occurred in a ConnectFour game. I'm trying to work through the logic but my brain is swiss cheese right now. Here's what I have for checking for a horizontal win. It seems to me like there should be a way to streamline this block to work in all possible directions.
private function checkForHorizontalWin(column:uint, row:uint, grid:Array):Boolean
{
var player:uint = grid[column][row];
var counter:uint = 1;
for(var i:uint = Math.min(0, uint(column-1)); i>=0; i--)
{
if(!grid[i][row] || grid[i][row] != player)
{
break;
}
counter++;
}
for(var j:uint = column+1; j<_columns; j++)
{
if(!grid[j][row] || grid[j][row] != player)
{
break;
}
counter++;
}
if(counter >=4)
{
return true;
}
else
{
return false;
}
}
I actually ended up doing something pretty simple...Converted the grid array to a string then look for 4 in a row...Only tricky part was getting the correct array for the diagonal possibilities but I got that worked out too.

Stop and start a for loop in AS3?

I'm pulling an xml and using a for loop to create a thumb list. This list is going to be quite long but I only 25 thumbs to be loaded at a time, so that the next 25 is only loaded when a user hits a button. I know how to set up a for loop in a function, but I can't quite figure out how to break up a loop where it would stop and start. I was thinking I would call the function each time a button is pressed and the loop would pick up where it left off with the next 25.
I thought maybe I could substite other variables into the for(); but everything I've tried breaks it. I tried pulling the var i:int = 0; out of the for so the function could set the i, but I guess I'm not clear on exactly how the for loop works.
What I'm doing:
function loadarticleHeadlines():void
{
for (var i:int = 0; i < egarticleXml.articlelist.articleitem.length(); i++)
{
vsThumb = new articleBox();
vsThumb.alpha = 0;
vsThumbLoader = new Loader();
vsThumbLoader.load(new URLRequest(egarticleXml.articlelist.articleitem[i].articlethumbnail));
articleListContainter.addChild(vsThumb);
vsThumb.articleImage.addChild(vsThumbLoader);
vsThumb.articleTitle.text = egarticleXml.articlelist.articleitem[i].articletitle;
titleAutosize(vsThumb.articleTitle);
vsThumb.x = next_x;
next_x += 260;
articlevsThumb[i] = vsThumb;
//vsThumbLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, showBox);
vsThumb.clickBtn.buttonMode = true;
}
}
Try this out.
var xml:Array = [];
for(var i:int=0;i<100;i++)
{
xml.push(i);
//array from 0-99
}
var xmlPosition:int = 0;
grabXML(xmlPosition);
//25
grabXML(xmlPosition);
//50
grabXML(xmlPosition);
//75
grabXML(xmlPosition);
//100
function grabXML(position:int):void
{
for(position;position<xml.length;position++)
{
trace(xml[position]);
//yields 0-24, 25-49, 50-74, and 75-99
if(position === xmlPosition + 25)
{
break;
}
}
xmlPosition += 25;
}
I'm breaking as soon as the parameter is 25 more than its original value (xmlPosition). Calling the function additional times will yield nothing, as xmlPosition is greater than xml's length property.

AS3 Functions: is it possible to return a value inside of a loop?

I am trying to find the index from an array using a loop function, but I am getting an error:
private function findMatch(matchValue:int):int {
for (var i:int = 0; i < playersList.length; i++) {
if (playersList[i].value + matchValue == levelTarget) {
return i;
}
}
}
Is it not possible to return a value from inside a loop, or rather, am I getting an error everytime it doesn't return a value?!?
private function findMatch(matchValue:int):int {
var _i:int = -1;
for (var i:int = 0; i < playersList.length; i++) {
if (playersList[i].value + matchValue == levelTarget) {
_i = i;
break;
}
}
return _i;
}
You can return from anywhere in a function, but you have to satisfy all code paths with a return value. As described above, you'll need to return a "non-valid" value to indicate no index is found, which is commonly -1.
In many programming languages you can return from any point in a method. The compiler is probably complaining because it can't be sure that it will find the right value in the loop, and then will have nothing to return (even if you as the developer are convinced that it will return before exiting the loop).
So yeah, adding some default return at the end is the right thing to do, and -1 is a common default answer for this kind of thing.