How to declare array with custom indices, in Unity JavaScript? - arrays

I'm looking for a way to store variables of same type in an array, and access them by their names. Like in PHP you do:
$array = array();
$array['first member']=$var1;
$array['another member']=$var2;
// so on
I want to do a similar thing in Unity3D's JavaScript. I have AudioClip variables, currently used like this:
#pragma strict
var Audio_Goal:AudioClip;
var Audio_Miss:AudioClip;
var Audio_Saved:AudioClip;
function PlaySound_Goal()
{
audio.PlayOneShot(Audio_Goal);
}
function PlaySound_Miss()
{
audio.PlayOneShot(Audio_Miss);
}
of course this requires one function per audioclip, which is ugly.
I want to do it like this:
function PlayAudio(audioname:String)
{
audio.PlayOneShot(AudioArray[audioname]);
}
How can I do this?

You need to use something like a dictionary:
#pragma strict
import System.Collections.Generic;
var AudioArray = new Dictionary.<string,AudioClip >();
// add to dict
AudioArray["one"] = AudioClip.Create(/**/); //see AudioClip.Create(...) for arguments
// play from dict
audio.clip = AudioArray["one"];
audio.Play();

You can do something like:
var myAudioClips: AudioClip[];
function Start() {
// Your stuff...
}
function PlayAudio(audioname:String)
{
for (var myClip in myAudioClips) {
if (audioname.Equals(myClip.name)) {
audio.PlayOneShot(myClip);
}
}
}
And then add all of your clips in the array by dragging them using the editor.

You should be able to use Enumerable.Zip>, but because it's not available in UnityScript, I think this is the best you can do:
var names : List.<String>;
var clips : List.<AudioClip>;
var keyFunc = function(kvp : KeyValuePair.<String, AudioClip>) kvp.Key;
var valueFunc = function(kvp : KeyValuePair.<String, AudioClip>) kvp.Value;
var dictionary = names.Select(
function(name, index) new KeyValuePair.<String, AudioClip>(name, clips[index])
).ToDictionary(keyFunc, valueFunc);
I don't know why you need to store the Funcs. This code compiles, but won't run:
var dictionary = names.Select(
function(name, index) new KeyValuePair.<String, AudioClip>(name, clips[index])
).ToDictionary(function(kvp) kvp.Key, function(kvp) kvp.Value);
Report it as a bug if you want. I don't want to, because I don't think the devs need to waste any more time on this language.

Related

Two Objects arrays and concat

i have two arrays that are both connected to a scope (http get etc.):
$scope.allShops
that hold all the shop details and
$scope.allCds
that hold all the cd's
both work fine and the Ng-Repeat gives me all the output (individually) i need, i however would like to build a search that allows me to search on the cd name and on the shop name from the same search field (using a label to mention if its a shop or a cd to avoid confusion). So i came up with this:
$scope.allShops = [];
$scope.allCds = [];
var jointData1 = '';
var jointData2 = '';
var SearchAll = '';
var jointData1 = $scope.allShops;
console.info(jointData1);
var jointData2 = $scope.allCds;
console.info(jointData2);
var searchAll = jointData1.concat(jointData2);
console.info(searchAll)
But all the logs are empty, if i place the log inside the succes.array function it shows me the data object but placing the log with the scope outside give me nothing. How do i get the data outside the array function and able to concat the two scope?
Your console.info calls will be empty because the $http service hasn't got the data back yet.
You'd have to do this after the data is returned by using a promise (.then())
Just try this
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname1 in obj1) {
obj3[attrname1] = obj1[attrname1];
}
for (var attrname2 in obj2) { obj3[attrname2] = obj2[attrname2]; }
return obj3;
}
merge_options(obj1,obj2);

calling swf with an array, not working with my string in flash

I'm trying to get my SWF loader to work with an array so I can call my swf files via one code, using buttons.
This is the problem I am getting:
Scene 1, Layer 'actions', Frame 2, Line 68 1067: Implicit coercion of a value of type Array to an unrelated type String.
I am not too good with arrays, or strings, or coding tbh, i'm not too sure what the problem is, I understand it, my array and my string don't work together,basically, but I don't know how to fix it, if it can be fixed/work with the code I am using.
just some help and being pointed in the right direction would be a treat
var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
var SWFLoader = new Loader;
var SWFRequest = new URLRequest (swfList) ;
SWFLoader.load (SWFRequest) ;
function loadSWF(file:String, container:MovieClip=null):void
{
if(container == null) container = MovieClip(root);
if(SWFLoader != null)
{
if(SWFLoader.parent) SWFLoader.parent.removeChild(SWFLoader);
}
addChild (SWFLoader);
}
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
To access items within an array use this format:
var SWFRequest = new URLRequest(swfList[i]);
Where i is the position in array (starting at zero).
For instance:
var SWFRequest = new URLRequest(swfList[0]);
gives the same result as:
var SWFRequest = new URLRequest("imagegallery.swf");
Did away with the array but still "have one code for both buttons instead of two separate codes".
// Looks unnecessary
// var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
// Transfer inside loadSWF()
// var SWFRequest = new URLRequest (swfList); // needs a url String parameter
// SWFLoader.load (SWFRequest);
var SWFLoader = new Loader(); // Don't forget the parenthesis
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
function loadSWF(file:String, container:MovieClip=null):void
{
// What for?
// if(container == null) container = MovieClip(root);
if(SWFLoader != null)
if(SWFLoader.parent)
SWFLoader.parent.removeChild(SWFLoader);
var SWFRequest = new URLRequest (file) ;
SWFLoader.load (SWFRequest);
addChild (SWFLoader);
}

As3 calling array outside of function

I am kind of new to AS3 and programming itself.
I have this issue. I want to be able to use the Pl_array and En_array outside of AfterLoad function, but I always get undefined value. I am writing the code inside the timeline not .as file. Does it matter?
I was trying to return them from function but since it's related to listener i just dont know how to do it also i was trying to make them public.
Here is code on first frame:
import flash.events.MouseEvent;
stop();
Btn_start.addEventListener(MouseEvent.CLICK, onStartClick);
function onStartClick(me:MouseEvent):void{
gotoAndStop("Dictionary");
}
and here is on the second called Dictionary:
import flash.events.Event;
import flash.utils.Timer;
import flash.events.MouseEvent;
stop();
var myTextLoader:URLLoader = new URLLoader();
var Txt_array:Array=new Array(); //tablica wczytanych zwrotów
var Pl_array:Array=new Array();
var En_array:Array=new Array();
var myTimer:Timer = new Timer(1000);
myTextLoader.addEventListener(Event.COMPLETE, onLoaded); //listener na koniec wczytywania pliku tekstowego
function onLoaded(e:Event):void { //funkcja wywoływana przez listener na koniec wczytywania pliku
Txt_array = e.target.data.split(/\n/); //
dispatchEvent(new Event("Load_END"));
}
myTextLoader.load(new URLRequest("Zwroty.txt"));
this.addEventListener("Load_END", AfterLoad); //kod wykonywano po wczytaniu pliku tekstowego
function AfterLoad(e:Event):void{
for each (var s:String in Txt_array){// pętla która rozdziela tekst na polski i angielski
var i:int=0;
En_array[i]=s.substr(0, s.indexOf("-")-1);
Pl_array[i]=s.substr(s.indexOf("-")+2, s.length);
i++;
} //koniec fora
}//koniec funkcji
Begin.addEventListener(MouseEvent.CLICK, test);
function test(e:Event):void{
trace(En_array[1]);
}
//funkcja wyświetlająca string w txt_load
function ShowString (txt_show:String):void{
load_txt.text = txt_show;
}
function ShowOpinion(txt_opinion:String):void{
opinion_txt.text=txt_opinion;
}
function HideOpinion():void{
opinion_txt.text=" ";
}
//funkcja porównująca łańcuchy
function Compare(txt_a:String,txt_b:String):Boolean{
if (txt_a==txt_b){
return true;
}
return false;
}
//up_btn.useHandCursor=true;
//up_btn.addEventListener(MouseEvent.MOUSE_OVER, switch_bg);
//function switch_bg(me:MouseEvent):void{
//var newColor:ColorTransform = me.target.transform.colorTransform;
//newColor.color = 0x1000C6;
//me.target.transform.colorTransform = newColor;
//}
on test function i always get undefined while tracing. I was trying to find solution in Google but couldn't.
This code looks like it should work but if you're trying to access the first element in En_array you need to remember indexing starts at 0, not 1. You might also want to make sure En_array is not empty before reading any of its values. Try this:
if (En_array.length > 0)
trace(En_array[0]);
it sometimes take some seconds to load data first. After loading then read data from array. In timeline, loading must not be at the same frame with the reading process, unless otherwise, explicitly loaded in first line of code then followed by reading.
You have mess in your code. Lets make it simpler:
import flash.events.Event;
import flash.utils.Timer;
import flash.events.MouseEvent;
stop();
var myTextLoader:URLLoader = new URLLoader();
var Txt_array:Array;
var Pl_array:Array;
var En_array:Array;
/* Good practice is to create object when you relay need it */
var myTimer:Timer = new Timer(1000);
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
Txt_array = e.target.data.split(/\n/); // now we create new array
afterLoad(Txt_array);
}
function afterLoad(array):void{ // it is good habit to start function names from small letter
En_array = [];// create arrays
Pl_array = [];
for each (var s:String in array){
En_array.push(s.substr(0, s.indexOf("-")-1));
Pl_array.push(s.substr(s.indexOf("-")+2, s.length));
// push let you add items more efficient and you don't need index
}
}
myTextLoader.load(new URLRequest("Zwroty.txt"));
Now everything should be fine :) Just remember to check if objects (in your case arrays) have elements you want to use (etc. array.lenght>0 or array=null)

How to define Java's Object[] someObject=new Object[10] in Actionscript

I have a class named Component and it has a code like this
class Component {
var ID:String;
var typical:String;
var connection:String;
var temperature:String;
var voltage:String;
var visibility:Boolean = true;
public function Component(type:String, temperature:String, connection:String, voltage:String) {
this.typical = type;
this.temperature = temperature;
this.connection = connection;
this.voltage = voltage;
}
public function setVisibility(b:Boolean):Void {
visibility = b;
}
}
I would like to create an array instance of this class just like in java (like Component[] someComponent = new Component[10]) How can I define this is Actionscript?
In Flash Player 10, Adobe added the Vector class. It is the typed array you are looking for. You can make a vector like this:
private var vector:Vector.<SomeComponent> = new Vector.<SomeComponent>(10);
private var anotherOne:Vector.<Number> = new Vector.<Number>;
thanks for the answer. I found something that might be another example.
just define an array like
var myArray:Array=new Array();
after that define each element of the array as another object, like
myArray[0]=new Component(); //Here Component is the class which I defined and showed in my original question.

AS3 Fastest way to merge multiple arrays

I'm trying to write a function where I can specify any amount of array, and the return value will be an array containing the contents of all of the specified arrays.
I've done this, but it seems like a really slow and ugly way of doing it:
var ar1:Array = [1,2,3,4,5,6,7,8,9];
var ar2:Array = ['a','b','c','d','e','f','g','h'];
function merge(...multi):Array
{
var out:String = "";
for each(var i:Array in multi)
{
out += i.join(',');
}
return out.split(',');
}
trace(merge(ar1, ar2));
Is there an inbuilt and more efficient / nice way of achieving this? The result does not need to be in the same order as the input - completely unsorted is fine.
You can use concat.
If the parameters specify an array, the elements of that array are concatenated.
var ar1:Array = [1,2,3,4,5,6,7,8,9];
var ar2:Array = ['a','b','c','d','e','f','g','h'];
var ar3:Array = ['i','j','k','l'];
var ar4 = ar1.concat(ar2, ar3); // or: ar1.concat(ar2).concat(ar3);
To make a single array out of a 2 dimensional array you can use this function:
private function flatten(arrays:Array):Array {
var result:Array = [];
for(var i:int=0;i<arrays.length;i++){
result = result.concat(arrays[i]);
}
return result;
}
// call
var ar4 = [ar1, ar2, ar3];
var ar5 = flatten(ar4);
You can also use varargs to merge multiple arrays:
private function merge(...arrays):Array {
var result:Array = [];
for(var i:int=0;i<arrays.length;i++){
result = result.concat(arrays[i]);
}
return result;
}
// call
var ar5 = merge(ar1, ar2, ar3);
I don't know if this method is faster than using loops, but it is a (fancy) quick way to merge 2 arrays. (and it works in Javascript and Actionscript)
var arr1:Array = [1,2,3,4,5]
var arr2:Array = [6,7,8,9,10]
arr1.push.apply(this, arr2); // merge
// arr1.push.call(this, arr2); // don't use this. see comment below
trace(arr1) // 1,2,3,4,5,6,7,8,9,10
function merge(...multi):Array
{
var res:Array = [];
for each(var i:Array in multi)
{
res = res.concat(i);
}
return res;
}
Didnt try it, but something like this would help you.

Resources