How to show my Array in Text without Repetition using AS3? - actionscript-3

var arr:Array = new Array("A","B","C")
//random number
var rand:Number = Math.floor(Math.random()*arr.length)
//my text
t1.text = arr[rand]
t2.text = arr[rand]
t3.text = arr[rand]

Something like
private function getRandomText():String
{
var rand:Number = Math.floor(Math.random() * arr.length);
// this will both get you the random string from the array
// and remove it from the array making sure you won't get the same text next time
var randomString:String = arr.splice(rand, 1);
return randomString;
}
t1.text = getRandomText();
t2.text = getRandomText();
t3.text = getRandomText();
Naturally, this will modify the array by removing the displayed string. So if you need to keep the array for the future use you'd need to make a copy of that and use the copy

At my opinion, you may use this kind of function.
This was quick done but I think that avoid to check everytime in a do while loop (useless and slower).
So you may easily change the code as you need it...
var choices:Vector.<String> = new <String>["A","B","C","D","E","F"];
var randomChoices:Vector.<String> = new Vector.<String>();
var choicesBackup:Vector.<String>;
function populateLetters():void{
var n: uint = Math.floor(Math.random()*choices.length);
randomChoices.push(choices[n]);
choices.splice(n,1);
}
function getDifferentLetters():Vector.<String>{
choicesBackup = choices.slice();
randomChoices = new Vector.<String>();
for(var i:uint=choices.length; i>0; i--){
populateLetters();
}
choices = choicesBackup.slice();
return randomChoices;
}
trace ("letters = " + choices + ", flush = " + getDifferentLetters());
// output : letters = A,B,C,D,E,F, flush = D,E,B,C,F,A

If I missed something, just let me know!
T1.text = getDifferentLetters();
etc...
Example :
var t1:TextField = new TextField();
addChild(t1);
t1.text = getDifferentLetters().toString();
t1.x = 100;
t1.y = 100;
var t2:TextField = new TextField();
addChild(t2);
t2.text = getDifferentLetters().toString();
t2.x = 100;
t2.y = 150;
var t3:TextField = new TextField();
addChild(t3);
t3.text = getDifferentLetters().toString();
t3.x = 100;
t3.y = 200;
This should work if you have a reference to your variable T1.
In your code try to use "Lowercase" for your variables and methods.
"Uppercase" for the first letter of classes and all in "uppercase" if you use a constant.
If you use only Strings in an Array, use Vector.<String> instead of Array!
trace was just an example to get the result in the output.
Best regards.
Nicolas.

Related

Randomising array coordinates with no duplicates AS3

very new to this kind of thing so please bear with me.
So basically I have 4 buttons that I have put to the stage using the Actions panel. They all have set coordinates so every time I run my game, they are in the same place.
Now here's my issue, I want these buttons to randomise their positions using those coordinates, but I often get duplicates, meaning one button is on top of another.
Here is my code so far
var coordArray : Array = [
new Point(44,420),
new Point(270,420),
new Point(44,550),
new Point(270,550),
];
var pointRange:Number = 4;
var randomPoint:int = Math.random()*pointRange;
answerButtons.x = coordArray[randomPoint].x;
answerButtons.y = coordArray[randomPoint].y;
var pointRange_2:Number = 4;
var randomPoint_2:int = Math.random()*pointRange_2;
answerButtons_2.x = coordArray[randomPoint_2].x;
answerButtons_2.y = coordArray[randomPoint_2].y;
var pointRange_3:Number = 4;
var randomPoint_3:int = Math.random()*pointRange_3;
answerButtons_3.x = coordArray[randomPoint_3].x;
answerButtons_3.y = coordArray[randomPoint_3].y;
var pointRange_4:Number = 4;
var randomPoint_4:int = Math.random()*pointRange_4;
answerButtons_4.x = coordArray[randomPoint_4].x;
answerButtons_4.y = coordArray[randomPoint_4].y;
I have googled this profusely and I keep getting answers to do with the splice and shift methods. Is this the type of thing I need? I'm assuming I need a function that removes a point from the array after it is used.
Cheers.
Just remove the coordinate from the list when you pick it randomly using splice:
var coordinates:Vector.<Point> = new <Point>[
new Point(44, 420),
new Point(270, 420),
new Point(44, 550),
new Point(270, 550)
];
function positionAtRandomCoordinate(object:DisplayObject):void {
var index:int = Math.random() * coordinates.length;
var coordinate:Point = coordinates.splice(index, 1)[0];
object.x = coordinate.x;
object.y = coordinate.y;
}
positionAtRandomCoordinate(answerButtons);
positionAtRandomCoordinate(answerButtons_2);
positionAtRandomCoordinate(answerButtons_3);
positionAtRandomCoordinate(answerButtons_4);

AS3 - Adjust image colors

I'm adjusting image colors through the function below. The problem is that if I need to switch a colorFilter value to 0 it's not working but if I enter 0.1 instead of 0 it works.
How to make it work without that workaround?
import fl.motion.AdjustColor;
import flash.filters.ColorMatrixFilter;
var colorFilter:AdjustColor = new AdjustColor();
var mColorMatrix:ColorMatrixFilter;
var mMatrix:Array = [];
var MC:MovieClip = new MovieClip();
function adjustColors():void
{
colorFilter.hue = 50;
colorFilter.saturation = 50;
colorFilter.brightness = 50;
colorFilter.contrast = 12;
mMatrix = colorFilter.CalculateFinalFlatArray();
mColorMatrix = new ColorMatrixFilter(mMatrix);
MC.filters = [mColorMatrix];
}
I tested this by adding an argument to adjustColors() and calling it twice, and I see the same problem. I think it's just a bug where it ignores zero values.
It's not much of a better workaround, but if you just create a new AdjustColor each time, it should work correctly:
import fl.motion.AdjustColor;
import flash.filters.ColorMatrixFilter;
var colorFilter:AdjustColor = new AdjustColor();
var mColorMatrix:ColorMatrixFilter;
var mMatrix:Array = [];
var MC:MovieClip = new MovieClip();
function adjustColors():void
{
colorFilter = new AdjustColor();
colorFilter.hue = 50;
colorFilter.saturation = 50;
colorFilter.brightness = 50;
colorFilter.contrast = 12;
mMatrix = colorFilter.CalculateFinalFlatArray();
mColorMatrix = new ColorMatrixFilter(mMatrix);
MC.filters = [mColorMatrix];
}
Here is my workaround for reference:
Just use the logical OR assignment when you set each property.
That way if a value is 0 it will evaluate to false and .1 will be assigned instead:
var colorMat:ColorMatrixFilter = new ColorMatrixFilter();
var colorAdjust:AdjustColor = new AdjustColor();
const colorsAdj:Array =
[
// BRIGHTNESS, CONTRAST, SATURATION, HUE
[-20,0,20,-50],
[0,0,0,0],
[0,0,0,17]
];
function setColorMat(colorID:int):void
{
colorAdjust.brightness = colorsAdj[colorID][0] ||= .1;
colorAdjust.contrast = colorsAdj[colorID][1] ||= .1;
colorAdjust.saturation = colorsAdj[colorID][2] ||= .1;
colorAdjust.hue = colorsAdj[colorID][3] ||= .1;
colorMat.matrix = colorAdjust.CalculateFinalFlatArray();
}
That way you avoid recreating a new ColorMatrixFilter each time, in case it really change something...
And you keep a nice clean array... ;-)

Using value of variable as variable name for urlVariable in actionscript

I have the next code
var uv:URLVariables = new URLVariables();
//lot of them in an array
var variable:String = "mode";
var value:String = "easy";
uv.<variable_value> = <value_value>;
It's like using the value of variable as the variable name. How can I achieve this?
Edit: The next code represents what I need as result
uv.mode = 'easy';
uv.category = 256;
..
..
Where the variables mode and category are values of other variables.
Using php would be something like this:
$next = 10;
$var = 'next';
echo ${$var}; //10
Thanks.
I'm not quite sure what you want ( because of the question formulation )
but i'm using URLVariables like this:
import flash.net.URLVariables;
import flash.net.URLLoader;
var urlVariables:URLVariables = new URLVariables ();
// setting the values with names
urlVariables[value_name_1] = value_1; // value_name_* is a string, value_* is anything you need, Number, String, Array, Object etc...
urlVariables[value_name_2] = value_2;
urlVariables[value_name_3] = value_3;
// and now for the loading
var loader:URLLoader = new URLLoader ();
loader.data = urlVariables;

How to set dynamic locations in an Image using actionscript3.0?

I want to set different locations in an Image, and when I mouse over the location it needs to shows something('box' or 'x' nd 'y' position of the location). How can i achieve this.?
Hope, you want to set some locations in the stage and u want to store something.
If that, your coding is good. here after u can achieve that by using amf-php for back end purpose. php will help u store values in the database. refer google to know about amf-php.
good luck.
not sure wht you are looking for, may be something like that
http://www.oscartrelles.com/archives/dynamic_movieclip_registration_with_as3
Not registration point...
var msgBox:messageBox;//package
var loc:Array = new Array();
for(var i:uint = 0;i<20;i++)
{
for(var j:uint = 0;j<14;j++)
{
spr = new Sprite();
spr.graphics.beginFill(0xaaaaaa,.1);
spr.graphics.drawCircle(0,0,10);
spr.graphics.endFill();
addChild(spr);
loc.push(spr);
spr.x = 30 + i * spr.width * 1.3;
spr.y = 30 + j * spr.height * 1.3;
}
}
for(i=0; i<loc.length;i++)
{
loc[i].name = "unknown "+i;
loc[i].buttonMode = true;
loc[i].addEventListener(MouseEvent.MOUSE_OVER, mouseOverAction);
loc[i].addEventListener(MouseEvent.MOUSE_OUT, mouseOutAction);
}
function mouseOverAction (e:MouseEvent):void
{
msgBox = new messageBox(100,20,6,0xFFFFFF);
addChild(msgBox);
cur_loc_name = new TextField();
cur_loc_name.text = e.target.name;
msgBox.addChild(cur_loc_name);
cur_loc_name.x = 5;
cur_loc_name.y = 1;
msgBox.x = mouseX + 20;
msgBox.y = mouseY + 26;
}
function mouseOutAction (e:MouseEvent):void
{
removeChild(msgBox);
}
Run this code. It will fill the stage with 280 sprites, and each sprite can have diff instance name..
I wants to do this using pixels...or any other way to do?

Closure problem? - passing current value of a variable

I'm trying to pass the current value of a variable when an a dynamically generated navigation 'node' is clicked. This needs to just be an integer, but it always results in the last node's value.. have tried some different methods to pass the value, a custom event listener, a setter, but I suspect it's a closure problem.. help would be appreciated ;-)
function callGrid():void {
for (var i:Number = 0; i < my_total; i++) {
var gridnode_url = my_grid[i].#gridnode;
var news_category= my_grid[i].#category;
var newstitle = my_grid[i].#newstitle;
var news_content = my_grid[i]..news_content;
var news_image = my_grid[i]..news_image;
var gridnode_loader = new Loader();
container_mc.addChild(gridnode_loader);
container_mc.mouseChildren = false;
gridnode_loader.load(new URLRequest(gridnode_url));
gridnode_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, gridLoaded);
gridnode_loader.name = i;
text_container_mc = new MovieClip();
text_container_mc.x = 0;
text_container_mc.mouseEnabled = false;
var textY = text_container_mc.y = (my_gridnode_height+18)*y_counter;
addChild(text_container_mc);
var tf:TextSplash=new TextSplash(newstitle,10,0,4 );
container_mc.addChild(tf);
tf.mouseEnabled = false;
tf.height = my_gridnode_height;
text_container_mc.addChild(tf);
var text_container_mc_tween = new Tween(text_container_mc, "alpha", Strong.easeIn, 0,1,0.1, true);
gridnode_loader.x = (my_gridnode_width+5) * x_counter;
gridnode_loader.y = (my_gridnode_height+15) * y_counter;
if (x_counter+1 < columns) {
x_counter++;
} else {
x_counter = 0;
y_counter++;
}
}
}
function gridLoaded(e:Event):void {
var i:uint;
var my_gridnode:Loader = Loader(e.target.loader);
container_mc.addChild(my_gridnode);
_xmlnewstarget = my_gridnode.name;
//||||||||||||||||||||||||||||||||||||||||
//when a particular grid node is clicked I need to send the current _xmlnewstarget value to the LoadNewsContent function...
//||||||||||||| ||||||||||||||||||||||||
my_tweens[Number(my_gridnode.name)]=new Tween(my_gridnode, "alpha", Strong.easeIn, 0,1,0.1, true);
my_gridnode.contentLoaderInfo.removeEventListener(Event.COMPLETE, gridLoaded);
my_gridnode.addEventListener(MouseEvent.CLICK, loadNewsContent);
}
function loadNewsContent(e:MouseEvent):void {
createNewsContainer();
getXMLNewsTarget();
news_category = my_grid[_xmlnewstarget].#category;
var tfnews_category:TextSplash=new TextSplash(news_category,20,16,32,false,false,0xffffff );
tfnews_category.mouseEnabled = false;
newstitle = my_grid[_xmlnewstarget].#newstitle;
var tftitle:TextSplash=new TextSplash(newstitle,20,70,24,false,false,0x333333 );
news_container_mc.addChild(tftitle);
tftitle.mouseEnabled = false;
news_content = my_grid[_xmlnewstarget]..news_content;
var tfnews_content:TextSplash=new TextSplash(news_content,20,110,20,true,true,0x333333,330);
news_container_mc.addChild(tfnews_content);
tfnews_content.mouseEnabled = false;
news_image = my_grid[_xmlnewstarget].#news_image;
loadNewsImage();
addChild(tfnews_category);
addChild(tftitle);
addChild(tfnews_content);
var news_container_mc_tween = new Tween(news_container_mc, "alpha", Strong.easeIn, 0,1,0.3, true);
news_container_mc_tween.addEventListener(Event.INIT, newsContentLoaded);
}
I'm not going to try to read your code (try to work on your formatting, even if it's just indenting), but I'll provide a simplified example:
for (var i = 0; i < my_total; i++) {
var closure = function() {
// use i here
}
}
As you say, when closure is called it will contain the last value of i (which in this case would be my_total). Do this instead:
for (var i = 0; i < my_total; i++) {
(function(i) {
var closure = function() {
// use i here
}
})(i);
}
This creates another function inside the loop which "captures" the current value of i so that your closure can refer to that value.
See also How does the (function() {})() construct work and why do people use it? for further similar examples.
Umm, as mentioned above, the code is a bit dense, but I think you might have a bit of type conversion problem between string and integers, is the "last value" always 0? try making these changes and let me know how you get on.
// replace this gridnode_loader.name = i;
gridnode_loader.name = i.toString();
// explictly type this as an int
_xmlnewstarget = parseInt(my_gridnode.name);
// replace this: my_tweens[Number(my_gridnode.name)] = new Tween(......
my_tweens[parseInt(my_gridnode.name)] = new Tween();
Oh and I think it goes without saying that you should massively refactor this code block once you've got it working.
Edit: after further study I think you need this
//replace this: my_gridnode.addEventListener(MouseEvent.CLICK, loadNewsContent);
var anonHandler:Function = function(e:MouseEvent):void
{
loadNewsContent(_xmlnewstarget);
};
my_gridnode.addEventListener(MouseEvent.CLICK, anonHandler);
Where your loadNewsContent has changed arguements from (e:MouseEvent) to (id:String)
Firstly, you do not need to call addChild for the same loader twice (once in callGrid) and then in (gridLoaded). Then you can try putting inside loadNewsContent: news_category = my_grid[int(e.target.name)].#category;instead of news_category = my_grid[_xmlnewstarget].#category; As _xmlnewstarget seems to be bigger scope, which is why it is getting updated every time a load operation completes.