Question

I'm having troubles with the use of arrays of Display Objects.

What I'm trying to do is to generate a “random” scrolling environment, out of some pre-made blocks (whose width is the same as the stage) which keep scrolling with some velocity. All of those “blocks” are stored in a single movieClip (and class) called “Walls”, with different shapes on each frame, so that I can make a random number and go to a random frame, which represents a random shape.

The blocks would generate just when the last one reaches (0,0) (the reference point of the movieclip containing the blocks its on its upper left corner), and the next would appear in (stage.stageWidth, 0) coordinate.

(NOTE: I've made an image to explain myself better, but due to the lack of "reputation" (I'm very new here) I can't upload. I will when I get to it.)

Well, to do so, my last bet was to make an array, named wallArray, and make each element of that array to be the class Walls, and manipulating its elements. The relevant part of the code is this:

var wallArray:Array = new Array();
var index:int = 0;

//In the constructor
for(index = 0; index < 10; index++){
    var aWall:Walls = new Walls();
    randomize = Math.floor(Math.random()*2) + 1;
    aWall.gotoAndStop(randomize);
    wallArray.push(aWall);
}
//Then I add the first element:
index = 0;
stage.addChild(wallArray[0]);

addEventListener(Event.ENTER_FRAME, update_game);
}//End of the constructor

function update_game(e:Event){
        if(wallArray[index].x < 0){
        spawn_wall_piece();
    }
}

function spawn_wall_piece(){
    index++;
        wallArray[index].x = 800;
        wallArray[index].y = 0;
    stage.addChild(wallArray[index]);
}

Well, this does not work for reasons I do not comprehend. It compiles and all, but I keep getting this error:

Error #1010: A term is undefined and has no properties.

I would appreciate very much any help/comment/idea. Thank you in advance!

PD: I know this is NOT a perfect or definitive (as the array will keep growing bigger and bigger), but, meanwhile, it's the only one I could think. If anybody has any other ideas, I would appreciate it very much.


Well, I answer myself because the comments are stacking up on the answer and I do not have the space to tell what I've descovered about the error.

First of all, now the TypeError #1009 doesn't appear, but it isn't still working. Well, after looking thoroughly, I've discovered that most probably the error has to do with removing Event Listeners. This is because the walls stop moving, but the indeed appear on stage as expected from the array wallArray. This is my code on the Walls class:

package  {

    import flash.display.MovieClip;
    import flash.events.Event;


    public class Walls extends MovieClip {

        public function Walls() {

            addEventListener(Event.ENTER_FRAME, update_wall_pos);
        }
        function update_wall_pos(e:Event){
            this.x -= Game.wall_mov_speed;
            if(this.x <  - 820){
            erase_wall();
            }
        }
        function erase_wall(){
            this.removeEventListener(Event.ENTER_FRAME, update_wall_pos);
            this.parent.removeChild(this);
        }
    }

}

Well, the trouble is with the removeEventListener. This should only apply to an specific instance (and therefore only an element of the wallArray), but unexpectedly it stops the whole other walls from moving. What's more, the very strange thing is that it only happens when index has reached the value of three, for unknown reasons. As the forth wall (the one in index == 3) does not reach x = 0, the other walls can't appear and everything stops working. Another thing is that if I delete the removeEventListener part, everything works fine, but when you reach the forth wall it gets very laggy and finally crashes.

Any idea why this happens? Is this problem, the removeEventListener applying to every instance of a class, a known issue? Does anybody know how to solve this? I would appreciate very much any kind of help.

Thank you.

Was it helpful?

Solution 2

Well, I solved it 2 days ago more o less, but was quite busy fixing another problem so I was not sure to post it if in the end it was not usable.

The problem was that the eventListeners in the Walls class were a problem when adding childs, so I left the class in blank, and moved them in the document class. I also added the removeChild in the spawn_wall_piece function too. I also created a function to initialize and adequate the array, so that when wallArray.length == 5, the function was called, the walls before the ones in stage eliminated, and other walls created. As for the collision, as I was facing problems, I put the addItem of the CDK method inside the spawn_wall_piece instead of the function to adequate the array. Well, this is the functional code:

//In the constructor
//Calling to the generating/adequating wallArray function
adequate_array_of_walls(true);
myWallCollisionList.addItem(wallArray[0]);
myWallCollisionList.addItem(wallArray[1]);
//...
//The function called by enter_frame
function update_game(e:Event){
    wallArray[(index - 1)].x -= wall_mov_speed;
    wallArray[index].x -= wall_mov_speed;
    if(wallArray[index].x < 0){
        spawn_wall_piece();
    }
    if(index == 5){
        //We call this function for cleaning
        adequate_array_of_walls(false);
    }
 //...
 //The functions called of the wall generation:
 function spawn_wall_piece(){
    index++;
    wallArray[index].x = (wallArray[index - 1].x + wallArray[index - 1].width);
    wallArray[index].y = 0;
    stage.addChild(wallArray[index]);
    myWallCollisionList.addItem(wallArray[index]);
    myWallCollisionList.removeItem(wallArray[index - 2]);
    stage.removeChild(wallArray[index - 2]);
 }
 function adequate_array_of_walls(init:Boolean):void{
 //This only executes if we are initialitizing the array
 if(init == true){
    for(index = 0; index < 10; index++){
         var aWall:Walls = new Walls();
         randomize = Math.floor(Math.random()*4) + 1;
         aWall.gotoAndStop(randomize);
         wallArray.push(aWall);
    }
    wallArray[0].gotoAndStop(1);
    stage.addChild(wallArray[0]);
    wallArray[1].x = 800;
    wallArray[1].y = 0;
    stage.addChild(wallArray[1]);
    //if not, then we are just cleaning it and rearranging it so it doesn't grow bigger and bigger
 }else{
    for(var a:Number = 0; a < index - 1; a++){
         wallArray.splice(0,1);
    }
    for(a = index - 1; a < (10-2); a++){
         var aWall2:Walls = new Walls();
         randomize = Math.floor(Math.random()*4) + 1;
         aWall2.gotoAndStop(randomize);
         wallArray.push(aWall2);
    }
 }
 //Then, either way, we tell index to be 1 since the reference in the function is [index - 1] and [index], so it starts with [0] and [1]
 index = 1;
}

OTHER TIPS

You haven't posted the full code so can I only give you a best guess on what's going on, but initially it looks like you might have a scoping issue with index. Is index a class variable accessible by spawn_wall_piece() and update_game()? Try tracing it out in one of those functions to see if you're getting the expected results.

You also have a rogue closing bracket after your ENTER_FRAME event listener.

If you're using Flash Professional, try using this guide to debug your movie and find out what is undefined. If you're using mtasc/MXML to compile then make sure your debug value is set to true so you receive line numbers when an error occurs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top