as3 array error #1010 - arrays

im basically trying to make a mini game where you have to dodge the oncoming objects by using the on-screen buttons (button left and right of the screen) it worked fine when i did it with an individual object then i decided to have more objects and make an array to hold them. thats when the error accrued.
the error is :
TypeError: Error #1010: A term is undefined and has no properties.at Untitled_fla::MainTimeline/cyclespeed()

Your cycle Array has 5 elements starting by the index 0 and ending by 4 :
... Array indices are zero-based, which means that the first element in the array is [0], the second element is [1], and so on.
That's why your for loop should be like this :
for (var i:int = 0; i < 5; i++) { }
OR
for (var i:int = 0; i <= 4; i++) { }
OR simply
for (var i:int = 0; i < cycle.length; i++) { }
In your cyclespeed function, the value of your i var will be always 5, which is the last value assigned to it in your for loop, and of course cercle[5] didn't exist that's why you got the TypeError: Error #1010: A term is undefined and has no properties : cercle[5] is undefined and has not an x property.
In your case you can use only one Event.ENTER_FRAME listener to do all the job like this :
stage.addEventListener(Event.ENTER_FRAME, onEnterThisFrame);
function onEnterThisFrame(e:Event):void {
box_MC.x -= 1;
for (var i:int = 0; i < cycle.length; i++) {
cycle[i].x += 1;
if(box_MC.hitTestObject(cycle[i])) {
trace ("true");
box_MC.x += 4;
}
}
if (movingdown == 1) {
box_MC.y -= 4.5;
} else if (movingup == 1) {
box_MC.y += 4.5;
}
}
Hope that can help.

I don't have enough rep points to comment, so I'll critique what I saw in your code.
There are quite a few things wrong with the code.
This was declared twice, once in a for loop and one outside of the functions
addEventListener(Event.ENTER_FRAME, cyclespeed);
You attached the "handleCollision" event to the stage and not a movieclip.
handleCollision refers to "cycle[i]" but i is out of scope since it is not apart of the for loop where i has been declared
function handleCollision( e:Event) : void {
if(box_MC.hitTestObject(cycle[**i**])) {
trace ("true");
box_MC.x += 4;
}
}
I would suggest building each piece one at a time because it seems like you are trying to do a lot at once, without actually getting anything to work.

Related

ReferenceError: Error #1069 Actionscript 3

So i have been stuck on this for about 2 weeks and i have no idea how to progress.
I have an array of movie clips called "_main.speederArray" and i'm trying to make it so that if they collide with each other then they are both destroyed. Here is my code in the "Speeder class" to detect collision.
private function detectionHandler():void{
//trace("array length", _main.speederArray.length);
detectionID = _main.gameCounter;
for ( var i:int = _main.speederArray.length -1; i >= 0; i--){
var speeder:Speeder = _main.speederArray[i];
if(speeder.destroyMe) continue;
if(speeder.detectionID == this.detectionID) continue;
if (boxIntersect(this, speeder)){
trace("collision");
destroyMe = true;
speeder.destroyMe = true;
}
}
}
Here is the boxIntersect function this code refers to. It's in the same class
private function boxIntersect ( speeder1:Speeder, speeder2:Speeder):Boolean{
if(speeder1.x + speeder1.distRight < speeder2.x + speeder2.distLeft) return false; //checking for overlap on X axis
if(speeder1.x + speeder1.distLeft > speeder2.x + speeder2.distRight) return false;
if(speeder1.y + speeder1.distBot < speeder2.y + speeder2.distTop) return false; // checking for overlap on Y axis
if(speeder1.y + speeder1.distTop > speeder2.y + speeder2.distBot) return false;
return true;
}
And then here is where i think the problem is. I have a class called "spawner" and this is where i was going to handle the objects being created and destroyed. Here is the code where i am trying to splice objects from the array depending on whether the destroyMe bool is set to true. At this stage i have confused the shit out of myself so any help would be greatly appreciated!
private function updateArray(e:Event):void{
for(var i:int = _main.speederArray.length - 1; i>=0; i--){
var speeder:Speeder = _main.speederArray[i];
if(speeder.destroyMe){
//trace("hello");
removeChild(speeder[i]); // take it off the stage
_main.speederArray[i] = null;
_main.speederArray.splice(i, 1); //remove it from the array
}
}
}
Now, the game runs however as soon as the 2 objects within the same array collide, i get the collision trace in the output window but straight after i get this :
ReferenceError: Error #1069: Property 1 not found on com.game.Speeder and there is no default value.
at com.game::Spawner/updateArray()
No idea what it means :(
Any help appreciated thanks guys!
The problem comes from the line
removeChild(speeder[i]); inside your update function.
Speeder has no properties that are called 1 and the 1 comes obviously from your for loop.
So, to solve this problem, you should simply call
removeChild(speeder);
speeder already is the object at the position i of your array. Putting [] behind an object is the same like accessing a property from it. essentially you were doing this:
removeChild(speeder.1);

Array not resetting in Game

Hey guys so i am developing a Game and i have an Array that keeps track of my 5 movie clips that are added to the stage by the array. I have a Player movie clip as well so the Player movie clip is Hittesting with all the 5 diamond movie clips which are added to the stage like so:
private var nPoints:Number = 5;..........
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);
}
}
Now when the Player comes in contact with all the 5 movie clips everything works fine and the output for the array looks like this:
0
1
2
3
4
Then it continues to the next level.
But say that my Player doesnt hit any of the 5 movie clips or only hits a couple of them, when the next level is started the output looks like this:
5
6
7
8
9
and when the next level is started weird things start happening like points start adding to the highscore by themselves.
I think the problem is that im not destroying the array holding the 5 movie clips correctly this is the code i use to start the next level and destroy the array:
if(player.hitTestObject(mcGoal_1))
{
//Remove all points from array/stage
for (var i:int = 0; i < aPointsArray.length; i++)
{
if (aPointsArray[i].parent)
{
parent.removeChild(aPointsArray[i]);
}
startNextLevel();
}
The mcGoal_1 is the object of the game so if the player hits the goal_1 then destroy all array objects on screen and start next level. This is the startnextlevel function.
private function startNextLevel():void
{
//add points to next stage
addPointsToStage();
}
So can you see why when the next level starts the array isnt reset back to 01234? I think thats why the game has that bug of randomly adding points. Please any help will be appreciated
//Remove all points from array/stage
for (var i:int = 0; i < aPointsArray.length; i++)
if (aPointsArray[i].parent)
parent.removeChild(aPointsArray[i]);
// just one statement, no braces
aPointsArray.length=0; // clear the array itself, not just
// points from display list!
startNextLevel(); // now start level
An incorrect order of correct statements leads to a disaster. Always check your code flow, what executes now and what then, and how many times.
It doesn't look like you're removing anything from the array.
You can use a combination of .indexOf() and .splice() to remove items from an array:
function removeMc(clip:MovieClip):void
{
if(clip.parent) clip.parent.removeChild(clip);
// Also remove from array.
var index:int = aPointsArray.indexOf(clip);
aPointsArray.splice(index, 1);
}
It might also be worth simply emptying the array when you startNextLevel():
private function startNextLevel():void
{
aPointsArray.length = 0;
//add points to next stage
addPointsToStage();
}
Just assign your array to null value. so that array will start from begining whenever you require. i hope the following code code would helps you.
var nPoints:Number = 5;
var points:poin;
var aPointsArray:Array;
var startPoint:Number = 0;
var xSpacing:Number = 20;
var ySpacing:Number = 20;
addPointsToStage();
function addPointsToStage():void
{
aPointsArray = null;
aPointsArray = new Array();
for (var i:int = 0; i < 6; i++)
{
trace(aPointsArray.length);
points = new poin();
addChild(points);
points.x = 100+ (xSpacing * i);
points.y = 200 - (ySpacing * i);
aPointsArray.push(points);
}
}

Finding the biggest width of multiple text fields in AS3

I have an array that makes multiple textfields based off a user variable. The code below is connected to a function that fires when text is added. From there it's supposed to find the widest text field, and then apply the width to rest of the textfields so they all are the same size.
Here is the code that is giving me problems. I could use a second look to see perhaps if my syntax is improper or if there's a better way at going at this.
for (var ied: int=1; ied>=electoff.electinput.textArray.length; ied++)
{
trace("one");
widest=(electoff.electinput.textArray["b"+ied].width>widest)?electoff.electinput.textArray["b"+ied].width:widest;
}
for (i =ied; i<electoff.electinput.textArray.length; ied++)
{
electoff.electinput.textArray["b"+ied].width = widest;
trace("two");
}
Here's the error I'm getting:
TypeError: Error #1010: A term is undefined and has no properties. at
NewPlv2_fla::MainTimeline/ajWidth()[NewPlv2_fla.MainTimeline::frame1:650] at NewPlv2_fla::MainTimeline/_keys()[NewPlv2_fla.MainTimeline::frame1:774]
AS3.0 Array is indices are zero-based, which means that the first element in the array is [0], the second element is [1], and so on.
so FYI you trying to access textArray["b"+ided]. but this syntax is a Associative arrays
I tested following code. check please.
import flash.text.TextField;
var arr:Array = [];
for(var i:int = 0; i<10; i++)
{
var tf:TextField = new TextField();
tf.width = 200 * Math.random();;
tf.name = "tf" + i;
tf.height = 100;
arr.push(tf);
trace(tf.name + ": " + tf.width);
}
var widest:Number = 0;
for (i=0;i<arr.length;i++)
{
if(arr[i].width>widest) widest = arr[i].width;
}
trace("widest: " + widest);

Is it possible to reload or reset an array in as3?

I'm wondering if it is possible to reset / reload / reconstruct an array order?
I'm making this "Space Invaders" game and the enemy's need to restart to it's position when the game is being restarted. When I shoot down the enemy's and reset my game, the enemy's I've killed keep being gone.
So here's some of the code responsible:
var spiderArray:Array = new Array(enemyField.enemy1,enemyField.enemy2,
enemyField.enemy3,enemyField.enemy4,
enemyField.enemy5,enemyField.enemy6,
enemyField.enemy7,enemyField.enemy8,
enemyField.enemy9,enemyField.enemy10,
enemyField.enemy11,enemyField.enemy12,
enemyField.enemy13,enemyField.enemy14,
enemyField.enemy15,enemyField.enemy16,
enemyField.enemy17,enemyField.enemy18,
enemyField.enemy19,enemyField.enemy20,
enemyField.enemy21,enemyField.enemy22,
enemyField.enemy23,enemyField.enemy24,
enemyField.enemy25,enemyField.enemy26,
enemyField.enemy27,enemyField.enemy28,
enemyField.enemy29,enemyField.enemy30,
enemyField.enemy31,enemyField.enemy32,
enemyField.enemy33,enemyField.enemy34,
enemyField.enemy35,enemyField.enemy36,
enemyField.enemy37,enemyField.enemy38,
enemyField.enemy39,enemyField.enemy40,
enemyField.enemy41,enemyField.enemy42,
enemyField.enemy43,enemyField.enemy44,
enemyField.enemy45,enemyField.enemy46,
enemyField.enemy47,enemyField.enemy48,
enemyField.enemy49,enemyField.enemy50,
enemyField.enemy51,enemyField.enemy52,
enemyField.enemy53,enemyField.enemy54,
enemyField.enemy55,enemyField.enemy56,
enemyField.enemy57,enemyField.enemy58,
enemyField.enemy59,enemyField.enemy60,
enemyField.enemy61,enemyField.enemy62,
enemyField.enemy63,enemyField.enemy64,
enemyField.enemy65,enemyField.enemy66);
Now the place where the enemy's are being killed:
function enemyHitTest():void {
//for each of the three spiders
for(var i:int = 0; i < spiderArray.length; i++) {
//the each of the six bullets
for(var j:int = 0; j < 6; j++) {
//don't consider bullets that aren't in play:
if(bulletArray[j].y > SpelerMC.y) continue;
if(spiderArray[i].hitTestObject(bulletArray[j])) {
score += 10;
scoreTxt.text = score.toString();
trace("Invader " + i + " neergeschoten!");
spiderArray[i].parent.removeChild(spiderArray[i]);
bulletArray[j].x = j * 70 + 100;
bulletArray[j].y = 595;
}
}
}
Now I think I need to put some sort of theArray.pop(); or something, but don't know how to use it, but I need to place it in this function:
function startGame() {
trace("Start het spel opnieuw...");
gameTimer.addEventListener(TimerEvent.TIMER, onTick);
gameTimer.start();
enemyField.x = 400;
enemyField.y = 160;
SpelerMC.x = 83;
SpelerMC.y = 531;
}
Please help me! Have been searching for 5 hours already. Thanks in advance!
to remove element number i use array.splice(i, 1); ( http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#splice().com/en_US/FlashPlatform/reference/actionscript/3/Array.html#splice%28%29) but keep in mind that array.length will decrease
to reset the array just invoke spidersArray = new Array(enemyField.enemy1, etc) again
UPDATE
in in the enemyHitTest function i changed the removing condition to if(enemyArray[i].visible && enemyArray[i].hitTestObject(laserArray[j])) and enemyArray[i].parent.removeChild(enemyArray[i]); to enemyArray[i].visible = false;
and added
function respawnEnemies():void{
for(var i:int = 0; i < enemyArray.length; i++) {
enemyArray[i].visible = true;
}
}
to call it from startGame
full code here
upd 2
so the problem was not in resetting the array but in the fact that your enemyField and its' enemies were added to stage manually and removed programmatically so there was no code to call to bring them back
if all your instances should be preserved - e.g. you generate all actors at the beginning and later all of them are reused (at the new game) you can set an array of them and on each start game make a copy and remove "dead" enemies from the copied array
also better option is to use a vector e.g.
var enemies:Vector.<Enemy> = Vector.<Enemy>([]);//in brackets references to the instances of Enemy class
var inGame:Vector.<Enemy> = enemies.concat();
also 5hrs of research? please be patient and try harder,
best regards

Flash AS 3 Loader OnComplete Inside a Loop

As a followup to the question, How to get associated URLRequest from Event.COMPLETE fired by URLLoader, how can I make the function work for loader object in a loop?
Here is my existing (rough) code; I always get the mylabel from the last element of the array.
var _loader = new Loader();
for (j = 0; j < 5; j++) {
//mylabel variable is correct setup in the loop
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
doneLoad(e, mylabel);
});
_loader.load(new URLRequest(encodeURI(recAC[j].url)));
}//for loop
As per the comments above, this won't work because:
1) You're just adding the same event listener 5 times to the loader.
2) You're just reseting your same loader object 5 times.
The final output will just be as though you only called it the last time.
There are a variety of ways to address this - loading stuff asynchronously is one of the great mindfucks of learning to code - but the simplest way is probably just to create five separate loaders.
I'd do something like this:
var loaders:Array = [];
var labels:Array = ["label1", "label2", "label3", "label4", "label5"];
for (var j:int = 0; j < 5; j++) {
loaders[j] = new Loader();
loaders[j].contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loaders[j].load(new URLRequest(encodeURI(recAC[j].url)));
}
function completeHandler(e:Event):void {
doneLoad(e.currentTarget, labels[loaders.indexOf(e.currentTarget)]);
}
The confusing part is finding a good way to keep track of which load is associated with which label etc, since in theory your loads can finish in any order. That's why I've got a separate label array there, and then you just match up the desired label with the loader that just finished loading.
I hope that helps!
the line belove should work but it returns -1, always.
loaders.indexOf(e.currentTarget);
Here my code
for(i; i < total; i++){
imgLoaderArray[i] = new Loader();
imgLoaderArray[i].contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, urlError);
imgLoaderArray[i].contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
imgLoaderArray[i].load(new URLRequest(xmlList[i].image));
}
function loaded(e:Event):void{
trace("index: "+imgLoaderArray.indexOf(e.currentTarget)); // return -1 every time
}

Resources