Skip to main content
Participating Frequently
January 15, 2014
Question

Populating a dynamic array with objects and managing it in runtime.

  • January 15, 2014
  • 1 reply
  • 1720 views

So I'm another stuck firstyear. I'll try and make my question compact. I'm using Flash CS6 and have drawn an animated character on the stage that consists of separate parts that are animated and its head is a separate class/symbol entirely because it has not only animation, but a state switch timeline as well. This said Head extends the Main that is the character MovieClip.

I am using a dynamic array to store and .push and .splice objects of another class that would collide with this said Head.

I also discovered the super() function that is implicitly called as the constructor of the parent in any child class that extends the parent, in this case Head extends Main. The issue is that my collidable object array is populated within the main, within the function that spawns every next collidable object with a TimerEvent. This said function then gets called twice due to the super() call.

I have tried putting this super() call into an impossible statement in my child class, but it doesn't change a thing, and it was said that this method is unsafe so I don't even know if it should be working.

However what confuses me the most is when I trace() the .length of my collidable object array at the end of that function. As I said earlier, the original function both spawns an object after a period of Timer(1000) and adds it to the stage as well as adds the object onto the object array, but the super() constructor only duplicates the length call and a creates a copy of the object on the stage, but it does not add the second copy of the object onto the array. The trace() output goes on like so:

1

1

2

2

3

3

4

4

etc.

I wonder why and I'm really stumped by this.

Here is the code in question:

public class Main extends MovieClip {

                    public var nicesnowflake: fallingsnow;

                    var nicesnowflakespawntimer: Timer = new Timer(1000);

                    public var nicesnowflakearray: Array = new Array();

                    public function Main() {

                              nicesnowflakespawntimer.addEventListener(TimerEvent.TIMER, nicesnowflakespawn);

                              nicesnowflakespawntimer.start();

                    }

                    public function nicesnowflakespawn(event:TimerEvent) : void {

                              nicesnowflake = new fallingsnow;

                              nicesnowflake.x = Math.random()* stage.stageWidth;

                              nicesnowflake.y = - stage.stageHeight + 100;

                              nicesnowflakearray.push(nicesnowflake);

                              stage.addChild(nicesnowflake);

                              trace(nicesnowflakearray.length);

                              for (var i:Number = 0; i < nicesnowflakearray.length; i++){

                                        nicesnowflakearray.addEventListener(Event.ENTER_FRAME, snowhit);

                              }

                    }

                    public function snowhit(event:Event) : void {

                              if (nicesnowflakearray[0].y >= 460){

                                        if (nicesnowflakearray[0].y == stage.stageHeight) {

                                        nicesnowflakearray.splice(nicesnowflakearray.indexOf(nicesnowflake), 1);

                              }

                              //if (this.hitTestObject(nicesnowflake)){

                                        //trace("hit");

                              }

                    }

I am also fiddling with the collision, but I believe that it would sort itself out when I deal with the array pop and depop properly. However I'm pasting it anyway in case the issue is subtly hidden somewhere I'm not looking for it. And here is the child class:

public class Head extends Main {

                    public function Head(){

                              if (false){

                                        super();

                              }

                              this.stop();

                    }

          }

}

So like what happens at the moment is that the array gets populated by the first object that spawns, but there is two objects on the stage, then when the objects reach stage.460y mark the array splices() the one object away and displays an error:

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

          at Main/snowhit()"

then when the next object spawns, it repeats the process. Why does it trace the array.length as "1, 1, 2, 2, 3, 3, 4, 4, 5, 5, etc" until the despawn point and then goes on to display an error and then starts from 1 again, because if the array length is more than one object at the time when the first object of the array gets spliced away, shouldn't it go on as usual, since there are other objects in the array?

Thank you very much to whomever will read this through.

This topic has been closed for replies.

1 reply

Inspiring
January 15, 2014

There are multiple problems:

1. You should add eventlisteners for your objects only once, but you add eventlisteners every time your timer runs to all of your snowflakes, again and again:

                              for (var i:Number = 0; i < nicesnowflakearray.length; i++){
                                        nicesnowflakearray.addEventListener(Event.ENTER_FRAME, snowhit);
                              }

change it to

nicesnowflake.addEventListener(Event.ENTER_FRAME, snowhit);

I don`t see why its even necessary to employ this snowflakearray, it would be much straight forward if you simply let the snowflakes take care of themselves.

2. Then you have to change your enterframe function accordingly

public function snowhit(event:Event) : void {
                              if (e.currentTarget.y >= 460){
                                        if (e.currentTarget.y == stage.stageHeight) {

                                        e.currentTarget.removeEventlistener(Event.ENTER_FRAME, snowhit);
                                        removeChild(e.currentTarget);
                              }

                    }

3.

                              //if (this.hitTestObject(nicesnowflake)){
                                        //trace("hit");
                              }

since "this" is a reference to the Main class (root) it surely won`t function as you intend it to.

                              if (false){
                                        super();
                              }

makes no sense to use a condition that can never be true

SkalbeAuthor
Participating Frequently
January 15, 2014

1. I moved the whole snowflakespawner etc out of the main into a separate snowflake symbol class.

2. The hitTest I posted was a rudiment and was previously in a different class, where this. was the head of the character.

3. Exactly. I found that you could force the program NOT to call super() at all by encasing it in an impossible statement, but I don't think I understood it fully and am not doing something right.

4. I have a different problem now. There is nothing left in my main and I just need to call in it the main function of the child snowflake class in order to execute everything like before. How do I simply call a child function in a parent class?

Inspiring
January 15, 2014

if the function is public you can call it with

_parent._child._myPublicFunction()

//subsitute with the instance names of your objects