looping and returning a array - arrays

I am in need of some help. I am very new to actionscript and what I am trying to do is calculate the amount of apples from the array and then trace it in the main function. Right now I am getting an error on the return and that error is 1067: Implicit coercion of a value of type String to an unrelated type Number. Now I have tried to switch out the number and string but I still get the error.
public class extends Sprite
{
public function()
{
var fruitNames:Array = ["apple", "peach","banana","pear","guava","apple","peach"];
var totalApples:Number = countingApples(fruitNames);
trace("You have " + totalApples);
}
private function countingApples(fruitNames:Array):Number
{
var total:String = "apple";
for(var i:uint=0; i<7; i++)
{
total += Number[i];
}
return total;
}
}

public class extends Sprite
{
public function()
{
var fruitNames:Array = ["apple", "peach","banana","pear","guava","apple","peach"];
var totalApples:Number = countingApples(fruitNames);
trace("You have " + totalApples);
}
private function countingApples(fruitNames:Array):Number
{
var total:uint = 0;
var i:String = new String();
for(i in fruitNames) {
if (fruitNames[i] == "apple") {
total = total + 1;
}
}
return total;
}
}

That error is because you're trying to return total, which is a String, but you've set the countingApples function's return type as Number. Here's an example which will do what you want, but I think you should try writing your own version again so that you know what's going on:
private function countingApples(fruitNames:Array):Number
{
var total:uint = 0;
var targetFruit:String = "apple";
var totalFruit:uint = fruitNames.length;
for(var i:uint = 0; i < totalFruit; i++)
{
if (fruitNames[i] == targetFruit) {
total++;
}
}
return total;
}

Related

Move Coins downard in Array AS3

I'm trying to make an array that creates 4 coins (which I've done), but the problem is I'm trying to move the coins downward, and I can't figure out how to access the array list to move the coins down(commented out lenght[i].y +=4) which doesn't work. The other problem is I want to only create 4 coins, and not 4 coins every frame in the update loop.
Thanks.
public class Coin extends Sprite
{
//..SPRITES
public static var coinSprite:CoinSprite;
public var _coins:Array = new Array();
public var c = new CoinSprite();
public static var COINCOUNT:int = 4;
//-------------------------------------------------------------------------|
//##SETUP------------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function Coin()
{
super();
this.addEventListener(starling.events.Event.ADDED_TO_STAGE, stageSetup);
}
public function stageSetup(event:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, stageSetup);
}
//-------------------------------------------------------------------------|
//-------------------------------------------------------------------------|
//##MANAGER----------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function manager():void {
this.addEventListener(Event.ENTER_FRAME, updateCoin);
}
//-------------------------------------------------------------------------|
//-------------------------------------------------------------------------|
//##COINHANDLER------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function coinHandler():void {
var length:Number = 4;
for ( var i:Number = 0; i < length; i++) {
//length[i].y += 4;
createCoin();
c.y = i * 50;
}
}
//-------------------------------------------------------------------------|
//-------------------------------------------------------------------------|
//##COLLISION||------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function hitCoinPlayer():void {
//..cleanup
if (c.hitTestObject(Player.playerSprite)) {
c.alpha = 0;
}
//..check bounds
if (c.y >= 1500) {
c.y = -200;
c.alpha = 1;
}
}
//-------------------------------------------------------------------------|
//-------------------------------------------------------------------------|
//##UPDATE-----------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function updateCoin(e:Event):void {
//coinHandler();
}
//-------------------------------------------------------------------------|
//-------------------------------------------------------------------------|
//##CREATE COIN------------------------------------------------------------|
//-------------------------------------------------------------------------|
public function createCoin():void {
c = new CoinSprite();
c.x = 305;
Starling.current.nativeOverlay.addChild(c);
_coins.push(c);
}
//-------------------------------------------------------------------------|
}
public var _coins:Array = {}; // you need an array to store the coins you've created
public function stageSetup(event:Event):void {
coinHandler(); //create four coins upon setting up the stage
this.removeEventListener(Event.ADDED_TO_STAGE, stageSetup); //done setup
}
//other parts of the code are not changed
public function coinHandler():void { // you only need to call this once from ur stagesetup
var length:Number = 4;
for ( var i:Number = 0; i < length; i++) {
createCoin();
c.y = i * 50;
}
}
public function updateCoin(e:Event):void {
moveCoin();
}
public function moveCoin(){
for ( var i:Number = 0; i < _coins.length; i++) {
_coins[i].y +=4;
}
}
public function createCoin():void {
c = new CoinSprite();
c.x = 305;
Starling.current.nativeOverlay.addChild(c);
_coins.push(c);
}

Type Coercion Failed in Action Script 3, getting element from an array

I'm getting this error when I'm getting an element from an array and trying to use some functions on it:
TypeError: Error #1034: Type Coercion failed: cannot convert jogador$
to jogador. at laser/mover_tiro_baixo()
Sorry it's in portuguese, just like the code i'll paste below, but I think you get it: when I retrieve the element from an array it's of type 'jogador$', and if I try to use it as being of 'jogador' it doesn't work. I'm trying to manually force the coercion, as it was trying to convert the object to a DisplayObject (because I'm trying to use the hit test function), but that also didn't work:
TypeError: Error #1034: Type Coercion failed: cannot convert jogador$
to flash.display.DisplayObject. at laser/mover_tiro_baixo()
Code:
package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.debugger.enterDebugger;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.display.DisplayObject;
public class laser extends MovieClip {
private var velo: Number;
private var meuPalco: Stage;
var dono: MovieClip;
var inimigoTipo: Number;
var Inimigos: Array;
var Dano: Number;
var Tam:Number;
var i:Number;
public function laser(palco: Stage, posX: Number, posY: Number, velocidade: Number, dano: Number, CimaBaixo: Number, Dono: MovieClip, vetJogadores: Array) {
this.dono = Dono;
this.Dano = dano;
if (getClass(this.dono) == "jogador") {
inimigoTipo = 0;
Inimigos = jogador(this.dono).VetorInimigos;
} else {
inimigoTipo = 1;
Inimigos = vetJogadores;
}
this.meuPalco = palco;
this.velo = velocidade;
this.x = posX;
this.y = posY;
if (CimaBaixo == 1) {
this.addEventListener(Event.ENTER_FRAME, mover_tiro_cima);
} else {
this.addEventListener(Event.ENTER_FRAME, mover_tiro_baixo);
}
meuPalco.addChild(this);
}
public function mover_tiro_cima(evt: Event) {
this.y -= velo;
if (inimigoTipo == 0) { // Dono do tiro é o player
var Tam: Number = Inimigos.length;
var i: Number = 0;
while (i < Tam) {
if (this.hitTestObject(Inimigos[i])) {
inimigo(Inimigos[i]).vida.Diminuir(this.Dano);
}
i++;
}
} else { // Dono do tiro é um inimigo
Tam = Inimigos.length;
i = 0;
while (i < Tam) {
if (this.hitTestObject(Inimigos[i])) {
jogador(Inimigos[i]).vida.Diminuir(this.Dano);
}
i++;
}
}
if (this.y <= 0) {
this.removeEventListener(Event.ENTER_FRAME, mover_tiro_cima);
meuPalco.removeChild(this);
}
}
public function mover_tiro_baixo(evt: Event) {
this.y += velo;
if (inimigoTipo == 0) { // Dono do tiro é o player
Tam = Inimigos.length;
i = 0;
while (i < Tam) {
if (this.hitTestObject(Inimigos[i])) {
inimigo(Inimigos[i]).vida.Diminuir(this.Dano);
}
i++;
}
} else { // Dono do tiro é um inimigo
Tam = Inimigos.length;
i = 0;
while (i < Tam) {
if (this.hitTestObject(Inimigos[i])) {
jogador(Inimigos[i]).vida.Diminuir(this.Dano);
}
i++;
}
}
if (this.y <= 0) {
this.removeEventListener(Event.ENTER_FRAME, mover_tiro_baixo);
meuPalco.removeChild(this);
}
}
static function getClass(obj: Object): String {
return String(Class(getDefinitionByName(getQualifiedClassName(obj))));
}
}
}
The error happens everytime the laser tests to see if it's hitting an enemy (hittest) in its functions. mover_tiro_baixo() moves the shot down.
Thanks people!
Edit: The way I create the arrays:
var player1:jogador = new jogador(stage,350,700,10,3,1);
var Jogadores:Array = [jogador];
player1.setJogadores(Jogadores);
var inimigo1:et = new et(stage,100,200,Jogadores);
var inimigo2:et = new et(stage,200,100,Jogadores);
var inimigo3:et = new et(stage,350,450,Jogadores);
var todosInimigos:Array = [inimigo1,inimigo2,inimigo3];
player1.DefinirInimigos(todosInimigos);
I've checked some other stack overflow questions that have similar type conversion errors. Most of the other people with a similar problem were actually filling their array with a Class, rather than objects that were instances of a Class. Are you filling those arrays like this?
for(var i:int = 0; i < 10; i++){
Inimigos.push(jogador); //incorrect
}
If so, that is the reason the problem is happening. This is the correct way to do it:
for(var i:int = 0; i < 10; i++){
Inimigos.push(new jogador()); //correct
}
EDIT:
In the new code you added to the first post, this line seems to be the problem:
var Jogadores:Array = [jogador]; //jogador is a class
Flash Actionscript Arrays cannot be "initialized" to only be able to contain a specific type of object. Actionscript Vectors are capable of that, but not Arrays. That line posted above initializes an array in which the first element is a class, not an object.

How do i get Object index in an array

I have seen many threads about this but my problem doesn't solved. This may be a simple way but i have no idea...
I'm trying to get Objects indices in an array like so :
var test:Array = new Array();
for (var row:Number = 0; row < 2; row++) {
test[row] = [];
for (var column:Number = 0; column < 3; column++) {
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
test[row][column] = new ballShape(column, column, row);
addChild(test[row][column]);
}
}
function objClicked(evt:MouseEvent):void {
// Here must return Object index in array
}
P.S :
I can get items index in int array, but i don't know about objects.
Any ideas would be appreciated.
Edit :
ballShape.as
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import fl.motion.Color;
public class ballShape extends Sprite {
private var shapeId:uint;
private var currentPosition:uint;
private var arrayPosition:uint;
private var color:Number;
public function ballShape(Id:uint, currPos:uint, arrPos:uint) {
setId(Id);
setArrayPos(arrPos);
setCurrentPos(currPos);
//trace("Array : " + arrPos);
//trace("Curr : " + currPos);
if (arrPos == 0) {
var posX:uint = 60;
} else {
var posX:uint = (arrPos + 1) * 60;
}
if (currPos == 0) {
var posY:uint = 42;
} else {
var posY:uint = (currPos + 1) * 42;
}
if (arrPos == 0) {
color = 0xFF0000;
} else {
color = 0x00FF00;
}
graphics.beginFill(color, 1.0);
graphics.drawCircle(posX, posY, 20);
graphics.endFill();
this.addEventListener(MouseEvent.CLICK, Clicked);
}
public function setId(Id:uint):void {
shapeId = Id;
}
public function getId():uint {
return shapeId;
}
public function Clicked(evt:MouseEvent):void {
//return getId();
trace("Ball id is " + getId());
trace("Array id is " + getArrayPos());
trace("PositionInArray id is " + getCurrentPos());
//return arrayPosition;
}
public function setCurrentPos(Pos:uint):void {
currentPosition = Pos;
}
public function getCurrentPos():uint {
return currentPosition;
trace(currentPosition);
}
public function setArrayPos(arrayPos:uint):void {
arrayPosition = arrayPos;
}
public function getArrayPos():uint {
return arrayPosition;
trace(arrayPosition);
}
public function addBead(arrayId, currPos):void {
}
}
}
I would suggest adding row and column as public variables in your ballShape class.
That way you can get them like this:
function objClicked(evt:MouseEvent):void {
trace(ballShape(evt.target).getCurrentPos(), ballShape(evt.target).getArrayPos());
}
Maybe turn this two lines around:
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
test[row][column] = new ballShape(column, column, row);
to be :
test[row][column] = new ballShape(column, column, row);
test[row][column].addEventListener(MouseEvent.CLICK, objClicked);
Try something like:
protected function objClicked(e:MouseEvent):void {
for (var row: int=0; row < test.length; row++) {
var column:int = (test[row] as Array).indexOf(e.currentTarget);//use currentTarget so you don't try to match on internal Interactive Objects!
if (column>-1) {
trace(row, column);
return;//or break, if you need to do something else below this loop
}
}
}

Actionscript 3: Trying to create a randomized array

im trying to create a randomized array that will change the position of my pictures(in the tilelist) each time the application is launched. Hope you understand what im looking for, and i dont really understand how to link code correctly here :/
I think its easier simply copying into flash and view from there
thanks :)
Here's my code:
flash.events.MouseEvent;
btn_back.addEventListener(MouseEvent.CLICK, ftilbake);
function ftilbake(evt:MouseEvent)
{
gotoAndStop(1);
}
var heroArray:Array = new Array();
var randomizeArray:Array = new Array();
createArrays()
function createArrays()
{
heroArray[0] = new Array("Rumble","Garen","Lulu","Corki","Warwick");
heroArray[1] = new Array("Bilder/Champions/Rumble.jpg","Bilder/Champions/Garen.jpg","Bilder/Champions/Lulu.jpg","Bilder/Champions/Corki.jpg","Bilder/Champions/Warwick.jpg");
heroArray[2] = new Array("Bilder/Champions/Rumble1.jpg","Bilder/Champions/Garen1.jpg","Bilder/Champions/Lulu1.jpg","Bilder/Champions/Corki1.jpg","Bilder/Champions/Warwick1.jpg");
heroArray[3] = new Array("the Mechanized Menace","the Might of Demacia","the Fae Sorceress","the Daring Bombardier","the Blood Hunter");
heroArray[4] = new Array(0,0,0,0,0);
heroArray[5] = new Array("Rumble.wav","Garen.wav","Lulu.wav","Corki.wav","Warwick.wav");
randomizeArray[0] = new Array();
randomizeArray[1] = new Array();
randomizeArray[2] = new Array();
randomizeArray[3] = new Array();
randomizeArray[4] = new Array();
//randomizing the positions in the array(?)
var randomPos:int = 0;
for (var i:int = 0; i < heroArray.length; i++)
{
randomPos = int(Math.random() * heroArray[0].length);
while (randomizeArray[randomPos][0] != null)
{
randomPos = int(Math.random() * heroArray.length);
}
}
}
var totalKlikk:int = 0;
for (var teller1:int = 0; teller1 <heroArray[0].length; teller1++)
{
leagueChamps.addItem({label:heroArray[0][teller1], source:heroArray[1][teller1]});
}
leagueChamps.columnWidth = 80;
leagueChamps.rowHeight = 80;
leagueChamps.columnCount = 5;
leagueChamps.rowCount = 1;
leagueChamps.direction = "horizontal";
leagueChamps.addEventListener(MouseEvent.CLICK, bildeKlikk);
function bildeKlikk(evt:MouseEvent)
{
var element:Object = leagueChamps.selectedItem;
var fil:String = element.source;
txtChHero.visible = false;
totalKlikk++;
if (totalKlikk <11)
{
for (teller1 = 0; teller1 <heroArray[0].length; teller1++)
{
if (heroArray[1][teller1] == fil)
{
heroArray[4][teller1]++;
if (heroArray[4][teller1] == 1)
{
txtBox1.visible = true;
txtBox2.visible = true;
leagueShow.source = heroArray[2][teller1];
txtBox1.text = heroArray[0][teller1];
txtBox2.text = heroArray[3][teller1];
}
if (heroArray[4][teller1] == 2)
{
txtBox1.visible = true;
txtBox2.visible = true;
leagueShow.source = heroArray[2][teller1];
txtBox1.text = heroArray[0][teller1];
txtBox2.text = heroArray[3][teller1];
heroArray[5][teller1].play();
}
if (heroArray[4][teller1] == 3)
{
bildeKlikk3();
}
}
}
}
else
{
txtChHero.visible = true;
txtChHero.text = "Du har klikket følgende mange ganger på de forskjellige bildene:";
txtH1.text = heroArray[4][0]
txtH2.text = heroArray[4][1]
txtH3.text = heroArray[4][2]
txtH4.text = heroArray[4][3]
txtH5.text = heroArray[4][4]
txtBox1.visible = false;
txtBox2.visible = false;
leagueShow.visible = false;
}
}
function bildeKlikk3()
{
txtBox1.visible = true;
txtBox2.visible = true;
leagueShow.source = heroArray[2][teller1];
txtBox2.text = "Ikke mer informasjon";
}
txtBox2.visible = false;
txtBox1.visible = false;
Array randomization is something which comes up very frequently in all my projects so I ended up creating a static method in my Array utility class for it.
It uses the Fisher–Yates shuffle which is supposed to be the most unbiased (and efficient?) algorithm for shuffling the content of an array. There could be faster ways of doing it (like using the array.sortOn() method, but I am not sure how unbiased a result they get compared to this one.)
The shuffle method:
/**
* shuffle the given array
* #param array
* #return
*/
public static function shuffle(array:Array):Array
{
var index :int;
var item :*;
var limit :int = array.length as int;
for (var i:int = limit-1; i >= 0 ; --i)
{
index = Math.floor(Math.random() * (i + 1));
item = array[index];
array[index] = array[i];
array[i] = item;
}
return array;
}
Example:
var myArray:Array = new Array("Red","Orange","Yellow","Green","Blue");
myArray = ArrayUtils.shuffle(myArray);
where ArrayUtils is the name of the Array Utility class I use. You can simply use the function directly if you don't want to use a utility class of course.
Try this
while (heroArray.length > 0) {
randomizeArray.push(heroArray.splice(Math.round(Math.random() * (heroArray.length - 1)), 1)[0]);
}
Just instatiate randomizeArray though, and don't fill it with empty Arrays like in ur source!
I recommend creating a single object to hold related data, and using a single Array/Vector of that object type.
To answer your question, randomizing an array is fairly easy to do with array.sort() and a random selection function. This method can also be used to randomize any array. you don't need to splice arrays or iterate either.
function sortOnRandom(a:Object, b:Object):Number{
if(Math.random() > 0.5){
return 1;
}else{
return -1;
}
}
myArray.sort(sortOnRandom);

How can I get the number of elements in a sparse array in Actionscript?

Actionscript uses sparse arrays, so I can have an array like this:
var myArray:Array = new Array();
myArray[0] = "foo";
myArray[22] = "bar";
Now myArray.length will give me 23. Is there a way to get the actual number of items in the array without iterating every element?
If you don't want to iterate through the array, you can filter it:
var myArray:Array = new Array();
myArray[0] = "foo";
myArray[22] = "bar";
var numberOfItems:int = myArray.toString().split(',').filter(isItem).length;
function isItem(item:*, index:int, array:Array):Boolean
{
return item != "";
}
By using for syntax, which will iterate the definded indexes:
public static function definedCount(arr:Array):uint {
var ctr:uint = 0;
for(ix:* in arr)
ctr++;
return ctr;
}
If you need to frequently check the count of items in a sparse array, you should wrap it an a collection class that independently keeps track of the count of items. Something like:
public class IndexedCollection {
private var _arr:Array = [];
private var _itemCount:uint = 0;
public function get count():uint {
return _itemCount;
}
public function getItem(index:uint):* {
return _arr[index];
}
public function setItem(index:uint, value:*):void {
if(_arr[index] === undefined)
_itemCount++;
_arr[index] = value;
}
public function delete(index:uint):void {
if(_arr[index] === undefined)
return;
delete _arr[index];
_itemCount--;
}
}
Fastest method should be to always use the inbuilt functions.
function myFilter(item:*, index:int, array:Array):Boolean{
if(item)
{
return true;
}else{
return false;
}
}
var myArray:Array = new Array();
myArray[0] = "foo";
myArray[22] = "bar";
trace(myArray.length) // 23
var myMyNewArray:Array = myArray.filter(myFilter)
trace(myMyNewArray .length) // 2

Resources